diff --git a/.gitignore b/.gitignore index 68488643d..c3c4d33eb 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ /build/temp /build/requires.txt /lib +/src/cfml/box.json settings.xml .project WEB-INF @@ -19,4 +20,5 @@ build/resources src/cfml/.version org.eclipse.jdt.ui.prefs apidocs/docbox -commandbox.rb \ No newline at end of file +commandbox.rb +/testbox \ No newline at end of file diff --git a/apidocs/box.json b/apidocs/box.json index 360668208..cb6ad0d33 100644 --- a/apidocs/box.json +++ b/apidocs/box.json @@ -3,9 +3,9 @@ "version":"1.0.0", "slug":"commandbox-apidocs", "private":true, - "defaultPort":8511, + "defaultPort":8989, "dependencies":{ - "docbox":"https://github.com/Ortus-Solutions/DocBox/archive/v2.0.3.zip" + "docbox":"https://github.com/Ortus-Solutions/DocBox/archive/v2.0.4.zip" }, "devDependencies":{ diff --git a/apidocs/index.cfm b/apidocs/index.cfm index abdc4e823..bd0a5a154 100644 --- a/apidocs/index.cfm +++ b/apidocs/index.cfm @@ -7,13 +7,21 @@ try{ strategy = "strategy.commandbox.CommandBoxStrategy", properties = { projectTitle = "CommandBox v#url.version#", - outputDir = url.path + outputDir = url.path } ); + baseDir = expandPath( '/commandbox' ); + commandDirs = directoryList(path='/commandbox/system/modules', recurse=true, filter=function(path){ return reFindNoCase( '.*[/\\]commands$', arguments.path ); } ); source = [ - { dir = expandPath( "/commandbox/commands" ), mapping = "commandbox.commands" }, - { dir = expandPath( "/commandbox/system/commands" ), mapping = "commandbox.system.commands" } ]; + for( dir in commandDirs ) { + source.append( + { + dir : dir, + mapping : listChangeDelims( replaceNoCase( dir, baseDir, 'commandbox' ), '.', '/\' ) + } + ); + } docbox.generate( source ); } catch ( Any e ){ rethrow; diff --git a/apidocs/strategy/commandbox/resources/templates/overview-frame.cfm b/apidocs/strategy/commandbox/resources/templates/overview-frame.cfm index 26e70b686..017834dda 100644 --- a/apidocs/strategy/commandbox/resources/templates/overview-frame.cfm +++ b/apidocs/strategy/commandbox/resources/templates/overview-frame.cfm @@ -138,7 +138,7 @@ .on("changed.jstree", function (e, data) { var obj = data.instance.get_node(data.selected[0]).li_attr; if( obj.linkhref ) { - window.parent.frames['classFrame'].location.assign( obj.linkhref ); + window.parent.frames['classFrame'].location.href = obj.linkhref; } }); diff --git a/build/brew-template.rb b/build/brew-template.rb index 446cf7a21..5b2d3ed4c 100644 --- a/build/brew-template.rb +++ b/build/brew-template.rb @@ -1,26 +1,40 @@ require "formula" - -class Commandbox@be@ < Formula +# Version update PR to Homebrew requires only the information below: +class Commandbox < Formula + desc "CFML embedded server, package manager, and app scaffolding tools" homepage "http://www.ortussolutions.com/products/commandbox" url "@repoURL@/ortussolutions/commandbox/@version@/commandbox-bin-@version@.zip" - sha1 "@sha1@" - version "@version@" - + sha256 "@sha256@" + depends_on :arch => :x86_64 + depends_on :java => "1.7+" - resource 'apidocs' do + resource "apidocs" do url "@repoURL@/ortussolutions/commandbox/@version@/commandbox-apidocs-@version@.zip" - sha1 "@apidocs.sha1@" + sha256 "@apidocs.sha256@" end def install - bin.install 'box' - doc.install resource( "apidocs" ) + bin.install "box" + doc.install resource("apidocs") end - def caveats - "You will need at least Java JDK 1.7+ to run CommandBox" - end + def caveats; <<-EOS.undent + CommandBox is licensed as open source software under the GNU Lesser General Public License v3 + + License information at: + http://www.gnu.org/licenses/lgpl-3.0.en.html + For full CommandBox documentation visit: + https://ortus.gitbooks.io/commandbox-documentation/ + Source Code: + https://github.com/Ortus-Solutions/commandbox + EOS + end + + test do + system "box", "install" + system "box", "--version" + end end diff --git a/build/build-auto.properties b/build/build-auto.properties index 2df6d086e..3c5e845d6 100644 --- a/build/build-auto.properties +++ b/build/build-auto.properties @@ -12,4 +12,6 @@ api.dir=/var/www/vhosts/stg.ortussolutions.com/integration/box-cli/build/temp/ap #debian+rpm repos rpm.repo=/var/www/vhosts/stg.ortussolutions.com/integration/artifacts/RPMS/noarch deb.repo=/var/www/vhosts/stg.ortussolutions.com/integration/artifacts/debs/noarch +rpm.repo.stable=/var/www/vhosts/stg.ortussolutions.com/integration/artifacts/RPMS-stable/noarch +deb.repo.stable=/var/www/vhosts/stg.ortussolutions.com/integration/artifacts/debs-stable/noarch #mvn.type=snapshot# \ No newline at end of file diff --git a/build/build.properties b/build/build.properties index f2655eaa4..e47ad6fb2 100644 --- a/build/build.properties +++ b/build/build.properties @@ -12,12 +12,12 @@ java.pack200=false #dependencies dependencies.dir=${basedir}/lib cfml.version=4.5.2.018 -cfml.loader.version=1.0.7 +cfml.loader.version=1.1.0 cfml.cli.version=${cfml.loader.version}.${cfml.version} lucee.version=4.5.2.018 -jre.version=1.8.0_60 +jre.version=1.8.0_72 launch4j.version=3.4 -runwar.version=3.2.0 +runwar.version=3.3.3 #build locations build.type=localdev @@ -35,6 +35,8 @@ api.dir=${basedir}/temp/apidocs #debian+rpm repos rpm.repo=${dist.dir}/RPMS/noarch deb.repo=${dist.dir}/debs/noarch +rpm.repo.stable=${dist.dir}/RPMS-stable/noarch +deb.repo.stable=${dist.dir}/debs-stable/noarch #mvn.type=snapshot #remote repos diff --git a/build/build.xml b/build/build.xml index 80d3a677b..c2e8cd5bc 100644 --- a/build/build.xml +++ b/build/build.xml @@ -15,8 +15,8 @@ External Dependencies: - - + + @@ -52,6 +52,16 @@ External Dependencies: + + + + + + + + + + @@ -321,29 +331,29 @@ External Dependencies: - - + + - + @be@ - + @version@ - + @repoURL@ - - @sha1@ + + @sha256@ - - @apidocs.sha1@ + + @apidocs.sha256@ @@ -361,11 +371,11 @@ External Dependencies: @repoURL@ - - @sha1@ + + @sha256@ - - @apidocs.sha1@ + + @apidocs.sha256@ @@ -556,7 +566,28 @@ External Dependencies: key="${ortus.sign.key.id}" passphrase="${ortus.sign.key.passphrase}" keyring="${ortus.sign.keyring}" /> + + + + + + + + + This is a stable build, let's update the stable Debian repo + + + + + + + + @@ -578,7 +609,31 @@ External Dependencies: + + + + + + + + + + + + + + + + + + diff --git a/src/cfml/Application.cfc b/src/cfml/Application.cfc index 3888cbc39..6af90b6a1 100644 --- a/src/cfml/Application.cfc +++ b/src/cfml/Application.cfc @@ -34,6 +34,7 @@ component{ // Try to log this to LogBox try { application.wireBox.getLogBox().getRootLogger().error( '#exception.message# #exception.detail ?: ''#', exception.stackTrace ); + application.wireBox.getInstance( 'interceptorService' ).announceInterception( 'onException', { exception=exception } ); // If it fails no worries, LogBox just probably isn't loaded yet. } catch ( Any e ) {} diff --git a/src/cfml/commands/contentbox/theme/install.cfc b/src/cfml/commands/contentbox/theme/install.cfc deleted file mode 100644 index 171ba060b..000000000 --- a/src/cfml/commands/contentbox/theme/install.cfc +++ /dev/null @@ -1,13 +0,0 @@ -/** - * Description of command - **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { - - /** - * - **/ - function run( ) { - print.line( "Command not implemented!" ); - } - -} \ No newline at end of file diff --git a/src/cfml/commands/contentbox/widget/install.cfc b/src/cfml/commands/contentbox/widget/install.cfc deleted file mode 100644 index 171ba060b..000000000 --- a/src/cfml/commands/contentbox/widget/install.cfc +++ /dev/null @@ -1,13 +0,0 @@ -/** - * Description of command - **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { - - /** - * - **/ - function run( ) { - print.line( "Command not implemented!" ); - } - -} \ No newline at end of file diff --git a/src/cfml/commands/contentbox/widget/remove.cfc b/src/cfml/commands/contentbox/widget/remove.cfc deleted file mode 100644 index 171ba060b..000000000 --- a/src/cfml/commands/contentbox/widget/remove.cfc +++ /dev/null @@ -1,13 +0,0 @@ -/** - * Description of command - **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { - - /** - * - **/ - function run( ) { - print.line( "Command not implemented!" ); - } - -} \ No newline at end of file diff --git a/src/cfml/commands/namespace/help.cfc b/src/cfml/commands/namespace/help.cfc deleted file mode 100644 index 02e044678..000000000 --- a/src/cfml/commands/namespace/help.cfc +++ /dev/null @@ -1,11 +0,0 @@ -component extends="commandbox.system.BaseCommand" excludeFromHelp=true { - - function run() { - - print.line(); - print.yellowLine( 'General help and description of how to use namespaces' ); - print.line(); - print.line(); - - } -} \ No newline at end of file diff --git a/src/cfml/commands/namespace/install.cfc b/src/cfml/commands/namespace/install.cfc deleted file mode 100644 index 8268e45e0..000000000 --- a/src/cfml/commands/namespace/install.cfc +++ /dev/null @@ -1,15 +0,0 @@ -/** - * Install a new top-level command namespace - **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { - - /** - * @path.hint The path of the namespace to install - **/ - function run( required string path ) { - print.redLine( 'Not implemented' ); - - } - - -} \ No newline at end of file diff --git a/src/cfml/commands/namespace/list.cfc b/src/cfml/commands/namespace/list.cfc deleted file mode 100644 index 96baab1ab..000000000 --- a/src/cfml/commands/namespace/list.cfc +++ /dev/null @@ -1,23 +0,0 @@ -/** - * List all top-level command namespaces - **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { - - property name="commandService" inject="CommandService"; - - function run( ) { - var commands = commandService.getCommandHierarchy(); - - print.line(); - for( var command in commands ) { - if( !isObject( commands[ command ] ) ) { - print.magentaText( command ); - print.line( ' (#structCount( commands[ command ] )# commands)' ); - } - } - print.line(); - - } - - -} \ No newline at end of file diff --git a/src/cfml/commands/namespace/remove.cfc b/src/cfml/commands/namespace/remove.cfc deleted file mode 100644 index 293f08bd5..000000000 --- a/src/cfml/commands/namespace/remove.cfc +++ /dev/null @@ -1,15 +0,0 @@ -/** - * Remove a new top-level command namespace - **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { - - /** - * @name.hint The name of the command to remove - **/ - function run( required string name ) { - print.redLine( 'Not implemented' ); - - } - - -} \ No newline at end of file diff --git a/src/cfml/commands/package/clear.cfc b/src/cfml/commands/package/clear.cfc deleted file mode 100644 index f63d6ab4c..000000000 --- a/src/cfml/commands/package/clear.cfc +++ /dev/null @@ -1,97 +0,0 @@ -/** - * Remove a property out of the box.json for this package. Command must be executed from the root - * directory of the package where box.json lives. - * Nested attributes may be set by specifying dot-delimited names or using array notation. - * . - * {code:bash} - * package clear description - * {code} - * . - **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { - - property name="packageService" inject="PackageService"; - - /** - * @property.hint Name of the property to clear - * @property.optionsUDF completeProperty - **/ - function run( required string property ) { - - // This will make each directory canonical and absolute - var directory = getCWD(); - - // Check and see if box.json exists - if( !packageService.isPackage( directory ) ) { - return error( 'File [#packageService.getDescriptorPath( directory )#] does not exist. Use the "init" command to create it.' ); - } - - if( arguments.property == 'name' ) { - return error( '[name] is a required property and cannot be cleared.' ); - } - if( arguments.property == 'slug' ) { - return error( '[slug] is a required property and cannot be cleared.' ); - } - var boxJSON = packageService.readPackageDescriptorRaw( directory ); - - // See if this string ends with array brackets containing a number greater than 1. Ex: test[3] - var search = reFind( "\[\s*([1-9][0-9]*)\s*\]$", property, 1, true ); - - // Deal with array index - if( search.pos[1] ) { - // Index to remove - var arrayIndex = mid( property, search.pos[2], search.len[2] ); - // Path to the array - var theArray = left( property, search.pos[1]-1 ); - - // Verify the full path exists (including the array index) - var fullPropertyName = 'boxJSON.#property#'; - if( !isDefined( fullPropertyName ) ) { - return error( '#arguments.property# does not exist.' ); - } - // Get the array reference - var fullPropertyName = 'boxJSON.#theArray#'; - var propertyValue = evaluate( fullPropertyName ); - // Remove the index - propertyValue.deleteAt( arrayIndex ); - - // Else see if it's a dot-delimted struct path. Ex foo.bar - } else if( listLen( property, '.' ) >= 2 ) { - // Name of last key to remove - var last = listLast( property, '.' ); - // path to containing struct - var everythingBut = listDeleteAt( property, listLen( property, '.' ), '.' ); - - // Confirm it exists - var fullPropertyName = 'boxJSON.#everythingBut#'; - if( !isDefined( fullPropertyName ) ) { - return error( '#arguments.property# does not exist.' ); - } - // Get a refernce to the containing struct - var propertyValue = evaluate( fullPropertyName ); - // Remove the key - structDelete( propertyValue, last ); - // Else just a simple propery name - } else { - // Make sure it exists - if( !structKeyExists( boxJSON, arguments.property ) ) { - return error( '#arguments.property# does not exist.' ); - } - // Remove it - structDelete( boxJSON, arguments.property ); - } - - print.greenLine( 'Removed #arguments.property#' ); - - // Write the file back out. - PackageService.writePackageDescriptor( boxJSON, directory ); - - } - - // Dynamic completion for property name based on contents of box.json - function completeProperty() { - var directory = fileSystemUtil.resolvePath( '' ); - return packageService.completeProperty( directory ); - } - -} \ No newline at end of file diff --git a/src/cfml/commands/package/set.cfc b/src/cfml/commands/package/set.cfc deleted file mode 100644 index b70f6f6c6..000000000 --- a/src/cfml/commands/package/set.cfc +++ /dev/null @@ -1,141 +0,0 @@ -/** - * Set values set in box.json for this package. Command must be executed from the root - * directory of the package where box.json lives. - * . - * set package name - * {code:bash} - * package set name=myPackage - * {code} - * . - * Nested attributes may be set by specifying dot-delimited names or using array notation. - * If the set value is JSON, it will be stored as a complex value in the box.json. - * . - * set repo type - * {code:bash} - * package set repository.type=Git - * {code} - * . - * set first testbox notify E-mail - * {code:bash} - * package set testbox.notify.email[1]="brad@bradwood.com" - * {code} - * . - * Set multiple params at once - * {code:bash} - * package set name=myPackage version="1.0.0" author="Brad Wood" slug="foo" - * {code} - * . - * Set complex value as JSON - * {code:bash} - * package set testbox.notify.emails="[ 'test@test.com', 'me@example.com' ]" - * {code} - * . - * Structs and arrays can be appended to using the "append" parameter. - * . - * Add an additional contributor to the existing list - * This only works if the property and incoming value are both of the same complex type. - * {code:bash} - * package set contributors="[ 'brad@coldbox.org' ]" --append - * {code} - * - **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { - - property name="packageService" inject="PackageService"; - - /** - * This param is a dummy param just to get the custom completor to work. - * The actual parameter names will be whatever property name the user wants to set - * @_.hint Pass any number of property names in followed by the value to set - * @_.optionsUDF completeProperty - * @append.hint If setting an array or struct, set to true to append instead of overwriting. - **/ - function run( _, boolean append=false ) { - var thisAppend = arguments.append; - - // Allow text to be piped into this command. If _ has length and a named parameter has been specified, - // copy _'s value into the named param. This allows for: - // cat myFile.txt | package set description='' - if( structKeyExists( arguments, '_' ) && len( arguments[ '_' ] ) && arrayLen( arguments ) > 2 ) { - arguments.setEL( 3, arguments[ '_' ] ); - } - - // Remove dummy arg - structDelete( arguments, '_' ); - structDelete( arguments, 'append' ); - - - // This will make each directory canonical and absolute - var directory = getCWD(); - - // Check and see if box.json exists - if( !packageService.isPackage( directory ) ) { - return error( 'File [#packageService.getDescriptorPath( directory )#] does not exist. Use the "init" command to create it.' ); - } - // Read without defaulted values - boxJSON = packageService.readPackageDescriptorRaw( directory ); - - for( var arg in arguments ) { - // Convert foo.bar-baz[1] to ['foo']['bar-baz'][1] - var tmpProperty = replace( arg, '[', '.[', 'all' ); - tmpProperty = replace( tmpProperty, ']', '].', 'all' ); - var fullPropertyName = ''; - for( var item in listToArray( tmpProperty, '.' ) ) { - if( item.startsWith( '[' ) ) { - fullPropertyName &= item; - } else { - fullPropertyName &= '[ "#item#" ]'; - } - } - fullPropertyName = 'boxJSON' & fullPropertyName; - - - var propertyValue = arguments[ arg ]; - if( isJSON( propertyValue ) ) { - // We're trying to append and the target property exists - if( thisAppend && isDefined( fullPropertyName ) ) { - // The target property we're trying to append to - var targetProperty = evaluate( fullPropertyName ); - // The value we want to append - var complexValue = deserializeJSON( arguments[ arg ] ); - // The target property is not simple, and matches the same data type as the incoming data - if( !isSimpleValue( targetProperty ) && ( isArray( targetProperty ) == isArray( complexValue ) ) ) { - // Make this idempotent so arrays don't get duplicate values - if( isArray( complexValue ) ) { - // For each new value - for( var newValue in complexValue ) { - // Check to see if it's already in the array - if( !targetProperty.find( newValue ) ) { - // If not, add it. - targetProperty.append( newValue ); - } - } - // structs - } else { - targetProperty.append( complexValue, true ); - } - print.greenLine( '#arguments[ arg ]# appended to #arg#' ); - continue; - } - - } - // If any of the ifs above fail, we'll fall back through to this - evaluate( '#fullPropertyName# = deserializeJSON( arguments[ arg ] )' ); - } else { - evaluate( '#fullPropertyName# = arguments[ arg ]' ); - } - print.greenLine( 'Set #arg# = #arguments[ arg ]#' ); - } - - // Write the file back out. - PackageService.writePackageDescriptor( boxJSON, directory ); - - } - - // Dynamic completion for property name based on contents of box.json - function completeProperty() { - var directory = fileSystemUtil.resolvePath( '' ); - // all=true will cause "package set" to prompt all possible box.json properties - return packageService.completeProperty( directory, true ); - } -} \ No newline at end of file diff --git a/src/cfml/commands/server/start.cfc b/src/cfml/commands/server/start.cfc deleted file mode 100644 index 7f80ccac2..000000000 --- a/src/cfml/commands/server/start.cfc +++ /dev/null @@ -1,147 +0,0 @@ -/** - * Start an embedded CFML server. Run command from the web root of the server. - * Please also remember to look at the plethora of arguments this command has as you can start your server with SSL, rewrites and much more. - * . - * {code:bash} - * server start - * {code} - * . - * Start with rewrites enabled - * {code:bash} - * server start --rewritesEnable - * {code} - * . - * Start with specifc heap size - * {code:bash} - * server start heapSize=768 - * {code} - **/ -component extends="commandbox.system.BaseCommand" aliases="start" excludeFromHelp=false { - - // DI - property name="serverService" inject="ServerService"; - property name="packageService" inject="packageService"; - - /** - * @name short name for this server` - * @name.optionsUDF serverNameComplete - * @port port number - * @host bind to a host/ip - * @openbrowser open a browser after starting - * @directory web root for this server - * @stopPort stop socket listener port number - * @force force start if status is not stopped - * @debug sets debug log level - * @webConfigDir custom location for web context configuration - * @serverConfigDir custom location for server configuration - * @libDirs comma-separated list of extra lib directories for the server - * @trayIcon path to .png file for tray icon - * @webXML path to web.xml file used to configure the server - * @HTTPEnable enable HTTP - * @SSLEnable enable SSL - * @SSLPort SSL port number - * @SSLCert SSL certificate - * @SSLKey SSL key (required if SSLCert specified) - * @SSLKeyPass SSL key passphrase (required if SSLCert specified) - * @rewritesEnable enable URL rewriting (default false) - * @rewritesConfig optional URL rewriting config file path - * @heapSize The max heap size in megabytes you would like this server to start with, it defaults to 512mb - **/ - function run( - String name = "", - Numeric port = 0, - String host = "127.0.0.1", - Boolean openbrowser = true, - String directory = "", - Numeric stopPort = 0, - Boolean force = false, - Boolean debug = false, - String webConfigDir = "", - String serverConfigDir = "", - String libDirs = "", - String trayIcon = "", - String webXML = "", - Boolean HTTPEnable = true, - Boolean SSLEnable, - Numeric SSLPort = 1443, - String SSLCert = "", - String SSLKey = "", - String SSLKeyPass = "", - Boolean rewritesEnable = false, - String rewritesConfig = "", - Numeric heapSize = 0 - ){ - // Resolve path as used locally - var webroot = fileSystemUtil.resolvePath( arguments.directory ); - - // Discover by shortname or server and get server info - var serverInfo = serverService.getServerInfoByDiscovery( - directory = webroot, - name = arguments.name - ); - - // Was it found, or new server? - if( structIsEmpty( serverInfo ) ){ - // We need a new entry - serverInfo = serverService.getServerInfo( webroot ); - } - - // Get package descriptor for overrides - var boxJSON = packageService.readPackageDescriptor( serverInfo.webroot ); - - // Update data from arguments - serverInfo.debug = arguments.debug; - serverInfo.name = arguments.name is "" ? listLast( serverInfo.webroot, "\/" ) : arguments.name; - serverInfo.host = arguments.host; - - // TODO: I think all these defaults should be consolodated into the ServerService. - // We're currently defaulting a lot of this stuff twice. - - // we don't want to changes the ports if we're doing stuff already - if( serverInfo.status is "stopped" || arguments.force ){ - // Box Desriptor check for port first. - if( boxJSON.defaultPort != 0 ) { - serverInfo.port = boxJSON.defaultPort; - } - // Check the arguments as the last overrides - if( arguments.port != 0 ){ - serverInfo.port = arguments.port; - } - if( arguments.stopPort != 0 ){ - serverInfo.stopsocket = arguments.stopPort; - } - } - - // Setup serverinfo according to params - if( Len( Trim( arguments.webConfigDir ) ) ) { serverInfo.webConfigDir = arguments.webConfigDir; } - if( Len( Trim( arguments.serverConfigDir ) ) ) { serverInfo.serverConfigDir = arguments.serverConfigDir; } - if( Len( Trim( arguments.libDirs ) ) ) { serverInfo.libDirs = arguments.libDirs; } - if( Len( Trim( arguments.trayIcon ) ) ) { serverInfo.trayIcon = arguments.trayIcon; } - if( Len( Trim( arguments.webXML ) ) ) { serverInfo.webXML = arguments.webXML; } - if( !isNull( arguments.SSLEnable ) ) { serverInfo.SSLEnable = arguments.SSLEnable; } - if( Len( Trim( arguments.HTTPEnable ) ) ) { serverInfo.HTTPEnable = arguments.HTTPEnable; } - if( Len( Trim( arguments.SSLPort ) ) ) { serverInfo.SSLPort = arguments.SSLPort; } - if( Len( Trim( arguments.SSLCert ) ) ) { serverInfo.SSLCert = arguments.SSLCert; } - if( Len( Trim( arguments.SSLKey ) ) ) { serverInfo.SSLKey = arguments.SSLKey; } - if( Len( Trim( arguments.SSLKeyPass ) ) ) { serverInfo.SSLKeyPass = arguments.SSLKeyPass; } - if( !isNull( arguments.rewritesEnable ) ) { serverInfo.rewritesEnable = arguments.rewritesEnable; } - if( Len( Trim( arguments.rewritesConfig ) ) ) { serverInfo.rewritesConfig = arguments.rewritesConfig; } - if( arguments.heapSize != 0 ){ serverInfo.heapSize = arguments.heapSize; } - - // startup the service using server info struct, the start service takes care of persisting updated params - return serverService.start( - serverInfo = serverInfo, - openBrowser = arguments.openbrowser, - force = arguments.force, - debug = arguments.debug - ); - } - - /** - * Complete server names - */ - function serverNameComplete() { - return serverService.getServerNames(); - } - -} \ No newline at end of file diff --git a/src/cfml/commands/task/list.cfc b/src/cfml/commands/task/list.cfc deleted file mode 100644 index cf883ade9..000000000 --- a/src/cfml/commands/task/list.cfc +++ /dev/null @@ -1,10 +0,0 @@ -/** - * List all tasks - **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { - - function run( ) { - print.line( "faux-list!" ); - } - -} \ No newline at end of file diff --git a/src/cfml/modules/.gitignore b/src/cfml/modules/.gitignore new file mode 100644 index 000000000..86d0cb272 --- /dev/null +++ b/src/cfml/modules/.gitignore @@ -0,0 +1,4 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore \ No newline at end of file diff --git a/src/cfml/system/BaseCommand.cfc b/src/cfml/system/BaseCommand.cfc index d4567666c..63f665ed2 100644 --- a/src/cfml/system/BaseCommand.cfc +++ b/src/cfml/system/BaseCommand.cfc @@ -8,22 +8,32 @@ * I am the base command implementation. An abstract class if you will. * */ -component accessors="true" singleton{ +component accessors="true" singleton { // DI - property name="CR" inject="CR@constants"; - property name="formatterUtil" inject="Formatter"; - property name="fileSystemUtil" inject="FileSystem"; - property name="shell" inject="shell"; - property name="print" inject="PrintBuffer"; - property name="wirebox" inject="wirebox"; - property name="logger" inject="logbox:logger:{this}"; - property name="parser" inject="Parser"; + property name="CR"; + property name="formatterUtil"; + property name="fileSystemUtil"; + property name="shell"; + property name="print"; + property name="wirebox"; + property name="logger"; + property name="parser"; /** * Constructor */ function init() { + var wirebox = application.wirebox; + variables.CR = wirebox.getInstance( "CR@constants" ); + variables.formatterUtil = wirebox.getInstance( "Formatter" ); + variables.fileSystemUtil = wirebox.getInstance( "FileSystem" ); + variables.shell = wirebox.getInstance( "shell" ); + variables.print = wirebox.getInstance( "PrintBuffer" ); + variables.wirebox = wirebox; + variables.logger = wirebox.getLogBox().getLogger( this ); + variables.parser = wirebox.getInstance( "Parser" ); + hasErrored = false; return this; } @@ -85,15 +95,24 @@ component accessors="true" singleton{ } /** - * Run another command by name. + * Run another command by name. + * This is deprecated in favor of command(), which escapes parameters for you. * @command.hint The command to run. Pass the same string a user would type at the shell. **/ function runCommand( required command, returnOutput=false ) { return shell.callCommand( arguments.command, arguments.returnOutput ); } + + /** + * Run another command by DSL. + * @name.hint The name of the command to run. + **/ + function command( required name ) { + return getinstance( name='CommandDSL', initArguments={ name : arguments.name } ); + } /** - * Use if if your command wants to give contorlled feedback to the user without raising + * Use if if your command wants to give controlled feedback to the user without raising * an actual exception which comes with a messy stack trace. "return" this command to stop execution of your command * Alternativley, multuple errors can be printed by calling this method more than once prior to returning. * Use clearPrintBuffer to wipe out any output accrued in the print buffer. @@ -103,19 +122,16 @@ component accessors="true" singleton{ * @message.hint The error message to display * @clearPrintBuffer.hint Wipe out the print buffer or not, it does not by default **/ - function error( required message, clearPrintBuffer=false ) { + function error( required message, detail='', clearPrintBuffer=false ) { hasErrored = true; if( arguments.clearPrintBuffer ) { // Wipe print.clear(); } else { // Distance ourselves from whatever other output the command may have given so far. - print.line().line(); + print.line(); } - print.whiteOnRedLine( 'ERROR' ) - .line() - .redLine( arguments.message ) - .line(); + throw( message=arguments.message, detail=arguments.detail, type="commandException"); } @@ -127,7 +143,6 @@ component accessors="true" singleton{ return hasErrored; } - /** * This will open a file or folder externally in the default editor for the user. * Useful for opening a new file for editing that was just created. diff --git a/src/cfml/system/Bootstrap.cfm b/src/cfml/system/Bootstrap.cfm index 98adfdbbd..9ae061a0c 100644 --- a/src/cfml/system/Bootstrap.cfm +++ b/src/cfml/system/Bootstrap.cfm @@ -28,6 +28,12 @@ Type "help" for help, or "help [command]" to be more specific. system = createObject( "java", "java.lang.System" ); args = system.getProperty( "cfml.cli.arguments" ); argsArray = deserializeJSON( system.getProperty( "cfml.cli.argument.array" ) ); + + // System.in is usually the keyboard input, but if the output of another command or a file + // was piped into CommandBox, System.in will represent that input. Wrap System.in + // in a buffered reader so we can check it. + inputStreamReader = createObject( 'java', 'java.io.InputStreamReader' ).init( system.in ); + bufferedReader = createObject( 'java', 'java.io.BufferedReader' ).init( inputStreamReader ); // Verify if we can run CommandBox Java v. 1.7+ if( findNoCase( "1.6", server.java.version ) ){ @@ -35,19 +41,18 @@ Type "help" for help, or "help [command]" to be more specific. sleep( 5000 ); abort; } - + // Check if we are called with an inline command if( !isNull( args ) && trim( args ) != "" ){ // Create the shell shell = wireBox.getInstance( name='Shell', initArguments={ asyncLoad=false } ); + shell.setShellType( 'command' ); + interceptorService = shell.getInterceptorService(); - // System.in is usually the keyboard input, but if the output of another command or a file - // was piped into CommandBox, System.in will represent that input. Wrap System.in - // in a buffered reader so we can check it. - inputStreamReader = createObject( 'java', 'java.io.InputStreamReader' ).init( system.in ); - bufferedReader = createObject( 'java', 'java.io.BufferedReader' ).init( inputStreamReader ); - + interceptData = { shellType=shell.getShellType(), args=argsArray, banner=banner }; + interceptorService.announceInterception( 'onCLIStart', interceptData ); + piped = []; hasPiped = false; // If data is piped to CommandBox, it will be in this buffered reader @@ -61,20 +66,58 @@ Type "help" for help, or "help [command]" to be more specific. if( hasPiped ) { // Concat lines back together piped = arrayToList( piped, chr( 10 ) ); - shell.callCommand( command=argsArray, piped=piped ); + shell.callCommand( command=argsArray, piped=piped, initialCommand=true ); } else { - shell.callCommand( command=argsArray ); + shell.callCommand( command=argsArray, initialCommand=true ); } // flush console shell.getReader().flush(); + // "box" was called all by itself with no commands } else { + // If the standard input has content waiting, cut the chit chat and just run the commands so we can exit. + silent = bufferedReader.ready(); + inStream = system.in; + + // If we're piping in data, let's grab it and treat it as commands. + // system.in should work directly, but Windows was blocking forever and not reading the InputStream + // So we'll create our own input stream with a line break at the end + if( silent ) { + piped = []; + // If data is piped to CommandBox, it will be in this buffered reader + while ( bufferedReader.ready() ) { + // Read all the lines and append them together. + piped.append( bufferedReader.readLine() ); + } + // Build a string with a line for each line read from the standard input. + piped = piped.toList( chr( 10 ) ) & chr( 10 ); + inStream = createObject("java","java.io.ByteArrayInputStream").init(piped.getBytes()); + } + // Create the shell - shell = wireBox.getInstance( 'Shell' ); - // Output the welcome banner - systemOutput( replace( banner, '@@version@@', shell.getVersion() ) ); + shell = application.wirebox.getInstance( name='Shell', initArguments={ asyncLoad=!silent, inStream=inStream, outputStream=system.out } ); + + shell.setShellType( 'interactive' ); + interceptorService = shell.getInterceptorService(); + + interceptData = { shellType=shell.getShellType(), args=argsArray, banner=banner }; + interceptorService.announceInterception( 'onCLIStart', interceptData ); + + if( !silent ) { + // Output the welcome banner + systemOutput( replace( interceptData.banner, '@@version@@', shell.getVersion() ) ); + } + // Running the "reload" command will enter this while loop once - while( shell.run() ){ + while( shell.run( silent=silent ) ){ + clearScreen = shell.getDoClearScreen(); + + interceptorService.announceInterception( 'onCLIExit' ); + + if( clearScreen ){ + shell.getReader().clearScreen(); + } + // Clear all caches: template, ... SystemCacheClear( "all" ); shell = javacast( "null", "" ); @@ -83,11 +126,24 @@ Type "help" for help, or "help [command]" to be more specific. wireBox.shutdown(); new wirebox.system.ioc.Injector( 'commandbox.system.config.WireBox' ); variables.wireBox = application.wireBox; + // startup a new shell shell = wireBox.getInstance( 'Shell' ); + interceptorService = shell.getInterceptorService(); + shell.setShellType( 'interactive' ); + interceptData = { shellType=shell.getShellType(), args=[], banner=banner }; + interceptorService.announceInterception( 'onCLIStart', interceptData ); + + if( clearScreen ){ + // Output the welcome banner + systemOutput( replace( interceptData.banner, '@@version@@', shell.getVersion() ) ); + } + } } + + interceptorService.announceInterception( 'onCLIExit' ); system.runFinalization(); system.gc(); diff --git a/src/cfml/system/Interceptor.cfc b/src/cfml/system/Interceptor.cfc new file mode 100644 index 000000000..22e3adc55 --- /dev/null +++ b/src/cfml/system/Interceptor.cfc @@ -0,0 +1,94 @@ +/** +********************************************************************************* +* Copyright Since 2005 ColdBox Platform by Ortus Solutions, Corp +* www.coldbox.org | www.ortussolutions.com +******************************************************************************** +* @author Brad Wood, Luis Majano +* The base class for all CommandBox interceptors +*/ +component accessors="true"{ + + // Shell reference + property name="shell"; + // LogBox reference + property name="logBox"; + // Pre-Configured Log Object + property name="log"; + // WireBox Reference + property name="wirebox"; + // The interceptor properties structure + property name="properties" type="struct"; + // The interceptor service + property name="interceptorService" type="commandbox.system.services.InterceptorService"; + + /** + * Constructor + * @shell.hint The CommandBox Shell + * @properties.hint The properties to init the Interceptor with + * + * @result Interceptor + */ + function init( required shell, struct properties={} ){ + // Register Shell + setShell( arguments.shell ); + // Register LogBox + setLogBox( arguments.shell.getLogBox() ); + // Register Log object + setLog( getLogBox().getLogger( this ) ); + // Register WireBox + setWireBox( arguments.shell.getWireBox() ); + // store properties + setProperties( arguments.properties ); + // setup interceptor service + setInterceptorService( arguments.shell.getInterceptorService() ); + + return this; + } + + /** + * Configuration method for the interceptor + */ + void function configure(){} + + /** + * Get an interceptor property + * @property.hint The property to retrieve + * @defaultValue.hint The default value to return if property does not exist + */ + any function getProperty( required property, defaultValue ){ + return ( structKeyExists( variables.properties, arguments.property ) ? variables.properties[ arguments.property ] : arguments.defaultValue ); + } + + /** + * Store an interceptor property + * @property.hint The property to store + * @value.hint The value to store + * + * @return Interceptor instance + */ + any function setProperty( required property, required value ){ + variables.properties[ arguments.property ] = arguments.value; + return this; + } + + /** + * Verify an interceptor property + * @property.hint The property to check + */ + boolean function propertyExists( required property ){ + return structKeyExists( variables.properties, arguments.property ); + } + + /** + * Unregister the interceptor + * @state.hint The named state to unregister this interceptor from + * + * @return Interceptor + */ + function unregister( required state ){ + var interceptorClass = listLast( getMetadata( this ).name, "." ); + getInterceptorService().unregister( interceptorClass, arguments.state ); + return this; + } + +} \ No newline at end of file diff --git a/src/cfml/system/Shell.cfc b/src/cfml/system/Shell.cfc index b0b847956..1b61c83c9 100644 --- a/src/cfml/system/Shell.cfc +++ b/src/cfml/system/Shell.cfc @@ -1,4 +1,4 @@ -/** + /** ********************************************************************************* * Copyright Since 2005 ColdBox Platform by Ortus Solutions, Corp * www.coldbox.org | www.ortussolutions.com @@ -16,6 +16,12 @@ component accessors="true" singleton { property name="formatterUtil" inject="Formatter"; property name="logger" inject="logbox:logger:{this}"; property name="fileSystem" inject="FileSystem"; + property name="WireBox" inject="wirebox"; + property name="LogBox" inject="logbox"; + property name="InterceptorService" inject="InterceptorService"; + property name="ModuleService" inject="ModuleService"; + property name="Util" inject="wirebox.system.core.util.Util"; + /** * The java jline reader class. @@ -38,6 +44,10 @@ component accessors="true" singleton { */ property name="reloadShell" default="false" type="Boolean"; /** + * Clear screen after reload + */ + property name="doClearScreen" default="false" type="Boolean"; + /** * The Current Working Directory */ property name="pwd"; @@ -45,6 +55,17 @@ component accessors="true" singleton { * The default shell prompt */ property name="shellPrompt"; + /** + * This value is either "interactive" meaning the shell stays open waiting for user input + * or "command" which means a single command will be run and then the shell will be exiting. + * This differentiation may be useful for commands who want to be careful not to leave threads running + * that they expect to finish since the JVM will terminiate immedatley after the command finishes. + * This could also be useful to reduce the amount of extra text that's output such as the CommandBox + * banner which isn't really needed for a one-off command, especially if the output of that command needs + * to be fed into another OS command. + */ + property name="shellType" default="interactive"; + /** * constructor @@ -60,7 +81,7 @@ component accessors="true" singleton { any outputStream, required string userDir, required string tempDir, - boolean asyncLoad=true + boolean asyncLoad=true ){ // Version is stored in cli-build.xml. Build number is generated by Ant. @@ -88,6 +109,8 @@ component accessors="true" singleton { variables.pwd = variables.userDir; } + setShellType( 'interactive' ); + return this; } @@ -101,7 +124,12 @@ component accessors="true" singleton { // Create temp dir & set setTempDir( variables.tempdir ); - + + getInterceptorService().configure(); + getModuleService().configure(); + + getModuleService().activateAllModules(); + // load commands if( variables.initArgs.asyncLoad ){ thread name="commandbox.loadcommands#getTickCount()#"{ @@ -112,6 +140,9 @@ component accessors="true" singleton { } } + + + /** * Exists the shell **/ @@ -127,11 +158,10 @@ component accessors="true" singleton { * @clear.hint clears the screen after reload **/ Shell function reload( Boolean clear=true ){ - if( arguments.clear ){ - variables.reader.clearScreen(); - } - variables.reloadshell = true; - variables.keepRunning = false; + + setDoClearScreen( arguments.clear ); + setReloadshell( true ); + setKeepRunning( false ); return this; } @@ -326,7 +356,7 @@ component accessors="true" singleton { * Runs the shell thread until exit flag is set * @input.hint command line to run if running externally **/ - Boolean function run( input="" ) { + Boolean function run( input="", silent=false ) { var mask = "*"; var trigger = "su"; @@ -346,8 +376,10 @@ component accessors="true" singleton { variables.keepRunning = true; var line =""; - // Set default prompt on reader - setPrompt(); + if( !arguments.silent ) { + // Set default prompt on reader + setPrompt(); + } // while keep running while( variables.keepRunning ){ @@ -355,14 +387,19 @@ component accessors="true" singleton { if( arguments.input != "" ){ variables.keepRunning = false; } - - try { - // Shell stops on this line while waiting for user input + + // Shell stops on this line while waiting for user input + if( arguments.silent ) { + line = variables.reader.readLine( javacast( "char", ' ' ) ); + } else { line = variables.reader.readLine(); - } catch( any er ) { - printError( er ); - continue; } + + // If the standard input isn't avilable, bail. This happens + // when commands are piped in and we've reached the end of the piped stream + if( !isDefined( 'line' ) ) { + return false; + } // If we input the special word then we will mask the next line. if( ( !isNull( trigger ) ) && ( line.compareTo( trigger ) == 0 ) ){ @@ -370,18 +407,10 @@ component accessors="true" singleton { } // If there's input, try to run it. - if( len( trim( line ) ) ) { - try{ - callCommand( line ); - } catch (any e) { - printError( e ); - } + if( len( trim( line ) ) ) { + callCommand( command=line, initialCommand=true ); } - // Flush history buffer to disk. I could do this in the quit command - // but then I would lose everything if the user just closes the window - variables.reader.getHistory().flush(); - } // end while keep running } catch( any e ){ @@ -394,19 +423,58 @@ component accessors="true" singleton { /** * Call a command - * @command.hint command name + * @command.hint Either a string containing a text command, or an array of tokens representing the command and parameters. * @returnOutput.hint True will return the output of the command as a string, false will send the output to the console. If command outputs nothing, an empty string will come back. + * @piped.hint Any text being piped into the command. This will overwrite the first parameter (pushing any positional params back) + * @initialCommand.hint Since commands can recursivley call new commands via this method, this flags the first in the chain so exceptions can bubble all the way back to the beginning. + * In other words, if "foo" calls "bar", which calls "baz" and baz errors, all three commands are scrapped and do not finish execution. **/ - function callCommand( required any command, returnOutput=false, string piped ) { + function callCommand( + required any command, + returnOutput=false, + string piped, + boolean initialCommand=false ) { + + // Commands a loaded async in interactive mode, so this is a failsafe to ensure the CommandService + // is finished. Especially useful for commands run onCLIStart. Wait up to 5 seconds. + var i = 0; + while( !CommandService.getConfigured() && ++i<50 ) { + sleep( 100 ); + } + - if( isArray( command ) ) { - if( structKeyExists( arguments, 'piped' ) ) { - var result = variables.commandService.runCommandTokens( arguments.command, piped ); + try{ + + if( isArray( command ) ) { + if( structKeyExists( arguments, 'piped' ) ) { + var result = variables.commandService.runCommandTokens( arguments.command, piped ); + } else { + var result = variables.commandService.runCommandTokens( arguments.command ); + } } else { - var result = variables.commandService.runCommandTokens( arguments.command ); + var result = variables.commandService.runCommandLine( arguments.command ); } - } else { - var result = variables.commandService.runCommandLine( arguments.command ); + + // This type of error is recoverable-- like validation error or unresolved command, just a polite message please. + } catch ( commandException var e) { + // If this is a nested command, pass the exception along to unwind the entire stack. + if( !initialCommand ) { + rethrow; + } else { + printError( { message : e.message, detail: e.detail } ); + } + // Anything else is completely unexpected and means boom booms happened-- full stack please. + } catch (any e) { + // If this is a nested command, pass the exception along to unwind the entire stack. + if( !initialCommand ) { + rethrow; + } else { + printError( e ); + } + } finally { + // Flush history buffer to disk. I could do this in the quit command + // but then I would lose everything if the user just closes the window + variables.reader.getHistory().flush(); } // Return the output to the caller to deal with @@ -442,9 +510,15 @@ component accessors="true" singleton { * @err.hint Error object to print (only message is required) **/ Shell function printError( required err ){ + + getInterceptorService().announceInterception( 'onException', { exception=err } ); + variables.logger.error( '#arguments.err.message# #arguments.err.detail ?: ''#', arguments.err.stackTrace ?: '' ); - variables.reader.print( variables.print.boldRedText( "ERROR: " & variables.formatterUtil.HTML2ANSI( arguments.err.message ) ) ); + + variables.reader.print( variables.print.whiteOnRedLine( 'ERROR' ) ); + variables.reader.println(); + variables.reader.print( variables.print.boldRedText( variables.formatterUtil.HTML2ANSI( arguments.err.message ) ) ); variables.reader.println(); if( structKeyExists( arguments.err, 'detail' ) ) { diff --git a/src/cfml/system/commands/CommandTemplate.cfc b/src/cfml/system/commands/CommandTemplate.cfc deleted file mode 100644 index fdfcb4578..000000000 --- a/src/cfml/system/commands/CommandTemplate.cfc +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Output information to the user. Extra details here. - * . - * {code:bash} - * commandtemplate - * {code} - * . - * Here's another way to call it - * {code:bash} - * commandtemplate --arg2 - * {code} - * - **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { - - /** - * @arg1.hint The first argument - * @arg2.hint The second argument - **/ - function run( required arg1, boolean arg2=false ) { - - // Make path canonical and absolute - arguments.path = fileSystemUtil.resolvePath( arguments.path ); - - // Exit command with error - return error( 'There was an error' ); - - // Print text - print.whiteOnRedText( 'foo' ); - print.greenLine( "Yes!!" ); - print.boldRedLine( "No!!" ); - - // Confirm with user - if( confirm( "Are you sure? [y/n]" ) ) { - - } - - // Ask user a question - var response = ask( "What's your favorite color?"); - - } - -} \ No newline at end of file diff --git a/src/cfml/system/commands/run.cfc b/src/cfml/system/commands/run.cfc deleted file mode 100644 index acf00baae..000000000 --- a/src/cfml/system/commands/run.cfc +++ /dev/null @@ -1,63 +0,0 @@ -/** - * Execute an operation system level command. By default, "run" will wait 60 seconds for the command to complete - * . - * {code:bash} - * run "C:\Windows\System32\SoundRecorder.exe" - * {code} - * . - * Wait a max of 10 seconds for the command to finish. - * . - * {code:bash} - * run cmd "/c npm ll" 10 - * {code} - * . - * Kick off the command asyncronoysly and don't wait at all. Also, discard any output. - * . - * {code:bash} - * run myApp.exe 0 - * {code} - * . - * Executing Java would look like this - * . - * {code:bash} - * run java "-jar myLib.jar" - * {code} - * - **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false{ - - /** - * @name.hint The full pathname of the application to execute including extension - * @arguments.hint Command-line arguments passed to the application - * @timeout.hint Ho many seconds to wait. A timeout of 0 returns immediatley without waiting, ignoring any output from the command. - **/ - function run( - required name, - args="", - numeric timeout=60 - ){ - - var executeResult = ""; - var executeError = ""; - - try{ - // execute the server command - execute name="#arguments.name#" arguments="#arguments.args#" timeout="#arguments.timeout#" variable="executeResult" errorvariable="executeError"; - // Output Results - if( !isNull( executeResult ) && len( executeResult ) ) { - print.cyanLine( executeResult ); - } - // Output error - if( !isNull( executeError ) && len( executeError ) ) { - print.redLine( executeError ); - } - - print.greenLine( "Command completed succesfully!" ); - - } catch (any e) { - error( '#e.message##CR##e.detail#' ); - } - - } - -} \ No newline at end of file diff --git a/src/cfml/system/config/CommandBoxDSL.cfc b/src/cfml/system/config/CommandBoxDSL.cfc new file mode 100644 index 000000000..a0786c3fa --- /dev/null +++ b/src/cfml/system/config/CommandBoxDSL.cfc @@ -0,0 +1,124 @@ +/** +********************************************************************************* +* Copyright Since 2014 CommandBox by Ortus Solutions, Corp +* www.coldbox.org | www.ortussolutions.com +******************************************************************************** +* @author Brad Wood, Luis Majano +* +* The DSL builder for all CommandBox-related stuff +* +*/ +component implements="wirebox.system.ioc.dsl.IDSLBuilder" accessors=true{ + + property name="injector"; + property name="log"; + + /** + * Configure the DSL for operation and returns itself + */ + public any function init( required any injector ) output=false { + setInjector( arguments.injector ); + setLog( arguments.injector.getLogBox().getLogger( this ) ); + return this; + } + + + /** + * Process an incoming DSL definition and produce an object with it. + * @output false + * @definition.hint The injection dsl definition structure to process. Keys: name, dsl + * @targetObject.hint The target object we are building the DSL dependency for. If empty, means we are just requesting building + */ + public any function process( required definition, targetObject ) output=false { + + var thisName = arguments.definition.name; + var thisType = arguments.definition.dsl; + var thisTypeLen = listLen(thisType,":"); + var thisLocationType = ""; + var thisLocationKey = ""; + var thisLocationToken = ""; + + // DSL stages + switch(thisTypeLen){ + case 1: { + return getInjector().getInstance( 'shell' ); + } + // commandbox:{key} stage 2 + case 2: { + thisLocationKey = getToken(thisType,2,":"); + switch( thisLocationKey ){ + case "moduleConfig" : { return getInjector().getInstance( 'ModuleService' ).getModuleData(); } + case "ConfigSettings" : { return getInjector().getInstance( 'ConfigService' ).getConfigSettings(); } + } + + break; + } + //commandbox:{key}:{target} + case 3: { + thisLocationType = getToken(thisType,2,":"); + thisLocationKey = getToken(thisType,3,":"); + switch(thisLocationType){ + case "moduleconfig" : { + var moduleConfig = getInjector().getInstance( 'ModuleService' ).getModuleData(); + // Check for module existance + if( structKeyExists(moduleConfig, thisLocationKey ) ){ + return moduleConfig[ thisLocationKey ]; + } else if( getLog().canDebug() ){ + getLog().debug("The module requested: #thisLocationKey# does not exist in the loaded modules. Loaded modules are #structKeyList(moduleConfig)#"); + } + } + case "modulesettings" : { + var moduleConfig = getInjector().getInstance( 'ModuleService' ).getModuleData(); + // Check for module existance + if( structKeyExists(moduleConfig, thisLocationKey ) ){ + return moduleConfig[ thisLocationKey ].settings; + } else if( getLog().canDebug() ){ + getLog().debug("The module requested: #thisLocationKey# does not exist in the loaded modules. Loaded modules are #structKeyList(moduleConfig)#"); + } + } + case "ConfigSettings" : { + var configSettings = getInjector().getInstance( 'ConfigService' ).getConfigSettings();; + // Check for setting existance + if( structKeyExists(configSettings, thisLocationKey ) ){ + return configSettings[ thisLocationKey ]; + } else if( getLog().canDebug() ){ + getLog().debug("The config setting requested: #thisLocationKey# does not exist in the loaded settings. Loaded settings are #structKeyList(configSettings)#"); + } + } + } + break; + } + //commandbox:{key}:{target}:{token} + case 4: { + thisLocationType = getToken(thisType,2,":"); + thisLocationKey = getToken(thisType,3,":"); + thisLocationToken = getToken(thisType,4,":"); + switch(thisLocationType){ + case "modulesettings" : { + var moduleConfig = getInjector().getInstance( 'ModuleService' ).getModuleData(); + // Check for module existance + if( structKeyExists(moduleConfig, thisLocationKey ) ){ + // Check for setting existance + if( structKeyExists( moduleConfig[ thisLocationKey ].settings, thisLocationToken ) ) { + return moduleConfig[ thisLocationKey ].settings[ thisLocationToken ]; + } else if( getLog().canDebug() ){ + getLog().debug("The module requested: #thisLocationKey# does not exist in the loaded modules. Loaded modules are #structKeyList(moduleConfig)#"); + } + } else if( getLog().canDebug() ){ + getLog().debug("The module requested: #thisLocationKey# does not exist in the loaded modules. Loaded modules are #structKeyList(moduleConfig)#"); + } + } + } + break; + } + } + + // debug info + if( getLog().canDebug() ){ + getLog().debug("getColdboxDSL() cannot find dependency using definition: #arguments.definition.toString()#"); + } + } + + + +} \ No newline at end of file diff --git a/src/cfml/system/config/LogBox.cfc b/src/cfml/system/config/LogBox.cfc index 100b56972..af94f83e2 100644 --- a/src/cfml/system/config/LogBox.cfc +++ b/src/cfml/system/config/LogBox.cfc @@ -18,12 +18,13 @@ component { // Define Appenders logBox.appenders = { fileAppender = { - class="wirebox.system.logging.appenders.AsyncRollingFileAppender", + class="wirebox.system.logging.appenders.RollingFileAppender", properties = { fileMaxArchives = 5, filename = "commandbox", filepath = homeDir & "/logs" - } + }, + async=true }, ANSIConsoleAppender = { class="commandbox.system.util.ANSIConsoleAppender" diff --git a/src/cfml/system/config/WireBox.cfc b/src/cfml/system/config/WireBox.cfc index 13c58dd9d..adfa99b5a 100644 --- a/src/cfml/system/config/WireBox.cfc +++ b/src/cfml/system/config/WireBox.cfc @@ -21,9 +21,17 @@ component extends="wirebox.system.ioc.config.Binder" { key = "wireBox" }; + // Register all event listeners here, they are created in the specified order + wirebox.listeners = [ + // { class="", name="", properties={} } + ]; + // LogBox wirebox.logBoxConfig = "commandbox.system.config.LogBox"; + // Register CommandBox DSL for special injection namespaces + mapDSL( "commandbox", "commandbox.system.config.CommandBoxDSL" ); + // Setup constants var system = createObject( "java", "java.lang.System" ); var homeDir = isNull( system.getProperty( 'cfml.cli.home' ) ) ? @@ -36,11 +44,8 @@ component extends="wirebox.system.ioc.config.Binder" { var REPLTagHistoryFile = homedir & "/.history-repl-tag"; var cr = chr( 10 ); var commandLocations = [ - // This is where system commands are stored - '/commandbox/system/commands', - // This is where core namespace commands are stored - '/commandbox/commands', // This is where user-installed commands are stored + // This is deprecated in favor of modules, but leaving it so "old" style commands will still load. '/commandbox-home/commands' ]; var ortusArtifactsURL = 'http://integration.stg.ortussolutions.com/artifacts/'; @@ -74,7 +79,7 @@ component extends="wirebox.system.ioc.config.Binder" { map( 'REPLTagHistoryFile@java' ).toJava( "jline.console.history.FileHistory" ) .initWith( createObject( "java", "java.io.File" ).init( REPLTagHistoryFile ) ) .asSingleton(); - + // Map Directories mapDirectory( '/commandbox/system/services' ); mapDirectory( '/commandbox/system/util' ); diff --git a/src/cfml/templates/box.json.txt b/src/cfml/system/config/box.json.txt similarity index 100% rename from src/cfml/templates/box.json.txt rename to src/cfml/system/config/box.json.txt diff --git a/src/cfml/system/config/urlrewrite.xml b/src/cfml/system/config/urlrewrite.xml index 064b20434..c724f6943 100644 --- a/src/cfml/system/config/urlrewrite.xml +++ b/src/cfml/system/config/urlrewrite.xml @@ -1,20 +1,14 @@ - - ContentBox Media URLs - ^/__media/.*$ - ^/(.*)$ - /index.cfm/$1 - Generic Front-Controller URLs - /(index.cfm|robots.txt|osd.xml|flex2gateway|cfide|cfformgateway|tests|railo-context|lucee|admin-context|modules/contentbox-dsncreator|modules/contentbox-installer|modules/contentbox|files|images|js|javascripts|css|styles|config).* - \.(bmp|gif|jpe?g|png|css|js|txt|xlsx?|docx?|ico|swf|woff2?|ttf|otf)$ - + /(flex2gateway|flashservices/gateway|messagebroker|lucee|rest|cfide|CFIDE|cfformgateway|jrunscripts)/.* + - --> + ^/(.+)$ /index.cfm/$1 diff --git a/src/cfml/system/endpoints/CFLib.cfc b/src/cfml/system/endpoints/CFLib.cfc index 30f8afc27..33ab393b7 100644 --- a/src/cfml/system/endpoints/CFLib.cfc +++ b/src/cfml/system/endpoints/CFLib.cfc @@ -1,9 +1,9 @@ /** ********************************************************************************* -* Copyright Since 2014 CommandBox by Ortus Solutions, Corp +* Copyright Since 2015 CommandBox by Ortus Solutions, Corp * www.coldbox.org | www.ortussolutions.com ******************************************************************************** -* @author Brad Wood, Luis Majano, Denny Valliant +* @author Brad Wood, Luis Majano, Denny Valliant, Ben Koshy * * I am the CFLIb endpoint. I get packages from CFblib.org based on their slug. * install cflib:UDFName @@ -15,6 +15,7 @@ component accessors="true" implements="IEndpoint" singleton { property name="tempDir" inject="tempDir@constants"; property name="progressableDownloader" inject="ProgressableDownloader"; property name="progressBar" inject="ProgressBar"; + property name="CR" inject="CR@constants"; // Properties property name="namePrefixes" type="string"; @@ -31,22 +32,25 @@ component accessors="true" implements="IEndpoint" singleton { directoryCreate( folderName, true, true ); - // Download File - var result = progressableDownloader.download( - 'http://www.cflib.org/udfdownload/' & package, - fullPath, - function( status ) { - progressBar.update( argumentCollection = status ); - }, - function( newURL ) { - consoleLogger.info( "Redirecting to: '#arguments.newURL#'..." ); - } - ); - + try { + // Download File + var result = progressableDownloader.download( + 'http://www.cflib.org/udfdownload/' & package, + fullPath, + function( status ) { + progressBar.update( argumentCollection = status ); + }, + function( newURL ) { + consoleLogger.info( "Redirecting to: '#arguments.newURL#'..." ); + } + ); + } catch( Any var e ) { + throw( '#e.message##CR##e.detail#', 'endpointException' ); + }; + fixTags( fullPath ); - return folderName; - + return folderName; } public function getDefaultName( required string package ) { diff --git a/src/cfml/system/endpoints/ForgeBox.cfc b/src/cfml/system/endpoints/ForgeBox.cfc index de774ffb9..e55f5f35e 100644 --- a/src/cfml/system/endpoints/ForgeBox.cfc +++ b/src/cfml/system/endpoints/ForgeBox.cfc @@ -61,6 +61,73 @@ component accessors="true" implements="IEndpointInteractive" singleton { return packagePath; } + + public function getDefaultName( required string package ) { + // if "foobar@2.0" just return "foobar" + return listFirst( arguments.package, '@' ); + } + + public function getUpdate( required string package, required string version, boolean verbose=false ) { + var slug = parseSlug( arguments.package ); + var version = parseVersion( arguments.package ); + var result = { + isOutdated = false, + version = '' + }; + + // Verify in ForgeBox + var fbData = forgebox.getEntry( slug ); + // Verify if we are outdated, internally isNew() parses the incoming strings + result.isOutdated = semanticVersion.isNew( current=version, target=fbData.version ); + result.version = fbData.version; + + return result; + } + + public string function createUser( + required string username, + required string password, + required string email, + required string firstName, + required string lastName ) { + + try { + + var results = forgebox.register( + username = arguments.username, + password = arguments.password, + email = arguments.email, + FName = arguments.firstName, + LName = arguments.lastName + ); + return results.APIToken; + + } catch( forgebox var e ) { + // This can include "expected" errors such as "Email already in use" + throw( e.message, 'endpointException', e.detail ); + } + } + + public string function login( required string userName, required string password ) { + + try { + + var results = forgebox.login( argumentCollection=arguments ); + return results.APIToken; + + } catch( forgebox var e ) { + // This can include "expected" errors such as "Email already in use" + throw( e.message, 'endpointException', e.detail ); + } + + } + + public function publish( required string path ) { + throw( 'Not implemented' ); + } + + + // Private methods private function getPackage( slug, version, verbose=false ) { @@ -124,18 +191,6 @@ component accessors="true" implements="IEndpointInteractive" singleton { return entryData; } - - public function createUser(required string userName,required string password) { - throw( 'Not implemented' ); - } - - public string function login(required string userName,required string password) { - throw( 'Not implemented' ); - } - - public function publish(required string path) { - throw( 'Not implemented' ); - } private function parseSlug( required string package ) { return listFirst( arguments.package, '@' ); @@ -150,28 +205,6 @@ component accessors="true" implements="IEndpointInteractive" singleton { version = listRest( arguments.package, '@' ); } return version; - } - - public function getDefaultName( required string package ) { - // if "foobar@2.0" just return "foobar" - return listFirst( arguments.package, '@' ); } - - public function getUpdate( required string package, required string version, boolean verbose=false ) { - var slug = parseSlug( arguments.package ); - var version = parseVersion( arguments.package ); - var result = { - isOutdated = false, - version = '' - }; - - // Verify in ForgeBox - var fbData = forgebox.getEntry( slug ); - // Verify if we are outdated, internally isNew() parses the incoming strings - result.isOutdated = semanticVersion.isNew( current=version, target=fbData.version ); - result.version = fbData.version; - - return result; - } - + } \ No newline at end of file diff --git a/src/cfml/system/endpoints/HTTP.cfc b/src/cfml/system/endpoints/HTTP.cfc index 8cc1fb0db..dcead369f 100644 --- a/src/cfml/system/endpoints/HTTP.cfc +++ b/src/cfml/system/endpoints/HTTP.cfc @@ -7,7 +7,7 @@ * * I am the HTTP endpoint. I get packages from an HTTP URL. */ -component accessors="true" implements="IEndpoint" singleton { +component accessors=true implements="IEndpoint" singleton { // DI property name="consoleLogger" inject="logbox:logger:console"; @@ -16,6 +16,7 @@ component accessors="true" implements="IEndpoint" singleton { property name="fileEndpoint" inject="commandbox.system.endpoints.File"; property name="progressableDownloader" inject="ProgressableDownloader"; property name="progressBar" inject="ProgressBar"; + property name="CR" inject="CR@constants"; // Properties property name="namePrefixes" type="string"; @@ -30,18 +31,22 @@ component accessors="true" implements="IEndpoint" singleton { var fileName = 'temp#randRange( 1, 1000 )#.zip'; var fullPath = tempDir & '/' & fileName; - // Download File - var result = progressableDownloader.download( - getNamePrefixes() & ':' & package, // URL to package - fullPath, // Place to store it locally - function( status ) { - progressBar.update( argumentCollection = status ); - }, - function( newURL ) { - consoleLogger.info( "Redirecting to: '#arguments.newURL#'..." ); - } - ); - + try { + // Download File + var result = progressableDownloader.download( + getNamePrefixes() & ':' & package, // URL to package + fullPath, // Place to store it locally + function( status ) { + progressBar.update( argumentCollection = status ); + }, + function( newURL ) { + consoleLogger.info( "Redirecting to: '#arguments.newURL#'..." ); + } + ); + } catch( Any var e ) { + throw( '#e.message##CR##e.detail#', 'endpointException' ); + }; + // Defer to file endpoint return fileEndpoint.resolvePackage( fullPath, arguments.verbose ); diff --git a/src/cfml/system/endpoints/IEndpointInteractive.cfc b/src/cfml/system/endpoints/IEndpointInteractive.cfc index eaddb8473..4040b13f1 100644 --- a/src/cfml/system/endpoints/IEndpointInteractive.cfc +++ b/src/cfml/system/endpoints/IEndpointInteractive.cfc @@ -10,7 +10,13 @@ */ interface extends="IEndpoint" { - public function createUser( required string userName, required string password ); + // Returns access token + public string function createUser( + required string username, + required string password, + required string email, + required string firstName, + required string lastName ); // Returns access token public string function login( required string userName, required string password ); diff --git a/src/cfml/system/modules/artifacts-commands/ModuleConfig.cfc b/src/cfml/system/modules/artifacts-commands/ModuleConfig.cfc new file mode 100644 index 000000000..a400988b5 --- /dev/null +++ b/src/cfml/system/modules/artifacts-commands/ModuleConfig.cfc @@ -0,0 +1,11 @@ +/** +********************************************************************************* +* Copyright Since 2014 CommandBox by Ortus Solutions, Corp +* www.coldbox.org | www.ortussolutions.com +******************************************************************************** +* @author Brad Wood, Luis Majano +*/ +component { + function configure() { + } +} \ No newline at end of file diff --git a/src/cfml/commands/artifacts/clean.cfc b/src/cfml/system/modules/artifacts-commands/commands/artifacts/clean.cfc similarity index 89% rename from src/cfml/commands/artifacts/clean.cfc rename to src/cfml/system/modules/artifacts-commands/commands/artifacts/clean.cfc index a22ad1bfa..4cac08176 100644 --- a/src/cfml/commands/artifacts/clean.cfc +++ b/src/cfml/system/modules/artifacts-commands/commands/artifacts/clean.cfc @@ -13,7 +13,7 @@ * {code} * **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { // DI property name='artifactService' inject='artifactService'; diff --git a/src/cfml/commands/artifacts/help.cfc b/src/cfml/system/modules/artifacts-commands/commands/artifacts/help.cfc similarity index 75% rename from src/cfml/commands/artifacts/help.cfc rename to src/cfml/system/modules/artifacts-commands/commands/artifacts/help.cfc index 0e6f7bfb8..e669cebb1 100644 --- a/src/cfml/commands/artifacts/help.cfc +++ b/src/cfml/system/modules/artifacts-commands/commands/artifacts/help.cfc @@ -1,4 +1,4 @@ -component extends="commandbox.system.BaseCommand" excludeFromHelp=true { +component excludeFromHelp=true { function run() { diff --git a/src/cfml/commands/artifacts/list.cfc b/src/cfml/system/modules/artifacts-commands/commands/artifacts/list.cfc similarity index 91% rename from src/cfml/commands/artifacts/list.cfc rename to src/cfml/system/modules/artifacts-commands/commands/artifacts/list.cfc index efc4d07f6..1ce8c346d 100644 --- a/src/cfml/commands/artifacts/list.cfc +++ b/src/cfml/system/modules/artifacts-commands/commands/artifacts/list.cfc @@ -11,7 +11,7 @@ * {code} * **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { // DI property name='artifactService' inject='artifactService'; diff --git a/src/cfml/commands/artifacts/remove.cfc b/src/cfml/system/modules/artifacts-commands/commands/artifacts/remove.cfc similarity index 95% rename from src/cfml/commands/artifacts/remove.cfc rename to src/cfml/system/modules/artifacts-commands/commands/artifacts/remove.cfc index 226523aa7..861d71143 100644 --- a/src/cfml/commands/artifacts/remove.cfc +++ b/src/cfml/system/modules/artifacts-commands/commands/artifacts/remove.cfc @@ -23,7 +23,7 @@ * {code} * **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { // DI property name='artifactService' inject='artifactService'; diff --git a/src/cfml/system/modules/cachebox-commands/ModuleConfig.cfc b/src/cfml/system/modules/cachebox-commands/ModuleConfig.cfc new file mode 100644 index 000000000..a400988b5 --- /dev/null +++ b/src/cfml/system/modules/cachebox-commands/ModuleConfig.cfc @@ -0,0 +1,11 @@ +/** +********************************************************************************* +* Copyright Since 2014 CommandBox by Ortus Solutions, Corp +* www.coldbox.org | www.ortussolutions.com +******************************************************************************** +* @author Brad Wood, Luis Majano +*/ +component { + function configure() { + } +} \ No newline at end of file diff --git a/src/cfml/commands/logbox/create/config.cfc b/src/cfml/system/modules/cachebox-commands/commands/cachebox/create/config.cfc similarity index 58% rename from src/cfml/commands/logbox/create/config.cfc rename to src/cfml/system/modules/cachebox-commands/commands/cachebox/create/config.cfc index 171ba060b..dce2a8c4e 100644 --- a/src/cfml/commands/logbox/create/config.cfc +++ b/src/cfml/system/modules/cachebox-commands/commands/cachebox/create/config.cfc @@ -1,7 +1,7 @@ /** * Description of command **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * diff --git a/src/cfml/commands/cachebox/create/help.cfc b/src/cfml/system/modules/cachebox-commands/commands/cachebox/create/help.cfc similarity index 68% rename from src/cfml/commands/cachebox/create/help.cfc rename to src/cfml/system/modules/cachebox-commands/commands/cachebox/create/help.cfc index 58ca17b34..27cd8e0a9 100644 --- a/src/cfml/commands/cachebox/create/help.cfc +++ b/src/cfml/system/modules/cachebox-commands/commands/cachebox/create/help.cfc @@ -1,4 +1,4 @@ -component extends="commandbox.system.BaseCommand" excludeFromHelp=true { +component excludeFromHelp=true { function run() { diff --git a/src/cfml/commands/cachebox/help.cfc b/src/cfml/system/modules/cachebox-commands/commands/cachebox/help.cfc similarity index 68% rename from src/cfml/commands/cachebox/help.cfc rename to src/cfml/system/modules/cachebox-commands/commands/cachebox/help.cfc index 44f3aa816..1eff0c860 100644 --- a/src/cfml/commands/cachebox/help.cfc +++ b/src/cfml/system/modules/cachebox-commands/commands/cachebox/help.cfc @@ -1,4 +1,4 @@ -component extends="commandbox.system.BaseCommand" excludeFromHelp=true { +component excludeFromHelp=true { function run() { diff --git a/src/cfml/templates/cachebox/CacheBox.txt b/src/cfml/system/modules/cachebox-commands/templates/cachebox/CacheBox.txt similarity index 100% rename from src/cfml/templates/cachebox/CacheBox.txt rename to src/cfml/system/modules/cachebox-commands/templates/cachebox/CacheBox.txt diff --git a/src/cfml/system/modules/coldbox-commands/ModuleConfig.cfc b/src/cfml/system/modules/coldbox-commands/ModuleConfig.cfc new file mode 100644 index 000000000..a400988b5 --- /dev/null +++ b/src/cfml/system/modules/coldbox-commands/ModuleConfig.cfc @@ -0,0 +1,11 @@ +/** +********************************************************************************* +* Copyright Since 2014 CommandBox by Ortus Solutions, Corp +* www.coldbox.org | www.ortussolutions.com +******************************************************************************** +* @author Brad Wood, Luis Majano +*/ +component { + function configure() { + } +} \ No newline at end of file diff --git a/src/cfml/commands/coldbox/compile.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/compile.cfc similarity index 58% rename from src/cfml/commands/coldbox/compile.cfc rename to src/cfml/system/modules/coldbox-commands/commands/coldbox/compile.cfc index 171ba060b..dce2a8c4e 100644 --- a/src/cfml/commands/coldbox/compile.cfc +++ b/src/cfml/system/modules/coldbox-commands/commands/coldbox/compile.cfc @@ -1,7 +1,7 @@ /** * Description of command **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * diff --git a/src/cfml/commands/coldbox/create/app-wizard.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/app-wizard.cfc similarity index 95% rename from src/cfml/commands/coldbox/create/app-wizard.cfc rename to src/cfml/system/modules/coldbox-commands/commands/coldbox/create/app-wizard.cfc index a5d23b2d5..366f18a1c 100644 --- a/src/cfml/commands/coldbox/create/app-wizard.cfc +++ b/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/app-wizard.cfc @@ -1,7 +1,7 @@ /** * Create a blank ColdBox app from one of our app skeletons by following our lovely wizard. **/ -component extends="app" aliases="" excludeFromHelp=false { +component extends="app" { /** * @name The name of the app you want to create diff --git a/src/cfml/commands/coldbox/create/app.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/app.cfc similarity index 96% rename from src/cfml/commands/coldbox/create/app.cfc rename to src/cfml/system/modules/coldbox-commands/commands/coldbox/create/app.cfc index c56855b90..0ea8bbf12 100644 --- a/src/cfml/commands/coldbox/create/app.cfc +++ b/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/app.cfc @@ -33,7 +33,7 @@ * {code} * **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * The location of our skeletons @@ -48,8 +48,7 @@ component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=fal * Constructor */ function init(){ - super.init(); - variables.skeletonLocation = expandPath( '/commandbox/skeletons/' ); + variables.skeletonLocation = expandPath( '/coldbox-commands/skeletons/' ); return this; } diff --git a/src/cfml/commands/coldbox/create/bdd.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/bdd.cfc similarity index 90% rename from src/cfml/commands/coldbox/create/bdd.cfc rename to src/cfml/system/modules/coldbox-commands/commands/coldbox/create/bdd.cfc index 9b35ad02e..2c3bc5097 100644 --- a/src/cfml/commands/coldbox/create/bdd.cfc +++ b/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/bdd.cfc @@ -8,7 +8,7 @@ * {code} * **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * @name.hint Name of the BDD spec to create without the .cfc. For packages, specify name as 'myPackage/myBDDSpec' diff --git a/src/cfml/commands/coldbox/create/controller.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/controller.cfc similarity index 91% rename from src/cfml/commands/coldbox/create/controller.cfc rename to src/cfml/system/modules/coldbox-commands/commands/coldbox/create/controller.cfc index e1111e9d3..46e27ea86 100644 --- a/src/cfml/commands/coldbox/create/controller.cfc +++ b/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/controller.cfc @@ -8,7 +8,7 @@ * {code} * **/ -component extends='commandbox.system.BaseCommand' aliases='coldbox create handler' excludeFromHelp=false { +component aliases='coldbox create handler' { /** * @name.hint Name of the controller to create without the .cfc. For packages, specify name as 'myPackage/myController' @@ -59,10 +59,10 @@ component extends='commandbox.system.BaseCommand' aliases='coldbox create handle } // Read in Templates - var handlerContent = fileRead( '/commandbox/templates/HandlerContent#scriptPrefix#.txt' ); - var actionContent = fileRead( '/commandbox/templates/ActionContent#scriptPrefix#.txt' ); - var handlerTestContent = fileRead( '/commandbox/templates/testing/HandlerBDDContent#scriptPrefix#.txt' ); - var handlerTestCaseContent = fileRead( '/commandbox/templates/testing/HandlerBDDCaseContent#scriptPrefix#.txt' ); + var handlerContent = fileRead( '/coldbox-commands/templates/HandlerContent#scriptPrefix#.txt' ); + var actionContent = fileRead( '/coldbox-commands/templates/ActionContent#scriptPrefix#.txt' ); + var handlerTestContent = fileRead( '/coldbox-commands/templates/testing/HandlerBDDContent#scriptPrefix#.txt' ); + var handlerTestCaseContent = fileRead( '/coldbox-commands/templates/testing/HandlerBDDCaseContent#scriptPrefix#.txt' ); // Start text replacements handlerContent = replaceNoCase( handlerContent, '|handlerName|', arguments.name, 'all' ); diff --git a/src/cfml/commands/coldbox/create/handlers/Users.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/handlers/Users.cfc old mode 100755 new mode 100644 similarity index 100% rename from src/cfml/commands/coldbox/create/handlers/Users.cfc rename to src/cfml/system/modules/coldbox-commands/commands/coldbox/create/handlers/Users.cfc diff --git a/src/cfml/commands/coldbox/create/help.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/help.cfc similarity index 89% rename from src/cfml/commands/coldbox/create/help.cfc rename to src/cfml/system/modules/coldbox-commands/commands/coldbox/create/help.cfc index ca22b620e..dce9140c0 100644 --- a/src/cfml/commands/coldbox/create/help.cfc +++ b/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/help.cfc @@ -1,4 +1,4 @@ -component extends="commandbox.system.BaseCommand" excludeFromHelp=true { +component excludeFromHelp=true { function run() { diff --git a/src/cfml/commands/coldbox/create/integration-test.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/integration-test.cfc similarity index 90% rename from src/cfml/commands/coldbox/create/integration-test.cfc rename to src/cfml/system/modules/coldbox-commands/commands/coldbox/create/integration-test.cfc index c8360b1e7..b496451d6 100644 --- a/src/cfml/commands/coldbox/create/integration-test.cfc +++ b/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/integration-test.cfc @@ -23,15 +23,7 @@ * coldbox create integration-test contacts --xunit * {code} **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { - - /** - * Constructor - */ - function init(){ - super.init(); - return this; - } +component { /** * @handler.hint Name of the handler to test @@ -85,8 +77,8 @@ component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=fal } // Read in Templates - var handlerTestContent = fileRead( '/commandbox/templates/testing/Handler#stylePrefix#Content#scriptPrefix#.txt' ); - var handlerTestCaseContent = fileRead( '/commandbox/templates/testing/Handler#stylePrefix#CaseContent#scriptPrefix#.txt' ); + var handlerTestContent = fileRead( '/coldbox-commands/templates/testing/Handler#stylePrefix#Content#scriptPrefix#.txt' ); + var handlerTestCaseContent = fileRead( '/coldbox-commands/templates/testing/Handler#stylePrefix#CaseContent#scriptPrefix#.txt' ); // Start text replacements handlerTestContent = replaceNoCase( handlerTestContent, '|appMapping|', arguments.appMapping, 'all' ); diff --git a/src/cfml/commands/coldbox/create/interceptor-test.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/interceptor-test.cfc similarity index 87% rename from src/cfml/commands/coldbox/create/interceptor-test.cfc rename to src/cfml/system/modules/coldbox-commands/commands/coldbox/create/interceptor-test.cfc index 0ecc84404..57a9b496a 100644 --- a/src/cfml/commands/coldbox/create/interceptor-test.cfc +++ b/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/interceptor-test.cfc @@ -7,7 +7,7 @@ * {code} * **/ -component extends='commandbox.system.BaseCommand' aliases='' excludeFromHelp=false { +component { /** * @path The instantiation path of the interceptor to create the test for @@ -33,8 +33,8 @@ component extends='commandbox.system.BaseCommand' aliases='' excludeFromHelp=fal print.line(); // Read in Template - var interceptorTestContent = fileRead( '/commandbox/templates/testing/InterceptorBDDContentScript.txt' ); - var interceptorTestCase = fileRead( '/commandbox/templates/testing/InterceptorBDDCaseContentScript.txt' ); + var interceptorTestContent = fileRead( '/coldbox-commands/templates/testing/InterceptorBDDContentScript.txt' ); + var interceptorTestCase = fileRead( '/coldbox-commands/templates/testing/InterceptorBDDCaseContentScript.txt' ); // Start Replacings interceptorTestContent = replaceNoCase( interceptorTestContent, "|name|", arguments.path, "all" ); diff --git a/src/cfml/commands/coldbox/create/interceptor.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/interceptor.cfc similarity index 88% rename from src/cfml/commands/coldbox/create/interceptor.cfc rename to src/cfml/system/modules/coldbox-commands/commands/coldbox/create/interceptor.cfc index 73d8e1972..c45a6cfe0 100644 --- a/src/cfml/commands/coldbox/create/interceptor.cfc +++ b/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/interceptor.cfc @@ -10,7 +10,7 @@ * {code} * **/ -component extends='commandbox.system.BaseCommand' aliases='' excludeFromHelp=false { +component { /** * @name Name of the interceptor to create without the .cfc @@ -52,10 +52,10 @@ component extends='commandbox.system.BaseCommand' aliases='' excludeFromHelp=fal } // Read in Template - var interceptorContent = fileRead( '/commandbox/templates/InterceptorContent#scriptPrefix#.txt' ); - var interceptorMethod = fileRead( '/commandbox/templates/InterceptorMethod#scriptPrefix#.txt' ); - var interceptorTestContent = fileRead( '/commandbox/templates/testing/InterceptorBDDContentScript.txt' ); - var interceptorTestCase = fileRead( '/commandbox/templates/testing/InterceptorBDDCaseContentScript.txt' ); + var interceptorContent = fileRead( '/coldbox-commands/templates/InterceptorContent#scriptPrefix#.txt' ); + var interceptorMethod = fileRead( '/coldbox-commands/templates/InterceptorMethod#scriptPrefix#.txt' ); + var interceptorTestContent = fileRead( '/coldbox-commands/templates/testing/InterceptorBDDContentScript.txt' ); + var interceptorTestCase = fileRead( '/coldbox-commands/templates/testing/InterceptorBDDCaseContentScript.txt' ); // Start Replacings interceptorContent = replaceNoCase( interceptorContent, '|Name|', arguments.name, 'all' ); diff --git a/src/cfml/commands/coldbox/create/layout.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/layout.cfc similarity index 95% rename from src/cfml/commands/coldbox/create/layout.cfc rename to src/cfml/system/modules/coldbox-commands/commands/coldbox/create/layout.cfc index d34f3c141..b7fdcaefc 100644 --- a/src/cfml/commands/coldbox/create/layout.cfc +++ b/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/layout.cfc @@ -8,7 +8,7 @@ * {code} * **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * @arguments.name.hint Name of the layout to create without the .cfm. diff --git a/src/cfml/commands/coldbox/create/model-test.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/model-test.cfc similarity index 88% rename from src/cfml/commands/coldbox/create/model-test.cfc rename to src/cfml/system/modules/coldbox-commands/commands/coldbox/create/model-test.cfc index adb58804e..817197dfe 100644 --- a/src/cfml/commands/coldbox/create/model-test.cfc +++ b/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/model-test.cfc @@ -7,13 +7,12 @@ * {code} * **/ -component extends='commandbox.system.BaseCommand' aliases='' excludeFromHelp=false { +component { /** * Constructor */ function init(){ - super.init(); // valid persistences variables.validPersistences = 'Transient,Singleton'; @@ -44,8 +43,8 @@ component extends='commandbox.system.BaseCommand' aliases='' excludeFromHelp=fal print.line(); // Read in Template - var modelTestContent = fileRead( '/commandbox/templates/testing/ModelBDDContentScript.txt' ); - var modelTestMethodContent = fileRead( '/commandbox/templates/testing/ModelBDDMethodContentScript.txt' ); + var modelTestContent = fileRead( '/coldbox-commands/templates/testing/ModelBDDContentScript.txt' ); + var modelTestMethodContent = fileRead( '/coldbox-commands/templates/testing/ModelBDDMethodContentScript.txt' ); // Basic replacements modelTestContent = replaceNoCase( modelTestContent, '|modelName|', arguments.path, 'all' ); diff --git a/src/cfml/commands/coldbox/create/model.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/model.cfc similarity index 92% rename from src/cfml/commands/coldbox/create/model.cfc rename to src/cfml/system/modules/coldbox-commands/commands/coldbox/create/model.cfc index c8aaf9c3b..eb6e50256 100644 --- a/src/cfml/commands/coldbox/create/model.cfc +++ b/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/model.cfc @@ -14,13 +14,12 @@ * {code} * **/ -component extends='commandbox.system.BaseCommand' aliases='' excludeFromHelp=false { +component { /** * Constructor */ function init(){ - super.init(); // valid persistences variables.validPersistences = 'Transient,Singleton'; @@ -84,10 +83,10 @@ component extends='commandbox.system.BaseCommand' aliases='' excludeFromHelp=fal } // Read in Template - var modelContent = fileRead( '/commandbox/templates/ModelContent#scriptPrefix#.txt' ); - var modelMethodContent = fileRead( '/commandbox/templates/ModelMethodContent#scriptPrefix#.txt' ); - var modelTestContent = fileRead( '/commandbox/templates/testing/ModelBDDContent#scriptPrefix#.txt' ); - var modelTestMethodContent = fileRead( '/commandbox/templates/testing/ModelBDDMethodContent#scriptPrefix#.txt' ); + var modelContent = fileRead( '/coldbox-commands/templates/ModelContent#scriptPrefix#.txt' ); + var modelMethodContent = fileRead( '/coldbox-commands/templates/ModelMethodContent#scriptPrefix#.txt' ); + var modelTestContent = fileRead( '/coldbox-commands/templates/testing/ModelBDDContent#scriptPrefix#.txt' ); + var modelTestMethodContent = fileRead( '/coldbox-commands/templates/testing/ModelBDDMethodContent#scriptPrefix#.txt' ); // Basic replacements diff --git a/src/cfml/commands/coldbox/create/module.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/module.cfc similarity index 92% rename from src/cfml/commands/coldbox/create/module.cfc rename to src/cfml/system/modules/coldbox-commands/commands/coldbox/create/module.cfc index 96e0f0210..db35fd580 100644 --- a/src/cfml/commands/coldbox/create/module.cfc +++ b/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/module.cfc @@ -7,7 +7,7 @@ * {code} * **/ -component extends='commandbox.system.BaseCommand' aliases='' excludeFromHelp=false { +component { /** * @name Name of the module to create. @@ -51,7 +51,7 @@ component extends='commandbox.system.BaseCommand' aliases='' excludeFromHelp=fal } // Read in Module Config - var moduleConfig = fileRead( '/commandbox/templates/modules/ModuleConfig#scriptPrefix#.cfc' ); + var moduleConfig = fileRead( '/coldbox-commands/templates/modules/ModuleConfig#scriptPrefix#.cfc' ); // Start Generation Replacing moduleConfig = replaceNoCase( moduleConfig, '@title@', arguments.name, 'all'); @@ -64,7 +64,7 @@ component extends='commandbox.system.BaseCommand' aliases='' excludeFromHelp=fal moduleConfig = replaceNoCase( moduleConfig, '@dependencies@', serializeJSON( listToArray( arguments.dependencies ) ), 'all'); // Copy module template - directoryCopy( '/commandbox/templates/modules/', arguments.directory & '/#arguments.name#', true ); + directoryCopy( '/coldbox-commands/templates/modules/', arguments.directory & '/#arguments.name#', true ); // Clean Files Out if( script ) { diff --git a/src/cfml/commands/coldbox/create/orm-crud.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/orm-crud.cfc similarity index 93% rename from src/cfml/commands/coldbox/create/orm-crud.cfc rename to src/cfml/system/modules/coldbox-commands/commands/coldbox/create/orm-crud.cfc index 7796c54ff..913fe32f2 100644 --- a/src/cfml/commands/coldbox/create/orm-crud.cfc +++ b/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/orm-crud.cfc @@ -8,7 +8,7 @@ * {code} * **/ -component extends='commandbox.system.BaseCommand' aliases='' excludeFromHelp=false { +component { /** * @entity The name and dot location path of the entity to create the CRUD for, starting from the root of your application. For example: models.Contact, models.security.User @@ -66,7 +66,7 @@ component extends='commandbox.system.BaseCommand' aliases='' excludeFromHelp=fal //********************** generate handler ************************************// // Read Handler Content - var hContent = fileRead( '/commandbox/templates/crud/HandlerContent.txt' ); + var hContent = fileRead( '/coldbox-commands/templates/crud/HandlerContent.txt' ); // Token replacement hContent = replacenocase( hContent, "|entity|", entityName, "all" ); hContent = replacenocase( hContent, "|entityPlural|", arguments.pluralName, "all" ); @@ -85,7 +85,7 @@ component extends='commandbox.system.BaseCommand' aliases='' excludeFromHelp=fal directorycreate( arguments.viewsDirectory & "/#arguments.pluralName#", true, true ); var views = [ "edit", "editor", "new" ]; for( var thisView in views ){ - var vContent = fileRead( '/commandbox/templates/crud/#thisView#.txt' ); + var vContent = fileRead( '/coldbox-commands/templates/crud/#thisView#.txt' ); vContent = replacenocase( vContent, "|entity|", entityName, "all" ); vContent = replacenocase( vContent, "|entityPlural|", arguments.pluralName, "all" ); fileWrite( arguments.viewsDirectory & "/#arguments.pluralName#/#thisView#.cfm", vContent); @@ -96,12 +96,12 @@ component extends='commandbox.system.BaseCommand' aliases='' excludeFromHelp=fal // Build table output for index savecontent variable="local.tableData"{ - include '/commandbox/templates/crud/table.cfm'; + include '/coldbox-commands/templates/crud/table.cfm'; } tableData = replaceNoCase( tableData, "%cf", "#chr(60)#cf", "all" ); tableData = replaceNoCase( tableData, "%/cf", "#chr(60)#/cf", "all" ); // index data - var vContent = fileRead( '/commandbox/templates/crud/index.txt' ); + var vContent = fileRead( '/coldbox-commands/templates/crud/index.txt' ); vContent = replacenocase( vContent, "|entity|", entityName, "all" ); vContent = replacenocase( vContent, "|entityPlural|", arguments.pluralName, "all" ); vContent = replacenocase( vContent, "|tableListing|", tableData, "all" ); diff --git a/src/cfml/commands/coldbox/create/orm-entity.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/orm-entity.cfc similarity index 95% rename from src/cfml/commands/coldbox/create/orm-entity.cfc rename to src/cfml/system/modules/coldbox-commands/commands/coldbox/create/orm-entity.cfc index f4d56fe6d..5cfa1f09c 100644 --- a/src/cfml/commands/coldbox/create/orm-entity.cfc +++ b/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/orm-entity.cfc @@ -28,7 +28,7 @@ * {code} * **/ -component extends='commandbox.system.BaseCommand' aliases='' excludeFromHelp=false { +component { /** * @entityName The name of the entity without .cfc @@ -79,8 +79,8 @@ component extends='commandbox.system.BaseCommand' aliases='' excludeFromHelp=fal if( !len( arguments.primaryKeyColumn ) ){ arguments.primaryKeyColumn = arguments.primaryKey; } // Read in Template - var modelContent = fileRead( '/commandbox/templates/orm/Entity#scriptPrefix#.txt' ); - var modelTestContent = fileRead( '/commandbox/templates/testing/ORMEntityBDDContent#scriptPrefix#.txt' ); + var modelContent = fileRead( '/coldbox-commands/templates/orm/Entity#scriptPrefix#.txt' ); + var modelTestContent = fileRead( '/coldbox-commands/templates/testing/ORMEntityBDDContent#scriptPrefix#.txt' ); // Basic replacements modelContent = replaceNoCase( modelContent, '|entityName|', arguments.entityName, 'all' ); diff --git a/src/cfml/commands/coldbox/create/orm-event-handler.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/orm-event-handler.cfc similarity index 89% rename from src/cfml/commands/coldbox/create/orm-event-handler.cfc rename to src/cfml/system/modules/coldbox-commands/commands/coldbox/create/orm-event-handler.cfc index 3f79a4427..b0e7ca327 100644 --- a/src/cfml/commands/coldbox/create/orm-event-handler.cfc +++ b/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/orm-event-handler.cfc @@ -7,7 +7,7 @@ * {code} * **/ -component extends='commandbox.system.BaseCommand' aliases='' excludeFromHelp=false { +component { /** * @name.hint Name of the event handler to create without the .cfc. For packages, specify name as 'myPackage/myModel' @@ -33,7 +33,7 @@ component extends='commandbox.system.BaseCommand' aliases='' excludeFromHelp=fal print.line(); // Read in Template - var modelContent = fileRead( '/commandbox/templates/orm/ORMEventHandler.txt' ); + var modelContent = fileRead( '/coldbox-commands/templates/orm/ORMEventHandler.txt' ); // Write out the model var modelPath = '#directory#/#arguments.name#.cfc'; diff --git a/src/cfml/commands/coldbox/create/orm-service.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/orm-service.cfc similarity index 91% rename from src/cfml/commands/coldbox/create/orm-service.cfc rename to src/cfml/system/modules/coldbox-commands/commands/coldbox/create/orm-service.cfc index 7e0084a0b..6ecbbd994 100644 --- a/src/cfml/commands/coldbox/create/orm-service.cfc +++ b/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/orm-service.cfc @@ -7,7 +7,7 @@ * {code} * **/ -component extends='commandbox.system.BaseCommand' aliases='' excludeFromHelp=false { +component { /** * @serviceName The name of this Base ORM service to create @@ -41,8 +41,8 @@ component extends='commandbox.system.BaseCommand' aliases='' excludeFromHelp=fal } // Read in Template - var modelContent = fileRead( '/commandbox/templates/orm/TemplatedEntityService.txt' ); - var modelTestContent = fileRead( '/commandbox/templates/testing/ModelBDDContentScript.txt' ); + var modelContent = fileRead( '/coldbox-commands/templates/orm/TemplatedEntityService.txt' ); + var modelTestContent = fileRead( '/coldbox-commands/templates/testing/ModelBDDContentScript.txt' ); // Query cache Region if( !len( arguments.cacheRegion ) ){ diff --git a/src/cfml/commands/coldbox/create/orm-virtual-service.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/orm-virtual-service.cfc similarity index 91% rename from src/cfml/commands/coldbox/create/orm-virtual-service.cfc rename to src/cfml/system/modules/coldbox-commands/commands/coldbox/create/orm-virtual-service.cfc index 039596a56..b399f6616 100644 --- a/src/cfml/commands/coldbox/create/orm-virtual-service.cfc +++ b/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/orm-virtual-service.cfc @@ -7,7 +7,7 @@ * {code} * **/ -component extends='commandbox.system.BaseCommand' aliases='' excludeFromHelp=false { +component { /** * @entityName The name of the entity this virtual service will be bound to @@ -41,8 +41,8 @@ component extends='commandbox.system.BaseCommand' aliases='' excludeFromHelp=fal } // Read in Template - var modelContent = fileRead( '/commandbox/templates/orm/VirtualEntityService.txt' ); - var modelTestContent = fileRead( '/commandbox/templates/testing/ModelBDDContentScript.txt' ); + var modelContent = fileRead( '/coldbox-commands/templates/orm/VirtualEntityService.txt' ); + var modelTestContent = fileRead( '/coldbox-commands/templates/testing/ModelBDDContentScript.txt' ); // Query cache Region if( !len( arguments.cacheRegion ) ){ diff --git a/src/cfml/commands/coldbox/create/unit.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/unit.cfc similarity index 90% rename from src/cfml/commands/coldbox/create/unit.cfc rename to src/cfml/system/modules/coldbox-commands/commands/coldbox/create/unit.cfc index 464d8da5b..d0df1253e 100644 --- a/src/cfml/commands/coldbox/create/unit.cfc +++ b/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/unit.cfc @@ -8,7 +8,7 @@ * {code} * **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * @name.hint Name of the xUnit Bundle to create without the .cfc. For packages, specify name as 'myPackage/MyServiceTest' diff --git a/src/cfml/commands/coldbox/create/view.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/view.cfc similarity index 60% rename from src/cfml/commands/coldbox/create/view.cfc rename to src/cfml/system/modules/coldbox-commands/commands/coldbox/create/view.cfc index 675b34c87..2e78898c9 100644 --- a/src/cfml/commands/coldbox/create/view.cfc +++ b/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/view.cfc @@ -1,52 +1,65 @@ /** * Create a new view in an existing ColdBox application. Run this command in the root -* of your app for it to find the correct folder. By default, your new view will be created in /views but you can +* of your app for it to find the correct folder. By default, your new view will be created in /views but you can * override that with the directory param. * . * {code:bash} * coldbox create view myView * {code} -* +* **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { - +component { + /** * @name.hint Name of the view to create without the .cfm. * @helper.hint Generate a helper file for this view * @directory.hint The base directory to create your view in and creates the directory if it does not exist. **/ - function run( + function run( required name, boolean helper=false, - directory='views' + directory='views' ){ - // This will make each directory canonical and absolute + // Allow dot-delimited paths + arguments.name = replace( arguments.name, '.', '/', 'all' ); + + // Check if the name is actually a path + var nameArray = arguments.name.listToArray( '/' ); + var nameArrayLength = nameArray.len(); + if (nameArrayLength > 1) { + // If it is a path, split the path from the name + arguments.name = nameArray[nameArrayLength]; + var extendedPath = nameArray.slice(1, nameArrayLength - 1).toList('/'); + arguments.directory &= '/#extendedPath#'; + } + + // This will make each directory canonical and absolute arguments.directory = fileSystemUtil.resolvePath( arguments.directory ); - + // Validate directory if( !directoryExists( arguments.directory ) ) { - directoryCreate( arguments.directory ); + directoryCreate( arguments.directory ); } - + // This help readability so the success messages aren't up against the previous command line print.line(); - + var viewContent = '

#arguments.name# view

'; var viewHelperContent = ''; - + // Write out view - var viewPath = '#arguments.directory#/#arguments.name#.cfm'; + var viewPath = '#arguments.directory#/#arguments.name#.cfm'; file action='write' file='#viewPath#' mode ='777' output='#viewContent#'; - print.greenLine( 'Created #viewPath#' ); - + print.greenLine( 'Created #viewPath#' ); + if( arguments.helper ) { // Write out view helper - var viewHelperPath = '#arguments.directory#/#arguments.name#Helper.cfm'; + var viewHelperPath = '#arguments.directory#/#arguments.name#Helper.cfm'; file action='write' file='#viewHelperPath#' mode ='777' output='#viewHelperContent#'; print.greenLine( 'Created #viewHelperPath#' ); - + } - + } -} \ No newline at end of file +} diff --git a/src/cfml/commands/coldbox/create/views/Users/edit.cfm b/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/views/Users/edit.cfm similarity index 100% rename from src/cfml/commands/coldbox/create/views/Users/edit.cfm rename to src/cfml/system/modules/coldbox-commands/commands/coldbox/create/views/Users/edit.cfm diff --git a/src/cfml/commands/coldbox/create/views/Users/editor.cfm b/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/views/Users/editor.cfm similarity index 100% rename from src/cfml/commands/coldbox/create/views/Users/editor.cfm rename to src/cfml/system/modules/coldbox-commands/commands/coldbox/create/views/Users/editor.cfm diff --git a/src/cfml/commands/coldbox/create/views/Users/index.cfm b/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/views/Users/index.cfm similarity index 100% rename from src/cfml/commands/coldbox/create/views/Users/index.cfm rename to src/cfml/system/modules/coldbox-commands/commands/coldbox/create/views/Users/index.cfm diff --git a/src/cfml/commands/coldbox/create/views/Users/new.cfm b/src/cfml/system/modules/coldbox-commands/commands/coldbox/create/views/Users/new.cfm similarity index 100% rename from src/cfml/commands/coldbox/create/views/Users/new.cfm rename to src/cfml/system/modules/coldbox-commands/commands/coldbox/create/views/Users/new.cfm diff --git a/src/cfml/commands/coldbox/help.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/help.cfc similarity index 91% rename from src/cfml/commands/coldbox/help.cfc rename to src/cfml/system/modules/coldbox-commands/commands/coldbox/help.cfc index 45821c742..002a02bf7 100644 --- a/src/cfml/commands/coldbox/help.cfc +++ b/src/cfml/system/modules/coldbox-commands/commands/coldbox/help.cfc @@ -1,4 +1,4 @@ -component extends="commandbox.system.BaseCommand" excludeFromHelp=true { +component excludeFromHelp=true { function run() { diff --git a/src/cfml/commands/coldbox/integrate/ant.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/integrate/ant.cfc similarity index 58% rename from src/cfml/commands/coldbox/integrate/ant.cfc rename to src/cfml/system/modules/coldbox-commands/commands/coldbox/integrate/ant.cfc index 171ba060b..dce2a8c4e 100644 --- a/src/cfml/commands/coldbox/integrate/ant.cfc +++ b/src/cfml/system/modules/coldbox-commands/commands/coldbox/integrate/ant.cfc @@ -1,7 +1,7 @@ /** * Description of command **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * diff --git a/src/cfml/commands/coldbox/integrate/cfuilder.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/integrate/cfuilder.cfc similarity index 58% rename from src/cfml/commands/coldbox/integrate/cfuilder.cfc rename to src/cfml/system/modules/coldbox-commands/commands/coldbox/integrate/cfuilder.cfc index 171ba060b..dce2a8c4e 100644 --- a/src/cfml/commands/coldbox/integrate/cfuilder.cfc +++ b/src/cfml/system/modules/coldbox-commands/commands/coldbox/integrate/cfuilder.cfc @@ -1,7 +1,7 @@ /** * Description of command **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * diff --git a/src/cfml/commands/coldbox/integrate/eclipse.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/integrate/eclipse.cfc similarity index 58% rename from src/cfml/commands/coldbox/integrate/eclipse.cfc rename to src/cfml/system/modules/coldbox-commands/commands/coldbox/integrate/eclipse.cfc index 171ba060b..dce2a8c4e 100644 --- a/src/cfml/commands/coldbox/integrate/eclipse.cfc +++ b/src/cfml/system/modules/coldbox-commands/commands/coldbox/integrate/eclipse.cfc @@ -1,7 +1,7 @@ /** * Description of command **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * diff --git a/src/cfml/commands/coldbox/integrate/grunt.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/integrate/grunt.cfc similarity index 58% rename from src/cfml/commands/coldbox/integrate/grunt.cfc rename to src/cfml/system/modules/coldbox-commands/commands/coldbox/integrate/grunt.cfc index 171ba060b..dce2a8c4e 100644 --- a/src/cfml/commands/coldbox/integrate/grunt.cfc +++ b/src/cfml/system/modules/coldbox-commands/commands/coldbox/integrate/grunt.cfc @@ -1,7 +1,7 @@ /** * Description of command **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * diff --git a/src/cfml/commands/coldbox/integrate/help.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/integrate/help.cfc similarity index 69% rename from src/cfml/commands/coldbox/integrate/help.cfc rename to src/cfml/system/modules/coldbox-commands/commands/coldbox/integrate/help.cfc index e0e8e74a9..1b461a80c 100644 --- a/src/cfml/commands/coldbox/integrate/help.cfc +++ b/src/cfml/system/modules/coldbox-commands/commands/coldbox/integrate/help.cfc @@ -1,4 +1,4 @@ -component extends="commandbox.system.BaseCommand" excludeFromHelp=true { +component excludeFromHelp=true { function run() { diff --git a/src/cfml/commands/coldbox/interceptor/help.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/interceptor/help.cfc similarity index 69% rename from src/cfml/commands/coldbox/interceptor/help.cfc rename to src/cfml/system/modules/coldbox-commands/commands/coldbox/interceptor/help.cfc index df9b35bb4..ff4e313c7 100644 --- a/src/cfml/commands/coldbox/interceptor/help.cfc +++ b/src/cfml/system/modules/coldbox-commands/commands/coldbox/interceptor/help.cfc @@ -1,4 +1,4 @@ -component extends="commandbox.system.BaseCommand" excludeFromHelp=true { +component excludeFromHelp=true { function run() { diff --git a/src/cfml/commands/coldbox/interceptor/install.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/interceptor/install.cfc similarity index 58% rename from src/cfml/commands/coldbox/interceptor/install.cfc rename to src/cfml/system/modules/coldbox-commands/commands/coldbox/interceptor/install.cfc index 171ba060b..dce2a8c4e 100644 --- a/src/cfml/commands/coldbox/interceptor/install.cfc +++ b/src/cfml/system/modules/coldbox-commands/commands/coldbox/interceptor/install.cfc @@ -1,7 +1,7 @@ /** * Description of command **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * diff --git a/src/cfml/commands/coldbox/interceptor/remove.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/interceptor/remove.cfc similarity index 58% rename from src/cfml/commands/coldbox/interceptor/remove.cfc rename to src/cfml/system/modules/coldbox-commands/commands/coldbox/interceptor/remove.cfc index 171ba060b..dce2a8c4e 100644 --- a/src/cfml/commands/coldbox/interceptor/remove.cfc +++ b/src/cfml/system/modules/coldbox-commands/commands/coldbox/interceptor/remove.cfc @@ -1,7 +1,7 @@ /** * Description of command **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * diff --git a/src/cfml/commands/coldbox/module/help.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/module/help.cfc similarity index 69% rename from src/cfml/commands/coldbox/module/help.cfc rename to src/cfml/system/modules/coldbox-commands/commands/coldbox/module/help.cfc index 2919fecae..becafab71 100644 --- a/src/cfml/commands/coldbox/module/help.cfc +++ b/src/cfml/system/modules/coldbox-commands/commands/coldbox/module/help.cfc @@ -1,4 +1,4 @@ -component extends="commandbox.system.BaseCommand" excludeFromHelp=true { +component excludeFromHelp=true { function run() { diff --git a/src/cfml/commands/coldbox/module/install.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/module/install.cfc similarity index 58% rename from src/cfml/commands/coldbox/module/install.cfc rename to src/cfml/system/modules/coldbox-commands/commands/coldbox/module/install.cfc index 171ba060b..dce2a8c4e 100644 --- a/src/cfml/commands/coldbox/module/install.cfc +++ b/src/cfml/system/modules/coldbox-commands/commands/coldbox/module/install.cfc @@ -1,7 +1,7 @@ /** * Description of command **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * diff --git a/src/cfml/commands/coldbox/module/list.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/module/list.cfc similarity index 58% rename from src/cfml/commands/coldbox/module/list.cfc rename to src/cfml/system/modules/coldbox-commands/commands/coldbox/module/list.cfc index 171ba060b..dce2a8c4e 100644 --- a/src/cfml/commands/coldbox/module/list.cfc +++ b/src/cfml/system/modules/coldbox-commands/commands/coldbox/module/list.cfc @@ -1,7 +1,7 @@ /** * Description of command **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * diff --git a/src/cfml/commands/coldbox/module/remove.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/module/remove.cfc similarity index 58% rename from src/cfml/commands/coldbox/module/remove.cfc rename to src/cfml/system/modules/coldbox-commands/commands/coldbox/module/remove.cfc index 171ba060b..dce2a8c4e 100644 --- a/src/cfml/commands/coldbox/module/remove.cfc +++ b/src/cfml/system/modules/coldbox-commands/commands/coldbox/module/remove.cfc @@ -1,7 +1,7 @@ /** * Description of command **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * diff --git a/src/cfml/commands/coldbox/notes.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/notes.cfc similarity index 58% rename from src/cfml/commands/coldbox/notes.cfc rename to src/cfml/system/modules/coldbox-commands/commands/coldbox/notes.cfc index 171ba060b..dce2a8c4e 100644 --- a/src/cfml/commands/coldbox/notes.cfc +++ b/src/cfml/system/modules/coldbox-commands/commands/coldbox/notes.cfc @@ -1,7 +1,7 @@ /** * Description of command **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * diff --git a/src/cfml/commands/coldbox/reinit.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/reinit.cfc similarity index 92% rename from src/cfml/commands/coldbox/reinit.cfc rename to src/cfml/system/modules/coldbox-commands/commands/coldbox/reinit.cfc index 5afd798ad..8c21aafed 100644 --- a/src/cfml/commands/coldbox/reinit.cfc +++ b/src/cfml/system/modules/coldbox-commands/commands/coldbox/reinit.cfc @@ -10,7 +10,7 @@ * coldbox reinit password="mypass" * {code} **/ -component extends="commandbox.system.BaseCommand" aliases="fwreinit" excludeFromHelp=false { +component aliases="fwreinit" { // DI property name="serverService" inject="ServerService"; diff --git a/src/cfml/commands/coldbox/report/di.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/report/di.cfc similarity index 58% rename from src/cfml/commands/coldbox/report/di.cfc rename to src/cfml/system/modules/coldbox-commands/commands/coldbox/report/di.cfc index 171ba060b..dce2a8c4e 100644 --- a/src/cfml/commands/coldbox/report/di.cfc +++ b/src/cfml/system/modules/coldbox-commands/commands/coldbox/report/di.cfc @@ -1,7 +1,7 @@ /** * Description of command **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * diff --git a/src/cfml/commands/coldbox/report/handlers.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/report/handlers.cfc similarity index 58% rename from src/cfml/commands/coldbox/report/handlers.cfc rename to src/cfml/system/modules/coldbox-commands/commands/coldbox/report/handlers.cfc index 171ba060b..dce2a8c4e 100644 --- a/src/cfml/commands/coldbox/report/handlers.cfc +++ b/src/cfml/system/modules/coldbox-commands/commands/coldbox/report/handlers.cfc @@ -1,7 +1,7 @@ /** * Description of command **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * diff --git a/src/cfml/commands/coldbox/report/help.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/report/help.cfc similarity index 69% rename from src/cfml/commands/coldbox/report/help.cfc rename to src/cfml/system/modules/coldbox-commands/commands/coldbox/report/help.cfc index 06dbd8fef..f94e73aaa 100644 --- a/src/cfml/commands/coldbox/report/help.cfc +++ b/src/cfml/system/modules/coldbox-commands/commands/coldbox/report/help.cfc @@ -1,4 +1,4 @@ -component extends="commandbox.system.BaseCommand" excludeFromHelp=true { +component excludeFromHelp=true { function run() { diff --git a/src/cfml/commands/coldbox/report/routes.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/report/routes.cfc similarity index 58% rename from src/cfml/commands/coldbox/report/routes.cfc rename to src/cfml/system/modules/coldbox-commands/commands/coldbox/report/routes.cfc index 171ba060b..dce2a8c4e 100644 --- a/src/cfml/commands/coldbox/report/routes.cfc +++ b/src/cfml/system/modules/coldbox-commands/commands/coldbox/report/routes.cfc @@ -1,7 +1,7 @@ /** * Description of command **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * diff --git a/src/cfml/commands/coldbox/stats.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/stats.cfc similarity index 58% rename from src/cfml/commands/coldbox/stats.cfc rename to src/cfml/system/modules/coldbox-commands/commands/coldbox/stats.cfc index 171ba060b..dce2a8c4e 100644 --- a/src/cfml/commands/coldbox/stats.cfc +++ b/src/cfml/system/modules/coldbox-commands/commands/coldbox/stats.cfc @@ -1,7 +1,7 @@ /** * Description of command **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * diff --git a/src/cfml/commands/coldbox/test-directory.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/test-directory.cfc similarity index 58% rename from src/cfml/commands/coldbox/test-directory.cfc rename to src/cfml/system/modules/coldbox-commands/commands/coldbox/test-directory.cfc index 171ba060b..dce2a8c4e 100644 --- a/src/cfml/commands/coldbox/test-directory.cfc +++ b/src/cfml/system/modules/coldbox-commands/commands/coldbox/test-directory.cfc @@ -1,7 +1,7 @@ /** * Description of command **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * diff --git a/src/cfml/commands/coldbox/test-watch.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/test-watch.cfc similarity index 58% rename from src/cfml/commands/coldbox/test-watch.cfc rename to src/cfml/system/modules/coldbox-commands/commands/coldbox/test-watch.cfc index 171ba060b..dce2a8c4e 100644 --- a/src/cfml/commands/coldbox/test-watch.cfc +++ b/src/cfml/system/modules/coldbox-commands/commands/coldbox/test-watch.cfc @@ -1,7 +1,7 @@ /** * Description of command **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * diff --git a/src/cfml/commands/coldbox/test.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/test.cfc similarity index 58% rename from src/cfml/commands/coldbox/test.cfc rename to src/cfml/system/modules/coldbox-commands/commands/coldbox/test.cfc index 171ba060b..dce2a8c4e 100644 --- a/src/cfml/commands/coldbox/test.cfc +++ b/src/cfml/system/modules/coldbox-commands/commands/coldbox/test.cfc @@ -1,7 +1,7 @@ /** * Description of command **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * diff --git a/src/cfml/commands/coldbox/war.cfc b/src/cfml/system/modules/coldbox-commands/commands/coldbox/war.cfc similarity index 58% rename from src/cfml/commands/coldbox/war.cfc rename to src/cfml/system/modules/coldbox-commands/commands/coldbox/war.cfc index 171ba060b..dce2a8c4e 100644 --- a/src/cfml/commands/coldbox/war.cfc +++ b/src/cfml/system/modules/coldbox-commands/commands/coldbox/war.cfc @@ -1,7 +1,7 @@ /** * Description of command **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * diff --git a/src/cfml/skeletons/Advanced.zip b/src/cfml/system/modules/coldbox-commands/skeletons/Advanced.zip similarity index 100% rename from src/cfml/skeletons/Advanced.zip rename to src/cfml/system/modules/coldbox-commands/skeletons/Advanced.zip diff --git a/src/cfml/skeletons/AdvancedScript.zip b/src/cfml/system/modules/coldbox-commands/skeletons/AdvancedScript.zip similarity index 100% rename from src/cfml/skeletons/AdvancedScript.zip rename to src/cfml/system/modules/coldbox-commands/skeletons/AdvancedScript.zip diff --git a/src/cfml/skeletons/AdvancedScriptv3.zip b/src/cfml/system/modules/coldbox-commands/skeletons/AdvancedScriptv3.zip similarity index 100% rename from src/cfml/skeletons/AdvancedScriptv3.zip rename to src/cfml/system/modules/coldbox-commands/skeletons/AdvancedScriptv3.zip diff --git a/src/cfml/skeletons/Advancedv3.zip b/src/cfml/system/modules/coldbox-commands/skeletons/Advancedv3.zip similarity index 100% rename from src/cfml/skeletons/Advancedv3.zip rename to src/cfml/system/modules/coldbox-commands/skeletons/Advancedv3.zip diff --git a/src/cfml/skeletons/Simple.zip b/src/cfml/system/modules/coldbox-commands/skeletons/Simple.zip similarity index 100% rename from src/cfml/skeletons/Simple.zip rename to src/cfml/system/modules/coldbox-commands/skeletons/Simple.zip diff --git a/src/cfml/skeletons/Simplev3.zip b/src/cfml/system/modules/coldbox-commands/skeletons/Simplev3.zip similarity index 100% rename from src/cfml/skeletons/Simplev3.zip rename to src/cfml/system/modules/coldbox-commands/skeletons/Simplev3.zip diff --git a/src/cfml/skeletons/SuperSimple.zip b/src/cfml/system/modules/coldbox-commands/skeletons/SuperSimple.zip similarity index 100% rename from src/cfml/skeletons/SuperSimple.zip rename to src/cfml/system/modules/coldbox-commands/skeletons/SuperSimple.zip diff --git a/src/cfml/skeletons/SuperSimplev3.zip b/src/cfml/system/modules/coldbox-commands/skeletons/SuperSimplev3.zip similarity index 100% rename from src/cfml/skeletons/SuperSimplev3.zip rename to src/cfml/system/modules/coldbox-commands/skeletons/SuperSimplev3.zip diff --git a/src/cfml/skeletons/rest.zip b/src/cfml/system/modules/coldbox-commands/skeletons/rest.zip similarity index 100% rename from src/cfml/skeletons/rest.zip rename to src/cfml/system/modules/coldbox-commands/skeletons/rest.zip diff --git a/src/cfml/templates/ActionContent.txt b/src/cfml/system/modules/coldbox-commands/templates/ActionContent.txt similarity index 100% rename from src/cfml/templates/ActionContent.txt rename to src/cfml/system/modules/coldbox-commands/templates/ActionContent.txt diff --git a/src/cfml/templates/ActionContentScript.txt b/src/cfml/system/modules/coldbox-commands/templates/ActionContentScript.txt similarity index 100% rename from src/cfml/templates/ActionContentScript.txt rename to src/cfml/system/modules/coldbox-commands/templates/ActionContentScript.txt diff --git a/src/cfml/templates/HandlerContent.txt b/src/cfml/system/modules/coldbox-commands/templates/HandlerContent.txt similarity index 100% rename from src/cfml/templates/HandlerContent.txt rename to src/cfml/system/modules/coldbox-commands/templates/HandlerContent.txt diff --git a/src/cfml/templates/HandlerContentScript.txt b/src/cfml/system/modules/coldbox-commands/templates/HandlerContentScript.txt similarity index 100% rename from src/cfml/templates/HandlerContentScript.txt rename to src/cfml/system/modules/coldbox-commands/templates/HandlerContentScript.txt diff --git a/src/cfml/templates/InterceptorContent.txt b/src/cfml/system/modules/coldbox-commands/templates/InterceptorContent.txt similarity index 100% rename from src/cfml/templates/InterceptorContent.txt rename to src/cfml/system/modules/coldbox-commands/templates/InterceptorContent.txt diff --git a/src/cfml/templates/InterceptorContentScript.txt b/src/cfml/system/modules/coldbox-commands/templates/InterceptorContentScript.txt similarity index 100% rename from src/cfml/templates/InterceptorContentScript.txt rename to src/cfml/system/modules/coldbox-commands/templates/InterceptorContentScript.txt diff --git a/src/cfml/templates/InterceptorMethod.txt b/src/cfml/system/modules/coldbox-commands/templates/InterceptorMethod.txt similarity index 100% rename from src/cfml/templates/InterceptorMethod.txt rename to src/cfml/system/modules/coldbox-commands/templates/InterceptorMethod.txt diff --git a/src/cfml/templates/InterceptorMethodScript.txt b/src/cfml/system/modules/coldbox-commands/templates/InterceptorMethodScript.txt similarity index 100% rename from src/cfml/templates/InterceptorMethodScript.txt rename to src/cfml/system/modules/coldbox-commands/templates/InterceptorMethodScript.txt diff --git a/src/cfml/templates/ModelContent.txt b/src/cfml/system/modules/coldbox-commands/templates/ModelContent.txt similarity index 100% rename from src/cfml/templates/ModelContent.txt rename to src/cfml/system/modules/coldbox-commands/templates/ModelContent.txt diff --git a/src/cfml/templates/ModelContentScript.txt b/src/cfml/system/modules/coldbox-commands/templates/ModelContentScript.txt similarity index 100% rename from src/cfml/templates/ModelContentScript.txt rename to src/cfml/system/modules/coldbox-commands/templates/ModelContentScript.txt diff --git a/src/cfml/templates/ModelMethodContent.txt b/src/cfml/system/modules/coldbox-commands/templates/ModelMethodContent.txt similarity index 100% rename from src/cfml/templates/ModelMethodContent.txt rename to src/cfml/system/modules/coldbox-commands/templates/ModelMethodContent.txt diff --git a/src/cfml/templates/ModelMethodContentScript.txt b/src/cfml/system/modules/coldbox-commands/templates/ModelMethodContentScript.txt similarity index 100% rename from src/cfml/templates/ModelMethodContentScript.txt rename to src/cfml/system/modules/coldbox-commands/templates/ModelMethodContentScript.txt diff --git a/src/cfml/templates/crud/HandlerContent.txt b/src/cfml/system/modules/coldbox-commands/templates/crud/HandlerContent.txt similarity index 100% rename from src/cfml/templates/crud/HandlerContent.txt rename to src/cfml/system/modules/coldbox-commands/templates/crud/HandlerContent.txt diff --git a/src/cfml/templates/crud/edit.txt b/src/cfml/system/modules/coldbox-commands/templates/crud/edit.txt similarity index 100% rename from src/cfml/templates/crud/edit.txt rename to src/cfml/system/modules/coldbox-commands/templates/crud/edit.txt diff --git a/src/cfml/templates/crud/editor.txt b/src/cfml/system/modules/coldbox-commands/templates/crud/editor.txt similarity index 100% rename from src/cfml/templates/crud/editor.txt rename to src/cfml/system/modules/coldbox-commands/templates/crud/editor.txt diff --git a/src/cfml/templates/crud/index.txt b/src/cfml/system/modules/coldbox-commands/templates/crud/index.txt similarity index 100% rename from src/cfml/templates/crud/index.txt rename to src/cfml/system/modules/coldbox-commands/templates/crud/index.txt diff --git a/src/cfml/templates/crud/new.txt b/src/cfml/system/modules/coldbox-commands/templates/crud/new.txt similarity index 100% rename from src/cfml/templates/crud/new.txt rename to src/cfml/system/modules/coldbox-commands/templates/crud/new.txt diff --git a/src/cfml/templates/crud/table.cfm b/src/cfml/system/modules/coldbox-commands/templates/crud/table.cfm similarity index 100% rename from src/cfml/templates/crud/table.cfm rename to src/cfml/system/modules/coldbox-commands/templates/crud/table.cfm diff --git a/src/cfml/templates/modules/ModuleConfig.cfc b/src/cfml/system/modules/coldbox-commands/templates/modules/ModuleConfig.cfc similarity index 98% rename from src/cfml/templates/modules/ModuleConfig.cfc rename to src/cfml/system/modules/coldbox-commands/templates/modules/ModuleConfig.cfc index 6d4cc882e..a6adc3b36 100644 --- a/src/cfml/templates/modules/ModuleConfig.cfc +++ b/src/cfml/system/modules/coldbox-commands/templates/modules/ModuleConfig.cfc @@ -60,6 +60,8 @@ Optional Methods this.modelNamespace = "@modelNamespace@"; // CF Mapping this.cfmapping = "@cfmapping@"; + // Auto-map models + this.autoMapModels = true; // Module Dependencies this.dependencies = @dependencies@; diff --git a/src/cfml/templates/modules/ModuleConfigScript.cfc b/src/cfml/system/modules/coldbox-commands/templates/modules/ModuleConfigScript.cfc similarity index 98% rename from src/cfml/templates/modules/ModuleConfigScript.cfc rename to src/cfml/system/modules/coldbox-commands/templates/modules/ModuleConfigScript.cfc index e2c5845ec..98baf7f91 100644 --- a/src/cfml/templates/modules/ModuleConfigScript.cfc +++ b/src/cfml/system/modules/coldbox-commands/templates/modules/ModuleConfigScript.cfc @@ -59,6 +59,8 @@ component { this.modelNamespace = "@modelNamespace@"; // CF Mapping this.cfmapping = "@cfmapping@"; + // Auto-map models + this.autoMapModels = true; // Module Dependencies this.dependencies = @dependencies@; diff --git a/src/cfml/templates/modules/handlers/Home.cfc b/src/cfml/system/modules/coldbox-commands/templates/modules/handlers/Home.cfc similarity index 100% rename from src/cfml/templates/modules/handlers/Home.cfc rename to src/cfml/system/modules/coldbox-commands/templates/modules/handlers/Home.cfc diff --git a/src/cfml/templates/modules/handlers/HomeScript.cfc b/src/cfml/system/modules/coldbox-commands/templates/modules/handlers/HomeScript.cfc similarity index 100% rename from src/cfml/templates/modules/handlers/HomeScript.cfc rename to src/cfml/system/modules/coldbox-commands/templates/modules/handlers/HomeScript.cfc diff --git a/src/cfml/templates/modules/models/models_here.txt b/src/cfml/system/modules/coldbox-commands/templates/modules/models/models_here.txt similarity index 100% rename from src/cfml/templates/modules/models/models_here.txt rename to src/cfml/system/modules/coldbox-commands/templates/modules/models/models_here.txt diff --git a/src/cfml/templates/modules/views/home/index.cfm b/src/cfml/system/modules/coldbox-commands/templates/modules/views/home/index.cfm similarity index 100% rename from src/cfml/templates/modules/views/home/index.cfm rename to src/cfml/system/modules/coldbox-commands/templates/modules/views/home/index.cfm diff --git a/src/cfml/templates/orm/Entity.txt b/src/cfml/system/modules/coldbox-commands/templates/orm/Entity.txt similarity index 100% rename from src/cfml/templates/orm/Entity.txt rename to src/cfml/system/modules/coldbox-commands/templates/orm/Entity.txt diff --git a/src/cfml/templates/orm/EntityScript.txt b/src/cfml/system/modules/coldbox-commands/templates/orm/EntityScript.txt similarity index 100% rename from src/cfml/templates/orm/EntityScript.txt rename to src/cfml/system/modules/coldbox-commands/templates/orm/EntityScript.txt diff --git a/src/cfml/templates/orm/ORMEventHandler.txt b/src/cfml/system/modules/coldbox-commands/templates/orm/ORMEventHandler.txt similarity index 100% rename from src/cfml/templates/orm/ORMEventHandler.txt rename to src/cfml/system/modules/coldbox-commands/templates/orm/ORMEventHandler.txt diff --git a/src/cfml/templates/orm/TemplatedEntityService.txt b/src/cfml/system/modules/coldbox-commands/templates/orm/TemplatedEntityService.txt similarity index 100% rename from src/cfml/templates/orm/TemplatedEntityService.txt rename to src/cfml/system/modules/coldbox-commands/templates/orm/TemplatedEntityService.txt diff --git a/src/cfml/templates/orm/VirtualEntityService.txt b/src/cfml/system/modules/coldbox-commands/templates/orm/VirtualEntityService.txt similarity index 100% rename from src/cfml/templates/orm/VirtualEntityService.txt rename to src/cfml/system/modules/coldbox-commands/templates/orm/VirtualEntityService.txt diff --git a/src/cfml/templates/testing/HandlerBDDCaseContent.txt b/src/cfml/system/modules/coldbox-commands/templates/testing/HandlerBDDCaseContent.txt similarity index 100% rename from src/cfml/templates/testing/HandlerBDDCaseContent.txt rename to src/cfml/system/modules/coldbox-commands/templates/testing/HandlerBDDCaseContent.txt diff --git a/src/cfml/templates/testing/HandlerBDDCaseContentScript.txt b/src/cfml/system/modules/coldbox-commands/templates/testing/HandlerBDDCaseContentScript.txt similarity index 100% rename from src/cfml/templates/testing/HandlerBDDCaseContentScript.txt rename to src/cfml/system/modules/coldbox-commands/templates/testing/HandlerBDDCaseContentScript.txt diff --git a/src/cfml/templates/testing/HandlerBDDContent.txt b/src/cfml/system/modules/coldbox-commands/templates/testing/HandlerBDDContent.txt similarity index 100% rename from src/cfml/templates/testing/HandlerBDDContent.txt rename to src/cfml/system/modules/coldbox-commands/templates/testing/HandlerBDDContent.txt diff --git a/src/cfml/templates/testing/HandlerBDDContentScript.txt b/src/cfml/system/modules/coldbox-commands/templates/testing/HandlerBDDContentScript.txt similarity index 100% rename from src/cfml/templates/testing/HandlerBDDContentScript.txt rename to src/cfml/system/modules/coldbox-commands/templates/testing/HandlerBDDContentScript.txt diff --git a/src/cfml/templates/testing/HandlerTestCaseContent.txt b/src/cfml/system/modules/coldbox-commands/templates/testing/HandlerTestCaseContent.txt similarity index 100% rename from src/cfml/templates/testing/HandlerTestCaseContent.txt rename to src/cfml/system/modules/coldbox-commands/templates/testing/HandlerTestCaseContent.txt diff --git a/src/cfml/templates/testing/HandlerTestCaseContentScript.txt b/src/cfml/system/modules/coldbox-commands/templates/testing/HandlerTestCaseContentScript.txt similarity index 100% rename from src/cfml/templates/testing/HandlerTestCaseContentScript.txt rename to src/cfml/system/modules/coldbox-commands/templates/testing/HandlerTestCaseContentScript.txt diff --git a/src/cfml/templates/testing/HandlerTestContent.txt b/src/cfml/system/modules/coldbox-commands/templates/testing/HandlerTestContent.txt similarity index 100% rename from src/cfml/templates/testing/HandlerTestContent.txt rename to src/cfml/system/modules/coldbox-commands/templates/testing/HandlerTestContent.txt diff --git a/src/cfml/templates/testing/HandlerTestContentScript.txt b/src/cfml/system/modules/coldbox-commands/templates/testing/HandlerTestContentScript.txt similarity index 100% rename from src/cfml/templates/testing/HandlerTestContentScript.txt rename to src/cfml/system/modules/coldbox-commands/templates/testing/HandlerTestContentScript.txt diff --git a/src/cfml/templates/testing/InterceptorBDDCaseContentScript.txt b/src/cfml/system/modules/coldbox-commands/templates/testing/InterceptorBDDCaseContentScript.txt similarity index 100% rename from src/cfml/templates/testing/InterceptorBDDCaseContentScript.txt rename to src/cfml/system/modules/coldbox-commands/templates/testing/InterceptorBDDCaseContentScript.txt diff --git a/src/cfml/templates/testing/InterceptorBDDContentScript.txt b/src/cfml/system/modules/coldbox-commands/templates/testing/InterceptorBDDContentScript.txt similarity index 100% rename from src/cfml/templates/testing/InterceptorBDDContentScript.txt rename to src/cfml/system/modules/coldbox-commands/templates/testing/InterceptorBDDContentScript.txt diff --git a/src/cfml/templates/testing/InterceptorTestCaseContent.txt b/src/cfml/system/modules/coldbox-commands/templates/testing/InterceptorTestCaseContent.txt similarity index 100% rename from src/cfml/templates/testing/InterceptorTestCaseContent.txt rename to src/cfml/system/modules/coldbox-commands/templates/testing/InterceptorTestCaseContent.txt diff --git a/src/cfml/templates/testing/InterceptorTestCaseContentScript.txt b/src/cfml/system/modules/coldbox-commands/templates/testing/InterceptorTestCaseContentScript.txt similarity index 100% rename from src/cfml/templates/testing/InterceptorTestCaseContentScript.txt rename to src/cfml/system/modules/coldbox-commands/templates/testing/InterceptorTestCaseContentScript.txt diff --git a/src/cfml/templates/testing/InterceptorTestContent.txt b/src/cfml/system/modules/coldbox-commands/templates/testing/InterceptorTestContent.txt similarity index 100% rename from src/cfml/templates/testing/InterceptorTestContent.txt rename to src/cfml/system/modules/coldbox-commands/templates/testing/InterceptorTestContent.txt diff --git a/src/cfml/templates/testing/InterceptorTestContentScript.txt b/src/cfml/system/modules/coldbox-commands/templates/testing/InterceptorTestContentScript.txt similarity index 100% rename from src/cfml/templates/testing/InterceptorTestContentScript.txt rename to src/cfml/system/modules/coldbox-commands/templates/testing/InterceptorTestContentScript.txt diff --git a/src/cfml/templates/testing/ModelBDDContent.txt b/src/cfml/system/modules/coldbox-commands/templates/testing/ModelBDDContent.txt similarity index 100% rename from src/cfml/templates/testing/ModelBDDContent.txt rename to src/cfml/system/modules/coldbox-commands/templates/testing/ModelBDDContent.txt diff --git a/src/cfml/templates/testing/ModelBDDContentScript.txt b/src/cfml/system/modules/coldbox-commands/templates/testing/ModelBDDContentScript.txt similarity index 100% rename from src/cfml/templates/testing/ModelBDDContentScript.txt rename to src/cfml/system/modules/coldbox-commands/templates/testing/ModelBDDContentScript.txt diff --git a/src/cfml/templates/testing/ModelBDDMethodContent.txt b/src/cfml/system/modules/coldbox-commands/templates/testing/ModelBDDMethodContent.txt similarity index 100% rename from src/cfml/templates/testing/ModelBDDMethodContent.txt rename to src/cfml/system/modules/coldbox-commands/templates/testing/ModelBDDMethodContent.txt diff --git a/src/cfml/templates/testing/ModelBDDMethodContentScript.txt b/src/cfml/system/modules/coldbox-commands/templates/testing/ModelBDDMethodContentScript.txt similarity index 100% rename from src/cfml/templates/testing/ModelBDDMethodContentScript.txt rename to src/cfml/system/modules/coldbox-commands/templates/testing/ModelBDDMethodContentScript.txt diff --git a/src/cfml/templates/testing/ModelTestContent.txt b/src/cfml/system/modules/coldbox-commands/templates/testing/ModelTestContent.txt similarity index 100% rename from src/cfml/templates/testing/ModelTestContent.txt rename to src/cfml/system/modules/coldbox-commands/templates/testing/ModelTestContent.txt diff --git a/src/cfml/templates/testing/ModelTestContentScript.txt b/src/cfml/system/modules/coldbox-commands/templates/testing/ModelTestContentScript.txt similarity index 100% rename from src/cfml/templates/testing/ModelTestContentScript.txt rename to src/cfml/system/modules/coldbox-commands/templates/testing/ModelTestContentScript.txt diff --git a/src/cfml/templates/testing/ORMEntityBDDContent.txt b/src/cfml/system/modules/coldbox-commands/templates/testing/ORMEntityBDDContent.txt similarity index 100% rename from src/cfml/templates/testing/ORMEntityBDDContent.txt rename to src/cfml/system/modules/coldbox-commands/templates/testing/ORMEntityBDDContent.txt diff --git a/src/cfml/templates/testing/ORMEntityBDDContentScript.txt b/src/cfml/system/modules/coldbox-commands/templates/testing/ORMEntityBDDContentScript.txt similarity index 100% rename from src/cfml/templates/testing/ORMEntityBDDContentScript.txt rename to src/cfml/system/modules/coldbox-commands/templates/testing/ORMEntityBDDContentScript.txt diff --git a/src/cfml/system/modules/contentbox-commands/ModuleConfig.cfc b/src/cfml/system/modules/contentbox-commands/ModuleConfig.cfc new file mode 100644 index 000000000..a400988b5 --- /dev/null +++ b/src/cfml/system/modules/contentbox-commands/ModuleConfig.cfc @@ -0,0 +1,11 @@ +/** +********************************************************************************* +* Copyright Since 2014 CommandBox by Ortus Solutions, Corp +* www.coldbox.org | www.ortussolutions.com +******************************************************************************** +* @author Brad Wood, Luis Majano +*/ +component { + function configure() { + } +} \ No newline at end of file diff --git a/src/cfml/commands/contentbox/help.cfc b/src/cfml/system/modules/contentbox-commands/commands/contentbox/help.cfc similarity index 68% rename from src/cfml/commands/contentbox/help.cfc rename to src/cfml/system/modules/contentbox-commands/commands/contentbox/help.cfc index beba8a74e..0204f0eed 100644 --- a/src/cfml/commands/contentbox/help.cfc +++ b/src/cfml/system/modules/contentbox-commands/commands/contentbox/help.cfc @@ -1,4 +1,4 @@ -component extends="commandbox.system.BaseCommand" excludeFromHelp=true { +component excludeFromHelp=true { function run() { diff --git a/src/cfml/commands/contentbox/install.cfc b/src/cfml/system/modules/contentbox-commands/commands/contentbox/install.cfc similarity index 58% rename from src/cfml/commands/contentbox/install.cfc rename to src/cfml/system/modules/contentbox-commands/commands/contentbox/install.cfc index 171ba060b..dce2a8c4e 100644 --- a/src/cfml/commands/contentbox/install.cfc +++ b/src/cfml/system/modules/contentbox-commands/commands/contentbox/install.cfc @@ -1,7 +1,7 @@ /** * Description of command **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * diff --git a/src/cfml/commands/contentbox/module/create.cfc b/src/cfml/system/modules/contentbox-commands/commands/contentbox/module/create.cfc similarity index 58% rename from src/cfml/commands/contentbox/module/create.cfc rename to src/cfml/system/modules/contentbox-commands/commands/contentbox/module/create.cfc index 171ba060b..dce2a8c4e 100644 --- a/src/cfml/commands/contentbox/module/create.cfc +++ b/src/cfml/system/modules/contentbox-commands/commands/contentbox/module/create.cfc @@ -1,7 +1,7 @@ /** * Description of command **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * diff --git a/src/cfml/commands/contentbox/module/help.cfc b/src/cfml/system/modules/contentbox-commands/commands/contentbox/module/help.cfc similarity index 69% rename from src/cfml/commands/contentbox/module/help.cfc rename to src/cfml/system/modules/contentbox-commands/commands/contentbox/module/help.cfc index 577ae5672..2246ce67e 100644 --- a/src/cfml/commands/contentbox/module/help.cfc +++ b/src/cfml/system/modules/contentbox-commands/commands/contentbox/module/help.cfc @@ -1,4 +1,4 @@ -component extends="commandbox.system.BaseCommand" excludeFromHelp=true { +component excludeFromHelp=true { function run() { diff --git a/src/cfml/commands/contentbox/module/install.cfc b/src/cfml/system/modules/contentbox-commands/commands/contentbox/module/install.cfc similarity index 58% rename from src/cfml/commands/contentbox/module/install.cfc rename to src/cfml/system/modules/contentbox-commands/commands/contentbox/module/install.cfc index 171ba060b..dce2a8c4e 100644 --- a/src/cfml/commands/contentbox/module/install.cfc +++ b/src/cfml/system/modules/contentbox-commands/commands/contentbox/module/install.cfc @@ -1,7 +1,7 @@ /** * Description of command **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * diff --git a/src/cfml/commands/contentbox/module/list.cfc b/src/cfml/system/modules/contentbox-commands/commands/contentbox/module/list.cfc similarity index 58% rename from src/cfml/commands/contentbox/module/list.cfc rename to src/cfml/system/modules/contentbox-commands/commands/contentbox/module/list.cfc index 171ba060b..dce2a8c4e 100644 --- a/src/cfml/commands/contentbox/module/list.cfc +++ b/src/cfml/system/modules/contentbox-commands/commands/contentbox/module/list.cfc @@ -1,7 +1,7 @@ /** * Description of command **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * diff --git a/src/cfml/commands/contentbox/module/remove.cfc b/src/cfml/system/modules/contentbox-commands/commands/contentbox/module/remove.cfc similarity index 58% rename from src/cfml/commands/contentbox/module/remove.cfc rename to src/cfml/system/modules/contentbox-commands/commands/contentbox/module/remove.cfc index 171ba060b..dce2a8c4e 100644 --- a/src/cfml/commands/contentbox/module/remove.cfc +++ b/src/cfml/system/modules/contentbox-commands/commands/contentbox/module/remove.cfc @@ -1,7 +1,7 @@ /** * Description of command **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * diff --git a/src/cfml/commands/contentbox/theme/create.cfc b/src/cfml/system/modules/contentbox-commands/commands/contentbox/theme/create.cfc similarity index 58% rename from src/cfml/commands/contentbox/theme/create.cfc rename to src/cfml/system/modules/contentbox-commands/commands/contentbox/theme/create.cfc index 171ba060b..dce2a8c4e 100644 --- a/src/cfml/commands/contentbox/theme/create.cfc +++ b/src/cfml/system/modules/contentbox-commands/commands/contentbox/theme/create.cfc @@ -1,7 +1,7 @@ /** * Description of command **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * diff --git a/src/cfml/commands/contentbox/theme/help.cfc b/src/cfml/system/modules/contentbox-commands/commands/contentbox/theme/help.cfc similarity index 69% rename from src/cfml/commands/contentbox/theme/help.cfc rename to src/cfml/system/modules/contentbox-commands/commands/contentbox/theme/help.cfc index 6bab13485..486d14d9f 100644 --- a/src/cfml/commands/contentbox/theme/help.cfc +++ b/src/cfml/system/modules/contentbox-commands/commands/contentbox/theme/help.cfc @@ -1,4 +1,4 @@ -component extends="commandbox.system.BaseCommand" excludeFromHelp=true { +component excludeFromHelp=true { function run() { diff --git a/src/cfml/system/modules/contentbox-commands/commands/contentbox/theme/install.cfc b/src/cfml/system/modules/contentbox-commands/commands/contentbox/theme/install.cfc new file mode 100644 index 000000000..dce2a8c4e --- /dev/null +++ b/src/cfml/system/modules/contentbox-commands/commands/contentbox/theme/install.cfc @@ -0,0 +1,13 @@ +/** + * Description of command + **/ +component { + + /** + * + **/ + function run( ) { + print.line( "Command not implemented!" ); + } + +} \ No newline at end of file diff --git a/src/cfml/commands/contentbox/theme/list.cfc b/src/cfml/system/modules/contentbox-commands/commands/contentbox/theme/list.cfc similarity index 58% rename from src/cfml/commands/contentbox/theme/list.cfc rename to src/cfml/system/modules/contentbox-commands/commands/contentbox/theme/list.cfc index 171ba060b..dce2a8c4e 100644 --- a/src/cfml/commands/contentbox/theme/list.cfc +++ b/src/cfml/system/modules/contentbox-commands/commands/contentbox/theme/list.cfc @@ -1,7 +1,7 @@ /** * Description of command **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * diff --git a/src/cfml/commands/contentbox/theme/remove.cfc b/src/cfml/system/modules/contentbox-commands/commands/contentbox/theme/remove.cfc similarity index 58% rename from src/cfml/commands/contentbox/theme/remove.cfc rename to src/cfml/system/modules/contentbox-commands/commands/contentbox/theme/remove.cfc index 171ba060b..dce2a8c4e 100644 --- a/src/cfml/commands/contentbox/theme/remove.cfc +++ b/src/cfml/system/modules/contentbox-commands/commands/contentbox/theme/remove.cfc @@ -1,7 +1,7 @@ /** * Description of command **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * diff --git a/src/cfml/commands/contentbox/widget/create.cfc b/src/cfml/system/modules/contentbox-commands/commands/contentbox/widget/create.cfc similarity index 58% rename from src/cfml/commands/contentbox/widget/create.cfc rename to src/cfml/system/modules/contentbox-commands/commands/contentbox/widget/create.cfc index 171ba060b..dce2a8c4e 100644 --- a/src/cfml/commands/contentbox/widget/create.cfc +++ b/src/cfml/system/modules/contentbox-commands/commands/contentbox/widget/create.cfc @@ -1,7 +1,7 @@ /** * Description of command **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * diff --git a/src/cfml/commands/contentbox/widget/help.cfc b/src/cfml/system/modules/contentbox-commands/commands/contentbox/widget/help.cfc similarity index 69% rename from src/cfml/commands/contentbox/widget/help.cfc rename to src/cfml/system/modules/contentbox-commands/commands/contentbox/widget/help.cfc index 898e69fc6..7e779d6f6 100644 --- a/src/cfml/commands/contentbox/widget/help.cfc +++ b/src/cfml/system/modules/contentbox-commands/commands/contentbox/widget/help.cfc @@ -1,4 +1,4 @@ -component extends="commandbox.system.BaseCommand" excludeFromHelp=true { +component excludeFromHelp=true { function run() { diff --git a/src/cfml/system/modules/contentbox-commands/commands/contentbox/widget/install.cfc b/src/cfml/system/modules/contentbox-commands/commands/contentbox/widget/install.cfc new file mode 100644 index 000000000..dce2a8c4e --- /dev/null +++ b/src/cfml/system/modules/contentbox-commands/commands/contentbox/widget/install.cfc @@ -0,0 +1,13 @@ +/** + * Description of command + **/ +component { + + /** + * + **/ + function run( ) { + print.line( "Command not implemented!" ); + } + +} \ No newline at end of file diff --git a/src/cfml/commands/contentbox/widget/list.cfc b/src/cfml/system/modules/contentbox-commands/commands/contentbox/widget/list.cfc similarity index 58% rename from src/cfml/commands/contentbox/widget/list.cfc rename to src/cfml/system/modules/contentbox-commands/commands/contentbox/widget/list.cfc index 171ba060b..dce2a8c4e 100644 --- a/src/cfml/commands/contentbox/widget/list.cfc +++ b/src/cfml/system/modules/contentbox-commands/commands/contentbox/widget/list.cfc @@ -1,7 +1,7 @@ /** * Description of command **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * diff --git a/src/cfml/system/modules/contentbox-commands/commands/contentbox/widget/remove.cfc b/src/cfml/system/modules/contentbox-commands/commands/contentbox/widget/remove.cfc new file mode 100644 index 000000000..dce2a8c4e --- /dev/null +++ b/src/cfml/system/modules/contentbox-commands/commands/contentbox/widget/remove.cfc @@ -0,0 +1,13 @@ +/** + * Description of command + **/ +component { + + /** + * + **/ + function run( ) { + print.line( "Command not implemented!" ); + } + +} \ No newline at end of file diff --git a/src/cfml/system/modules/forgebox-commands/ModuleConfig.cfc b/src/cfml/system/modules/forgebox-commands/ModuleConfig.cfc new file mode 100644 index 000000000..a400988b5 --- /dev/null +++ b/src/cfml/system/modules/forgebox-commands/ModuleConfig.cfc @@ -0,0 +1,11 @@ +/** +********************************************************************************* +* Copyright Since 2014 CommandBox by Ortus Solutions, Corp +* www.coldbox.org | www.ortussolutions.com +******************************************************************************** +* @author Brad Wood, Luis Majano +*/ +component { + function configure() { + } +} \ No newline at end of file diff --git a/src/cfml/commands/forgebox/apikey.cfc b/src/cfml/system/modules/forgebox-commands/commands/forgebox/apikey.cfc similarity index 58% rename from src/cfml/commands/forgebox/apikey.cfc rename to src/cfml/system/modules/forgebox-commands/commands/forgebox/apikey.cfc index 171ba060b..dce2a8c4e 100644 --- a/src/cfml/commands/forgebox/apikey.cfc +++ b/src/cfml/system/modules/forgebox-commands/commands/forgebox/apikey.cfc @@ -1,7 +1,7 @@ /** * Description of command **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * diff --git a/src/cfml/commands/forgebox/credentials.cfc b/src/cfml/system/modules/forgebox-commands/commands/forgebox/credentials.cfc similarity index 58% rename from src/cfml/commands/forgebox/credentials.cfc rename to src/cfml/system/modules/forgebox-commands/commands/forgebox/credentials.cfc index 171ba060b..dce2a8c4e 100644 --- a/src/cfml/commands/forgebox/credentials.cfc +++ b/src/cfml/system/modules/forgebox-commands/commands/forgebox/credentials.cfc @@ -1,7 +1,7 @@ /** * Description of command **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * diff --git a/src/cfml/commands/forgebox/disable.cfc b/src/cfml/system/modules/forgebox-commands/commands/forgebox/disable.cfc similarity index 58% rename from src/cfml/commands/forgebox/disable.cfc rename to src/cfml/system/modules/forgebox-commands/commands/forgebox/disable.cfc index 171ba060b..dce2a8c4e 100644 --- a/src/cfml/commands/forgebox/disable.cfc +++ b/src/cfml/system/modules/forgebox-commands/commands/forgebox/disable.cfc @@ -1,7 +1,7 @@ /** * Description of command **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * diff --git a/src/cfml/commands/forgebox/enable.cfc b/src/cfml/system/modules/forgebox-commands/commands/forgebox/enable.cfc similarity index 58% rename from src/cfml/commands/forgebox/enable.cfc rename to src/cfml/system/modules/forgebox-commands/commands/forgebox/enable.cfc index 171ba060b..dce2a8c4e 100644 --- a/src/cfml/commands/forgebox/enable.cfc +++ b/src/cfml/system/modules/forgebox-commands/commands/forgebox/enable.cfc @@ -1,7 +1,7 @@ /** * Description of command **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * diff --git a/src/cfml/commands/forgebox/help.cfc b/src/cfml/system/modules/forgebox-commands/commands/forgebox/help.cfc similarity index 93% rename from src/cfml/commands/forgebox/help.cfc rename to src/cfml/system/modules/forgebox-commands/commands/forgebox/help.cfc index 148d0b049..0be97da6c 100644 --- a/src/cfml/commands/forgebox/help.cfc +++ b/src/cfml/system/modules/forgebox-commands/commands/forgebox/help.cfc @@ -1,4 +1,4 @@ -component extends="commandbox.system.BaseCommand" excludeFromHelp=true { +component excludeFromHelp=true { function run() { diff --git a/src/cfml/commands/forgebox/my-contributions.cfc b/src/cfml/system/modules/forgebox-commands/commands/forgebox/my-contributions.cfc similarity index 58% rename from src/cfml/commands/forgebox/my-contributions.cfc rename to src/cfml/system/modules/forgebox-commands/commands/forgebox/my-contributions.cfc index 171ba060b..dce2a8c4e 100644 --- a/src/cfml/commands/forgebox/my-contributions.cfc +++ b/src/cfml/system/modules/forgebox-commands/commands/forgebox/my-contributions.cfc @@ -1,7 +1,7 @@ /** * Description of command **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * diff --git a/src/cfml/commands/forgebox/register.cfc b/src/cfml/system/modules/forgebox-commands/commands/forgebox/register.cfc similarity index 58% rename from src/cfml/commands/forgebox/register.cfc rename to src/cfml/system/modules/forgebox-commands/commands/forgebox/register.cfc index 171ba060b..dce2a8c4e 100644 --- a/src/cfml/commands/forgebox/register.cfc +++ b/src/cfml/system/modules/forgebox-commands/commands/forgebox/register.cfc @@ -1,7 +1,7 @@ /** * Description of command **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * diff --git a/src/cfml/commands/forgebox/search.cfc b/src/cfml/system/modules/forgebox-commands/commands/forgebox/search.cfc similarity index 90% rename from src/cfml/commands/forgebox/search.cfc rename to src/cfml/system/modules/forgebox-commands/commands/forgebox/search.cfc index 7b1aaa941..55cb595c6 100644 --- a/src/cfml/commands/forgebox/search.cfc +++ b/src/cfml/system/modules/forgebox-commands/commands/forgebox/search.cfc @@ -7,18 +7,11 @@ * {code} * . **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { // DI property name="forgeBox" inject="ForgeBox"; - /** - * Constructor - */ - function init() { - return super.init( argumentCollection = arguments ); - } - /** * @searchText.hint Text to search on **/ diff --git a/src/cfml/commands/forgebox/show.cfc b/src/cfml/system/modules/forgebox-commands/commands/forgebox/show.cfc similarity index 97% rename from src/cfml/commands/forgebox/show.cfc rename to src/cfml/system/modules/forgebox-commands/commands/forgebox/show.cfc index 1dd211ffa..895840a2f 100644 --- a/src/cfml/commands/forgebox/show.cfc +++ b/src/cfml/system/modules/forgebox-commands/commands/forgebox/show.cfc @@ -31,18 +31,11 @@ * {code} * **/ -component extends="commandbox.system.BaseCommand" aliases="show" excludeFromHelp=false { +component aliases="show" { // DI property name="forgeBox" inject="ForgeBox"; - /** - * Constructor - */ - function init() { - return super.init( argumentCollection = arguments ); - } - function onDIComplete() { variables.forgeboxOrders = forgebox.ORDER; } diff --git a/src/cfml/commands/forgebox/slugcheck.cfc b/src/cfml/system/modules/forgebox-commands/commands/forgebox/slugcheck.cfc similarity index 79% rename from src/cfml/commands/forgebox/slugcheck.cfc rename to src/cfml/system/modules/forgebox-commands/commands/forgebox/slugcheck.cfc index 5fe58780d..68c960ba3 100644 --- a/src/cfml/commands/forgebox/slugcheck.cfc +++ b/src/cfml/system/modules/forgebox-commands/commands/forgebox/slugcheck.cfc @@ -7,19 +7,11 @@ * . **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { // DI property name="forgeBox" inject="ForgeBox"; - /** - * Constructor - */ - function init(){ - super.init(); - return this; - } - /** * @slug.hint The slug to verify in ForgeBox */ diff --git a/src/cfml/commands/forgebox/types.cfc b/src/cfml/system/modules/forgebox-commands/commands/forgebox/types.cfc similarity index 78% rename from src/cfml/commands/forgebox/types.cfc rename to src/cfml/system/modules/forgebox-commands/commands/forgebox/types.cfc index 39c2b3c04..e5edce95c 100644 --- a/src/cfml/commands/forgebox/types.cfc +++ b/src/cfml/system/modules/forgebox-commands/commands/forgebox/types.cfc @@ -7,19 +7,11 @@ * . **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { // DI property name="forgeBox" inject="ForgeBox"; - /** - * Constructor - */ - function init(){ - super.init(); - return this; - } - /** * Run Command */ diff --git a/src/cfml/system/modules/games-commands/ModuleConfig.cfc b/src/cfml/system/modules/games-commands/ModuleConfig.cfc new file mode 100644 index 000000000..a400988b5 --- /dev/null +++ b/src/cfml/system/modules/games-commands/ModuleConfig.cfc @@ -0,0 +1,11 @@ +/** +********************************************************************************* +* Copyright Since 2014 CommandBox by Ortus Solutions, Corp +* www.coldbox.org | www.ortussolutions.com +******************************************************************************** +* @author Brad Wood, Luis Majano +*/ +component { + function configure() { + } +} \ No newline at end of file diff --git a/src/cfml/commands/game/snake.cfc b/src/cfml/system/modules/games-commands/commands/game/snake.cfc similarity index 99% rename from src/cfml/commands/game/snake.cfc rename to src/cfml/system/modules/games-commands/commands/game/snake.cfc index e003edeb1..2f7755614 100644 --- a/src/cfml/commands/game/snake.cfc +++ b/src/cfml/system/modules/games-commands/commands/game/snake.cfc @@ -12,7 +12,7 @@ * {code} **/ -component extends="commandbox.system.BaseCommand" aliases="snake" excludeFromHelp=false { +component aliases="snake" { processingdirective pageEncoding='UTF-8'; diff --git a/src/cfml/system/modules/logbox-commands/ModuleConfig.cfc b/src/cfml/system/modules/logbox-commands/ModuleConfig.cfc new file mode 100644 index 000000000..a400988b5 --- /dev/null +++ b/src/cfml/system/modules/logbox-commands/ModuleConfig.cfc @@ -0,0 +1,11 @@ +/** +********************************************************************************* +* Copyright Since 2014 CommandBox by Ortus Solutions, Corp +* www.coldbox.org | www.ortussolutions.com +******************************************************************************** +* @author Brad Wood, Luis Majano +*/ +component { + function configure() { + } +} \ No newline at end of file diff --git a/src/cfml/commands/logbox/create/appender.cfc b/src/cfml/system/modules/logbox-commands/commands/logbox/create/appender.cfc similarity index 58% rename from src/cfml/commands/logbox/create/appender.cfc rename to src/cfml/system/modules/logbox-commands/commands/logbox/create/appender.cfc index 171ba060b..dce2a8c4e 100644 --- a/src/cfml/commands/logbox/create/appender.cfc +++ b/src/cfml/system/modules/logbox-commands/commands/logbox/create/appender.cfc @@ -1,7 +1,7 @@ /** * Description of command **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * diff --git a/src/cfml/commands/cachebox/create/config.cfc b/src/cfml/system/modules/logbox-commands/commands/logbox/create/config.cfc similarity index 58% rename from src/cfml/commands/cachebox/create/config.cfc rename to src/cfml/system/modules/logbox-commands/commands/logbox/create/config.cfc index 171ba060b..dce2a8c4e 100644 --- a/src/cfml/commands/cachebox/create/config.cfc +++ b/src/cfml/system/modules/logbox-commands/commands/logbox/create/config.cfc @@ -1,7 +1,7 @@ /** * Description of command **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * diff --git a/src/cfml/commands/logbox/create/help.cfc b/src/cfml/system/modules/logbox-commands/commands/logbox/create/help.cfc similarity index 68% rename from src/cfml/commands/logbox/create/help.cfc rename to src/cfml/system/modules/logbox-commands/commands/logbox/create/help.cfc index 4de8690ee..b05fec6ec 100644 --- a/src/cfml/commands/logbox/create/help.cfc +++ b/src/cfml/system/modules/logbox-commands/commands/logbox/create/help.cfc @@ -1,4 +1,4 @@ -component extends="commandbox.system.BaseCommand" excludeFromHelp=true { +component excludeFromHelp=true { function run() { diff --git a/src/cfml/commands/logbox/help.cfc b/src/cfml/system/modules/logbox-commands/commands/logbox/help.cfc similarity index 67% rename from src/cfml/commands/logbox/help.cfc rename to src/cfml/system/modules/logbox-commands/commands/logbox/help.cfc index 533361459..4bf0ea640 100644 --- a/src/cfml/commands/logbox/help.cfc +++ b/src/cfml/system/modules/logbox-commands/commands/logbox/help.cfc @@ -1,4 +1,4 @@ -component extends="commandbox.system.BaseCommand" excludeFromHelp=true { +component excludeFromHelp=true { function run() { diff --git a/src/cfml/templates/logbox/LogBox.txt b/src/cfml/system/modules/logbox-commands/templates/logbox/LogBox.txt similarity index 100% rename from src/cfml/templates/logbox/LogBox.txt rename to src/cfml/system/modules/logbox-commands/templates/logbox/LogBox.txt diff --git a/src/cfml/system/modules/package-commands/ModuleConfig.cfc b/src/cfml/system/modules/package-commands/ModuleConfig.cfc new file mode 100644 index 000000000..a400988b5 --- /dev/null +++ b/src/cfml/system/modules/package-commands/ModuleConfig.cfc @@ -0,0 +1,11 @@ +/** +********************************************************************************* +* Copyright Since 2014 CommandBox by Ortus Solutions, Corp +* www.coldbox.org | www.ortussolutions.com +******************************************************************************** +* @author Brad Wood, Luis Majano +*/ +component { + function configure() { + } +} \ No newline at end of file diff --git a/src/cfml/commands/package/bugs.cfc b/src/cfml/system/modules/package-commands/commands/package/bugs.cfc similarity index 88% rename from src/cfml/commands/package/bugs.cfc rename to src/cfml/system/modules/package-commands/commands/package/bugs.cfc index 3b91b42ef..3bf2440e8 100644 --- a/src/cfml/commands/package/bugs.cfc +++ b/src/cfml/system/modules/package-commands/commands/package/bugs.cfc @@ -10,7 +10,7 @@ * bugs * {code} **/ -component extends="commandbox.system.BaseCommand" aliases="bugs" excludeFromHelp=false { +component aliases="bugs" { property name="packageService" inject="PackageService"; diff --git a/src/cfml/system/modules/package-commands/commands/package/clear.cfc b/src/cfml/system/modules/package-commands/commands/package/clear.cfc new file mode 100644 index 000000000..8c4c3d270 --- /dev/null +++ b/src/cfml/system/modules/package-commands/commands/package/clear.cfc @@ -0,0 +1,57 @@ +/** + * Remove a property out of the box.json for this package. Command must be executed from the root + * directory of the package where box.json lives. + * Nested attributes may be set by specifying dot-delimited names or using array notation. + * . + * {code:bash} + * package clear description + * {code} + * . + **/ +component { + + property name="packageService" inject="PackageService"; + property name="JSONService" inject="JSONService"; + + /** + * @property.hint Name of the property to clear + * @property.optionsUDF completeProperty + **/ + function run( required string property ) { + var directory = getCWD(); + + // Check and see if box.json exists + if( !packageService.isPackage( directory ) ) { + return error( 'File [#packageService.getDescriptorPath( directory )#] does not exist. Use the "init" command to create it.' ); + } + + if( arguments.property == 'name' ) { + return error( '[name] is a required property and cannot be cleared.' ); + } + if( arguments.property == 'slug' ) { + return error( '[slug] is a required property and cannot be cleared.' ); + } + var boxJSON = packageService.readPackageDescriptorRaw( directory ); + + try { + JSONService.clear( boxJSON, arguments.property ); + } catch( JSONException var e ) { + error( e.message ); + } catch( any var e ) { + rethrow; + } + + print.greenLine( 'Removed #arguments.property#' ); + + // Write the file back out. + PackageService.writePackageDescriptor( boxJSON, directory ); + + } + + // Dynamic completion for property name based on contents of box.json + function completeProperty() { + var directory = fileSystemUtil.resolvePath( '' ); + return packageService.completeProperty( directory ); + } + +} \ No newline at end of file diff --git a/src/cfml/commands/package/documentation.cfc b/src/cfml/system/modules/package-commands/commands/package/documentation.cfc similarity index 87% rename from src/cfml/commands/package/documentation.cfc rename to src/cfml/system/modules/package-commands/commands/package/documentation.cfc index 43479069e..61c9cbe97 100644 --- a/src/cfml/commands/package/documentation.cfc +++ b/src/cfml/system/modules/package-commands/commands/package/documentation.cfc @@ -10,7 +10,7 @@ * bugs * {code} **/ -component extends="commandbox.system.BaseCommand" aliases="docs,documentation" excludeFromHelp=false { +component aliases="docs,documentation" { property name="packageService" inject="PackageService"; diff --git a/src/cfml/commands/package/help.cfc b/src/cfml/system/modules/package-commands/commands/package/help.cfc similarity index 86% rename from src/cfml/commands/package/help.cfc rename to src/cfml/system/modules/package-commands/commands/package/help.cfc index 006c2ad15..8e07d155d 100644 --- a/src/cfml/commands/package/help.cfc +++ b/src/cfml/system/modules/package-commands/commands/package/help.cfc @@ -1,4 +1,4 @@ -component extends="commandbox.system.BaseCommand" excludeFromHelp=true { +component excludeFromHelp=true { function run() { diff --git a/src/cfml/commands/package/homepage.cfc b/src/cfml/system/modules/package-commands/commands/package/homepage.cfc similarity index 88% rename from src/cfml/commands/package/homepage.cfc rename to src/cfml/system/modules/package-commands/commands/package/homepage.cfc index d525dc296..a99c3a7c2 100644 --- a/src/cfml/commands/package/homepage.cfc +++ b/src/cfml/system/modules/package-commands/commands/package/homepage.cfc @@ -10,7 +10,7 @@ * homepage * {code} **/ -component extends="commandbox.system.BaseCommand" aliases="homepage" excludeFromHelp=false { +component aliases="homepage" { property name="packageService" inject="PackageService"; diff --git a/src/cfml/commands/package/init-wizard.cfc b/src/cfml/system/modules/package-commands/commands/package/init-wizard.cfc similarity index 94% rename from src/cfml/commands/package/init-wizard.cfc rename to src/cfml/system/modules/package-commands/commands/package/init-wizard.cfc index 6b0cacdfb..34e4c7419 100644 --- a/src/cfml/commands/package/init-wizard.cfc +++ b/src/cfml/system/modules/package-commands/commands/package/init-wizard.cfc @@ -1,7 +1,7 @@ /** * Initialize a package in the current directory by creating a default box.json file using our lovely wizard **/ -component extends="init" aliases="" excludeFromHelp=false { +component extends="init" { /** * @name The human-readable name for this package diff --git a/src/cfml/commands/package/init.cfc b/src/cfml/system/modules/package-commands/commands/package/init.cfc similarity index 97% rename from src/cfml/commands/package/init.cfc rename to src/cfml/system/modules/package-commands/commands/package/init.cfc index ab70a6f8c..6780561ba 100644 --- a/src/cfml/commands/package/init.cfc +++ b/src/cfml/system/modules/package-commands/commands/package/init.cfc @@ -18,7 +18,7 @@ * {code} * **/ -component extends="commandbox.system.BaseCommand" aliases="init" excludeFromHelp=false { +component aliases="init" { // DI property name="PackageService" inject="PackageService"; diff --git a/src/cfml/commands/package/install.cfc b/src/cfml/system/modules/package-commands/commands/package/install.cfc similarity index 92% rename from src/cfml/commands/package/install.cfc rename to src/cfml/system/modules/package-commands/commands/package/install.cfc index 25f730354..be85bce2c 100644 --- a/src/cfml/commands/package/install.cfc +++ b/src/cfml/system/modules/package-commands/commands/package/install.cfc @@ -1,12 +1,12 @@ /** * Download and install an entry from an endpoint (like ForgeBox) into your application or read the box.json descriptor - * and install all production/development dependencies in your project if no ID is passed. + * and install all production/development dependencies in your project if no ID is passed. * . * Install the feeds package from ForgeBox and save as a dependency * {code:bash} * install feeds * {code} - * . + * . * Override the installation location by passing the "directory" parameter. * {code:bash} * install coldbox ../lib/frameworks/ @@ -34,13 +34,13 @@ * install --production * {code} * . - * You can also specify the version of a package you want to install from Forgebox. Note, this only - * currently works if the specified version of the package is in your local artifacts folder. + * You can also specify the version of a package you want to install from Forgebox. Note, this only + * currently works if the specified version of the package is in your local artifacts folder. * {code:bash} * install coldbox@3.8.1 * {code} * . - * Installation from endpoints other than ForgeBox is supported. + * Installation from endpoints other than ForgeBox is supported. * Additional endpoints include HTTP/HTTPS, local zip file or folder, Git repos, CFlib.org, and RIAForge.org * . * {code:bash} @@ -50,12 +50,13 @@ * install git://site.com/user/repo.git * install git+https://site.com/user/repo.git * install git+ssh://site.com:user/repo.git + * install git+ssh://git@github.com:user/repo.git * {code} * . * The git+ssh endpoint will look for a private SSH key in your ~/.ssh directory named "id_rsa", "id_dsa", or "identity". - * That matching public key needs to be registered in the Git server. - * . - * Git repos are cloned and the "master" branch used by default. + * That matching public key needs to be registered in the Git server. + * . + * Git repos are cloned and the "master" branch used by default. * You can also use a committ-ish to target a branch, tag, or commit * . * {code:bash} @@ -83,8 +84,8 @@ * install riaforge:iwantmylastfm * {code} **/ -component extends="commandbox.system.BaseCommand" aliases="install" excludeFromHelp=false { - +component aliases="install" { + /** * The ForgeBox entries cache */ @@ -93,18 +94,18 @@ component extends="commandbox.system.BaseCommand" aliases="install" excludeFromH // DI property name="forgeBox" inject="ForgeBox"; property name="packageService" inject="PackageService"; - + /** * @ID.hint "endpoint:package" to install. Default endpoint is "forgebox". If no ID is passed, all dependencies in box.json will be installed. * @ID.optionsUDF IDComplete - * @directory.hint The directory to install in and creates the directory if it does not exist. This will override the packages's box.json install dir if provided. + * @directory.hint The directory to install in and creates the directory if it does not exist. This will override the packages's box.json install dir if provided. * @save.hint Save the installed package as a dependancy in box.json (if it exists), defaults to true * @saveDev.hint Save the installed package as a dev dependancy in box.json (if it exists) * @production.hint When calling this command with no ID to install all dependencies, set this to true to ignore devDependencies. * @verbose.hint If set, it will produce much more verbose information about the package installation * @force.hint When set to true, it will force dependencies to be installed whether they already exist or not **/ - function run( + function run( string ID='', string directory, boolean save=true, @@ -113,20 +114,20 @@ component extends="commandbox.system.BaseCommand" aliases="install" excludeFromH boolean verbose=false, boolean force=false ){ - - // Don't default the dir param since we need to differentiate whether the user actually + + // Don't default the dir param since we need to differentiate whether the user actually // specifically typed in a param or not since it overrides the package's box.json install dir. if( structKeyExists( arguments, 'directory' ) ) { - + arguments.directory = fileSystemUtil.resolvePath( arguments.directory ); - + // Validate directory if( !directoryExists( arguments.directory ) ) { directoryCreate( arguments.directory ); } - + } - + // TODO: climb tree to find root of the site by searching for box.json arguments.currentWorkingDirectory = getCWD(); // Make ID an array @@ -135,19 +136,19 @@ component extends="commandbox.system.BaseCommand" aliases="install" excludeFromH // Install this package(s). // Don't pass directory unless you intend to override the box.json of the package being installed - + // One or more IDs if( arguments.IDArray.len() ) { for( var thisID in arguments.IDArray ){ - arguments.ID = thisID; + arguments.ID = thisID; packageService.installPackage( argumentCollection = arguments ); } // No ID, just install the dependencies in box.json } else { - arguments.ID = ''; - packageService.installPackage( argumentCollection = arguments ); + arguments.ID = ''; + packageService.installPackage( argumentCollection = arguments ); } - + } // Auto-complete list of IDs @@ -155,17 +156,17 @@ component extends="commandbox.system.BaseCommand" aliases="install" excludeFromH var result = []; // Cache in command if( !structKeyExists( variables, 'entries' ) ) { - variables.entries = forgebox.getEntries(); + variables.entries = forgebox.getEntries(); } - + // Loop over results and append all active ForgeBox entries for( var entry in variables.entries ) { if( val( entry.isactive ) ) { result.append( entry.slug ); } } - + return result; } -} \ No newline at end of file +} diff --git a/src/cfml/commands/package/list.cfc b/src/cfml/system/modules/package-commands/commands/package/list.cfc similarity index 96% rename from src/cfml/commands/package/list.cfc rename to src/cfml/system/modules/package-commands/commands/package/list.cfc index f9fe67c87..41a6f8c23 100644 --- a/src/cfml/commands/package/list.cfc +++ b/src/cfml/system/modules/package-commands/commands/package/list.cfc @@ -19,7 +19,7 @@ * list --JSON * {code} **/ -component extends="commandbox.system.BaseCommand" aliases="list" excludeFromHelp=false { +component aliases="list" { processingdirective pageEncoding='UTF-8'; diff --git a/src/cfml/commands/package/outdated.cfc b/src/cfml/system/modules/package-commands/commands/package/outdated.cfc similarity index 96% rename from src/cfml/commands/package/outdated.cfc rename to src/cfml/system/modules/package-commands/commands/package/outdated.cfc index 6589a48da..8a62cee55 100644 --- a/src/cfml/commands/package/outdated.cfc +++ b/src/cfml/system/modules/package-commands/commands/package/outdated.cfc @@ -18,7 +18,7 @@ * outdated --JSON * {code} **/ -component extends="commandbox.system.BaseCommand" aliases="outdated" excludeFromHelp=false { +component aliases="outdated" { processingdirective pageEncoding='UTF-8'; diff --git a/src/cfml/system/modules/package-commands/commands/package/set.cfc b/src/cfml/system/modules/package-commands/commands/package/set.cfc new file mode 100644 index 000000000..c8acdde45 --- /dev/null +++ b/src/cfml/system/modules/package-commands/commands/package/set.cfc @@ -0,0 +1,86 @@ +/** + * Set values set in box.json for this package. Command must be executed from the root + * directory of the package where box.json lives. + * . + * set package name + * {code:bash} + * package set name=myPackage + * {code} + * . + * Nested attributes may be set by specifying dot-delimited names or using array notation. + * If the set value is JSON, it will be stored as a complex value in the box.json. + * . + * set repo type + * {code:bash} + * package set repository.type=Git + * {code} + * . + * set first testbox notify E-mail + * {code:bash} + * package set testbox.notify.email[1]="brad@bradwood.com" + * {code} + * . + * Set multiple params at once + * {code:bash} + * package set name=myPackage version="1.0.0" author="Brad Wood" slug="foo" + * {code} + * . + * Set complex value as JSON + * {code:bash} + * package set testbox.notify.emails="[ 'test@test.com', 'me@example.com' ]" + * {code} + * . + * Structs and arrays can be appended to using the "append" parameter. + * . + * Add an additional contributor to the existing list + * This only works if the property and incoming value are both of the same complex type. + * {code:bash} + * package set contributors="[ 'brad@coldbox.org' ]" --append + * {code} + * + **/ +component { + + property name="packageService" inject="PackageService"; + property name="JSONService" inject="JSONService"; + + /** + * This param is a dummy param just to get the custom completor to work. + * The actual parameter names will be whatever property name the user wants to set + * @_.hint Pass any number of property names in followed by the value to set + * @_.optionsUDF completeProperty + * @append.hint If setting an array or struct, set to true to append instead of overwriting. + **/ + function run( _, boolean append=false ) { + var thisAppend = arguments.append; + var directory = getCWD(); + + // Remove dummy args + structDelete( arguments, '_' ); + structDelete( arguments, 'append' ); + + // Check and see if box.json exists + if( !packageService.isPackage( directory ) ) { + return error( 'File [#packageService.getDescriptorPath( directory )#] does not exist. Use the "init" command to create it.' ); + } + // Read without defaulted values + var boxJSON = packageService.readPackageDescriptorRaw( directory ); + + var results = JSONService.set( boxJSON, arguments, thisAppend ); + + // Write the file back out. + PackageService.writePackageDescriptor( boxJSON, directory ); + + for( var message in results ) { + print.greeLine( message ); + } + + } + + // Dynamic completion for property name based on contents of box.json + function completeProperty() { + var directory = fileSystemUtil.resolvePath( '' ); + // all=true will cause "package set" to prompt all possible box.json properties + return packageService.completeProperty( directory, true ); + } +} \ No newline at end of file diff --git a/src/cfml/commands/package/show.cfc b/src/cfml/system/modules/package-commands/commands/package/show.cfc similarity index 58% rename from src/cfml/commands/package/show.cfc rename to src/cfml/system/modules/package-commands/commands/package/show.cfc index c0eb765b2..179241814 100644 --- a/src/cfml/commands/package/show.cfc +++ b/src/cfml/system/modules/package-commands/commands/package/show.cfc @@ -26,18 +26,16 @@ * {code} * . **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { property name="packageService" inject="PackageService"; - property name="formatterUtil" inject="Formatter"; + property name="JSONService" inject="JSONService"; /** * @property.hint The name of the property to show. Can nested to get "deep" properties * @property.optionsUDF completeProperty **/ - function run( string property ) { - - // This will make each directory canonical and absolute + function run( string property='' ) { var directory = getCWD(); // Check and see if box.json exists @@ -46,32 +44,24 @@ component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=fal } // Read without defaulted values - boxJSON = packageService.readPackageDescriptorRaw( directory ); - - // Convert foo.bar-baz[1] to ['foo']['bar-baz'][1] - var tmpProperty = replace( arguments.property, '[', '.[', 'all' ); - tmpProperty = replace( tmpProperty, ']', '].', 'all' ); - var fullPropertyName = ''; - for( var item in listToArray( tmpProperty, '.' ) ) { - if( item.startsWith( '[' ) ) { - fullPropertyName &= item; + var boxJSON = packageService.readPackageDescriptorRaw( directory ); + + try { + + var propertyValue = JSONService.show( boxJSON, arguments.property ); + + if( isSimpleValue( propertyValue ) ) { + print.line( propertyValue ); } else { - fullPropertyName &= '[ "#item#" ]'; + print.line( formatterUtil.formatJson( propertyValue ) ); } - } - fullPropertyName = 'boxJSON' & fullPropertyName; - - if( !isDefined( fullPropertyName ) ) { - return error( 'Property [#arguments.property#] doesn''t exist in this package''s box.json' ); - } - var propertyValue = evaluate( fullPropertyName ); - - if( isSimpleValue( propertyValue ) ) { - print.line( propertyValue ); - } else { - print.line( formatterUtil.formatJson( propertyValue ) ); + } catch( JSONException var e ) { + error( e.message ); + } catch( any var e ) { + rethrow; } + } // Dynamic completion for property name based on contents of box.json diff --git a/src/cfml/commands/package/uninstall.cfc b/src/cfml/system/modules/package-commands/commands/package/uninstall.cfc similarity index 96% rename from src/cfml/commands/package/uninstall.cfc rename to src/cfml/system/modules/package-commands/commands/package/uninstall.cfc index 25517edec..a9df1763f 100644 --- a/src/cfml/commands/package/uninstall.cfc +++ b/src/cfml/system/modules/package-commands/commands/package/uninstall.cfc @@ -17,7 +17,7 @@ * {code} * . **/ -component extends="commandbox.system.BaseCommand" aliases="uninstall" excludeFromHelp=false { +component aliases="uninstall" { /** * The ForgeBox entries cache diff --git a/src/cfml/commands/package/update.cfc b/src/cfml/system/modules/package-commands/commands/package/update.cfc similarity index 97% rename from src/cfml/commands/package/update.cfc rename to src/cfml/system/modules/package-commands/commands/package/update.cfc index 9e95ebe61..ad39b4287 100644 --- a/src/cfml/commands/package/update.cfc +++ b/src/cfml/system/modules/package-commands/commands/package/update.cfc @@ -26,7 +26,7 @@ * update coldbox --force * {code} **/ -component extends="commandbox.system.BaseCommand" aliases="update" excludeFromHelp=false { +component aliases="update" { processingdirective pageEncoding='UTF-8'; diff --git a/src/cfml/commands/package/version.cfc b/src/cfml/system/modules/package-commands/commands/package/version.cfc similarity index 95% rename from src/cfml/commands/package/version.cfc rename to src/cfml/system/modules/package-commands/commands/package/version.cfc index 9f5ac1a1c..00463e995 100644 --- a/src/cfml/commands/package/version.cfc +++ b/src/cfml/system/modules/package-commands/commands/package/version.cfc @@ -26,7 +26,7 @@ * If multiple version parts are specified, the "larger" one will be used starting with major. * If a version AND a flag are both supplied, the version will be used and the flag(s) ignored. **/ -component extends="commandbox.system.BaseCommand" aliases="bump" excludeFromHelp=false { +component aliases="bump" { property name='packageService' inject='PackageService'; property name='semanticVersion' inject='semanticVersion'; @@ -58,17 +58,20 @@ component extends="commandbox.system.BaseCommand" aliases="bump" excludeFromHelp // Bump major versionObject.major = val( versionObject.major ) + 1; + versionObject.minor = 0; + versionObject.revision = 0; setVersion( semanticVersion.getVersionAsString( versionObject ) ); } else if( structKeyExists( arguments, 'minor' ) && arguments.minor ) { // Bump minor versionObject.minor = val( versionObject.minor ) + 1; + versionObject.revision = 0; setVersion( semanticVersion.getVersionAsString( versionObject ) ); } else if( structKeyExists( arguments, 'patch' ) && arguments.patch ) { - // Bump patc + // Bump patch versionObject.revision = val( versionObject.revision ) + 1; setVersion( semanticVersion.getVersionAsString( versionObject ) ); diff --git a/src/cfml/system/modules/server-commands/ModuleConfig.cfc b/src/cfml/system/modules/server-commands/ModuleConfig.cfc new file mode 100644 index 000000000..a400988b5 --- /dev/null +++ b/src/cfml/system/modules/server-commands/ModuleConfig.cfc @@ -0,0 +1,11 @@ +/** +********************************************************************************* +* Copyright Since 2014 CommandBox by Ortus Solutions, Corp +* www.coldbox.org | www.ortussolutions.com +******************************************************************************** +* @author Brad Wood, Luis Majano +*/ +component { + function configure() { + } +} \ No newline at end of file diff --git a/src/cfml/commands/server/cd.cfc b/src/cfml/system/modules/server-commands/commands/server/cd.cfc similarity index 91% rename from src/cfml/commands/server/cd.cfc rename to src/cfml/system/modules/server-commands/commands/server/cd.cfc index 6f6611851..b0c085d1b 100644 --- a/src/cfml/commands/server/cd.cfc +++ b/src/cfml/system/modules/server-commands/commands/server/cd.cfc @@ -5,7 +5,7 @@ * server cd myServer * {code} **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { // DI property name="serverService" inject="ServerService"; diff --git a/src/cfml/system/modules/server-commands/commands/server/clear.cfc b/src/cfml/system/modules/server-commands/commands/server/clear.cfc new file mode 100644 index 000000000..ef456428b --- /dev/null +++ b/src/cfml/system/modules/server-commands/commands/server/clear.cfc @@ -0,0 +1,45 @@ +/** + * Remove a property out of the server.json for this server. Command must be executed from the web root + * directory of the server where server.json lives. + * Nested attributes may be set by specifying dot-delimited names or using array notation. + * . + * {code:bash} + * server clear port + * {code} + * . + **/ +component { + + property name="serverService" inject="ServerService"; + property name="JSONService" inject="JSONService"; + + /** + * @property.hint Name of the property to clear + * @property.optionsUDF completeProperty + **/ + function run( required string property ) { + var directory = getCWD(); + + var serverJSON = ServerService.readServerJSON( directory ); + + try { + JSONService.clear( serverJSON, arguments.property ); + } catch( JSONException var e ) { + error( e.message ); + } catch( any var e ) { + rethrow; + } + + print.greenLine( 'Removed #arguments.property#' ); + + // Write the file back out. + ServerService.saveServerJSON( directory, serverJSON ); + + } + + // Dynamic completion for property name based on contents of server.json + function completeProperty() { + return serverService.completeProperty( getCWD() ); + } + +} \ No newline at end of file diff --git a/src/cfml/commands/server/forget.cfc b/src/cfml/system/modules/server-commands/commands/server/forget.cfc similarity index 95% rename from src/cfml/commands/server/forget.cfc rename to src/cfml/system/modules/server-commands/commands/server/forget.cfc index c4797f102..3c73e2537 100644 --- a/src/cfml/commands/server/forget.cfc +++ b/src/cfml/system/modules/server-commands/commands/server/forget.cfc @@ -8,7 +8,7 @@ * server forget --all --force * {code} **/ -component extends="commandbox.system.BaseCommand" excludeFromHelp=false { +component { // di property name="serverService" inject="ServerService"; diff --git a/src/cfml/commands/server/help.cfc b/src/cfml/system/modules/server-commands/commands/server/help.cfc similarity index 83% rename from src/cfml/commands/server/help.cfc rename to src/cfml/system/modules/server-commands/commands/server/help.cfc index 2aded00e3..7fb91cb2f 100644 --- a/src/cfml/commands/server/help.cfc +++ b/src/cfml/system/modules/server-commands/commands/server/help.cfc @@ -1,4 +1,4 @@ -component extends="commandbox.system.BaseCommand" excludeFromHelp=true { +component excludeFromHelp=true { function run() { diff --git a/src/cfml/commands/server/list.cfc b/src/cfml/system/modules/server-commands/commands/server/list.cfc similarity index 98% rename from src/cfml/commands/server/list.cfc rename to src/cfml/system/modules/server-commands/commands/server/list.cfc index 0b7e74c02..4d53b5ab8 100644 --- a/src/cfml/commands/server/list.cfc +++ b/src/cfml/system/modules/server-commands/commands/server/list.cfc @@ -28,7 +28,7 @@ * {code} * . **/ -component extends="commandbox.system.BaseCommand" excludeFromHelp=false { +component { // DI property name="serverService" inject="ServerService"; diff --git a/src/cfml/commands/server/log.cfc b/src/cfml/system/modules/server-commands/commands/server/log.cfc similarity index 94% rename from src/cfml/commands/server/log.cfc rename to src/cfml/system/modules/server-commands/commands/server/log.cfc index 5314edcc9..70ad7e73e 100644 --- a/src/cfml/commands/server/log.cfc +++ b/src/cfml/system/modules/server-commands/commands/server/log.cfc @@ -6,7 +6,7 @@ * server log name=serverName * {code} **/ -component extends="commandbox.system.BaseCommand" excludeFromHelp=false { +component { property name="serverService" inject="ServerService"; diff --git a/src/cfml/commands/server/open.cfc b/src/cfml/system/modules/server-commands/commands/server/open.cfc similarity index 91% rename from src/cfml/commands/server/open.cfc rename to src/cfml/system/modules/server-commands/commands/server/open.cfc index 25373c886..3be3bb0c3 100644 --- a/src/cfml/commands/server/open.cfc +++ b/src/cfml/system/modules/server-commands/commands/server/open.cfc @@ -6,7 +6,7 @@ * server open * {code} **/ -component extends="commandbox.system.BaseCommand" aliases="fwreinit" excludeFromHelp=false { +component { // DI property name="serverService" inject="ServerService"; diff --git a/src/cfml/commands/server/restart.cfc b/src/cfml/system/modules/server-commands/commands/server/restart.cfc similarity index 87% rename from src/cfml/commands/server/restart.cfc rename to src/cfml/system/modules/server-commands/commands/server/restart.cfc index cc106f519..d7c2b9523 100644 --- a/src/cfml/commands/server/restart.cfc +++ b/src/cfml/system/modules/server-commands/commands/server/restart.cfc @@ -7,7 +7,7 @@ * server restart myapp * {code} **/ -component extends="commandbox.system.BaseCommand" aliases="restart" excludeFromHelp=false { +component aliases="restart" { // DI property name="serverService" inject="ServerService"; @@ -40,7 +40,7 @@ component extends="commandbox.system.BaseCommand" aliases="restart" excludeFromH } var stopCommand = "server stop '#serverInfo.name#'"; - var startCommand = "server start name='#serverInfo.name#' openBrowser=#arguments.openBrowser# port=#serverInfo.port# force=#arguments.force#"; + var startCommand = "server start name='#serverInfo.name#' port=#serverInfo.port# openBrowser=#arguments.openBrowser# --!saveSettings"; // stop server print.boldCyanLine( "Trying to stop server..." ); diff --git a/src/cfml/system/modules/server-commands/commands/server/set.cfc b/src/cfml/system/modules/server-commands/commands/server/set.cfc new file mode 100644 index 000000000..3375a65fc --- /dev/null +++ b/src/cfml/system/modules/server-commands/commands/server/set.cfc @@ -0,0 +1,79 @@ +/** + * Set values set in server.json for this server. Command must be executed from the web root + * directory of the server where server.json lives. + * . + * set server port + * {code:bash} + * server set port=8080 + * {code} + * . + * Nested attributes may be set by specifying dot-delimited names or using array notation. + * If the set value is JSON, it will be stored as a complex value in the server.json. + * . + * Set a nested key + * {code:bash} + * server set extra.info=value + * {code} + * . + * set an item in an array + * {code:bash} + * server set aliases[1]="/js" + * {code} + * . + * Set multiple params at once + * {code:bash} + * server set name=myServer port="8080" + * {code} + * . + * Set complex value as JSON + * {code:bash} + * server set aliases="[ '/js', '/css' ]" + * {code} + * . + * Structs and arrays can be appended to using the "append" parameter. + * . + * This only works if the property and incoming value are both of the same complex type. + * {code:bash} + * server set aliases="[ '/includes' ]" --append + * {code} + * + **/ +component { + + property name="ServerService" inject="ServerService"; + property name="JSONService" inject="JSONService"; + + /** + * This param is a dummy param just to get the custom completor to work. + * The actual parameter names will be whatever property name the user wants to set + * @_.hint Pass any number of property names in followed by the value to set + * @_.optionsUDF completeProperty + * @append.hint If setting an array or struct, set to true to append instead of overwriting. + **/ + function run( _, boolean append=false ) { + var thisAppend = arguments.append; + var directory = getCWD(); + + // Remove dummy args + structDelete( arguments, '_' ); + structDelete( arguments, 'append' ); + + var serverJSON = ServerService.readServerJSON( directory ); + + var results = JSONService.set( serverJSON, arguments, thisAppend ); + + // Write the file back out. + ServerService.saveServerJSON( directory, serverJSON ); + + for( var message in results ) { + print.greeLine( message ); + } + + } + + // Dynamic completion for property name based on contents of server.json + function completeProperty() { + // all=true will cause "server set" to prompt all possible server.json properties + return ServerService.completeProperty( getCWD(), true ); + } +} \ No newline at end of file diff --git a/src/cfml/system/modules/server-commands/commands/server/show.cfc b/src/cfml/system/modules/server-commands/commands/server/show.cfc new file mode 100644 index 000000000..54b6653ea --- /dev/null +++ b/src/cfml/system/modules/server-commands/commands/server/show.cfc @@ -0,0 +1,59 @@ +/** + * View proprties set in server.json for this server. Command must be executed from the web root + * directory of the server where server.json lives. Call with no parameters to view the entire server.json + * . + * Outputs port + * {code:bash} + * server show port + * {code} + * . + * Nested attributes may be accessed by specifying dot-delimited names or using array notation. + * If the accessed property is a complex value, the JSON representation will be displayed + * . + * {code:bash} + * server show key1.key2 + * {code} + * . + * {code:bash} + * server show aliases[2] + * {code} + * + **/ +component { + + property name="ServerService" inject="ServerService"; + property name="JSONService" inject="JSONService"; + + /** + * @property.hint The name of the property to show. Can nested to get "deep" properties + * @property.optionsUDF completeProperty + **/ + function run( string property='' ) { + var directory = getCWD(); + + // Read without defaulted values + var serverJSON = ServerService.readServerJSON( directory ); + + try { + + var propertyValue = JSONService.show( serverJSON, arguments.property ); + + if( isSimpleValue( propertyValue ) ) { + print.line( propertyValue ); + } else { + print.line( formatterUtil.formatJson( propertyValue ) ); + } + + } catch( JSONException var e ) { + error( e.message ); + } catch( any var e ) { + rethrow; + } + + } + + // Dynamic completion for property name based on contents of box.json + function completeProperty() { + return ServerService.completeProperty( getCWD() ); + } +} \ No newline at end of file diff --git a/src/cfml/system/modules/server-commands/commands/server/start.cfc b/src/cfml/system/modules/server-commands/commands/server/start.cfc new file mode 100644 index 000000000..9249f11ac --- /dev/null +++ b/src/cfml/system/modules/server-commands/commands/server/start.cfc @@ -0,0 +1,95 @@ +/** + * Start an embedded CFML server. Run command from the web root of the server. + * Please also remember to look at the plethora of arguments this command has as you can start your server with SSL, rewrites and much more. + * . + * {code:bash} + * server start + * {code} + * . + * Start with rewrites enabled + * {code:bash} + * server start --rewritesEnable + * {code} + * . + * Start with specifc heap size + * {code:bash} + * server start heapSize=768 + * {code} + **/ +component aliases="start" { + + // DI + property name="serverService" inject="ServerService"; + + /** + * @name short name for this server` + * @name.optionsUDF serverNameComplete + * @port port number + * @host bind to a host/ip + * @openbrowser open a browser after starting + * @directory web root for this server + * @stopPort stop socket listener port number + * @force force start if status is not stopped + * @debug sets debug log level + * @webConfigDir custom location for web context configuration + * @serverConfigDir custom location for server configuration + * @libDirs comma-separated list of extra lib directories for the server + * @trayIcon path to .png file for tray icon + * @webXML path to web.xml file used to configure the server + * @HTTPEnable enable HTTP + * @SSLEnable enable SSL + * @SSLPort SSL port number + * @SSLCert SSL certificate + * @SSLKey SSL key (required if SSLCert specified) + * @SSLKeyPass SSL key passphrase (required if SSLCert specified) + * @rewritesEnable enable URL rewriting (default false) + * @rewritesConfig optional URL rewriting config file path + * @heapSize The max heap size in megabytes you would like this server to start with, it defaults to 512mb + * @directoryBrowsing Enable/Disabled directory browsing, defaults to true + * @JVMArgs Additional JVM args to use when starting the server. Use "server status --verbose" to debug + * @runwarArgs Additional Runwar options to use when starting the server. Use "server status --verbose" to debug + * @saveSettings Save start settings in server.json + **/ + function run( + String name, + Numeric port, + String host, + Boolean openbrowser, + String directory = "", + Numeric stopPort, + Boolean force, + Boolean debug, + String webConfigDir, + String serverConfigDir, + String libDirs, + String trayIcon, + String webXML, + Boolean HTTPEnable, + Boolean SSLEnable, + Numeric SSLPort, + String SSLCert, + String SSLKey, + String SSLKeyPass, + Boolean rewritesEnable, + String rewritesConfig, + Numeric heapSize, + boolean directoryBrowsing, + String JVMArgs, + String runwarArgs, + boolean saveSettings=true + ){ + // Resolve path as used locally + arguments.directory = fileSystemUtil.resolvePath( arguments.directory ); + + // startup the server + return serverService.start( serverProps = arguments ); + } + + /** + * Complete server names + */ + function serverNameComplete() { + return serverService.getServerNames(); + } + +} \ No newline at end of file diff --git a/src/cfml/commands/server/status.cfc b/src/cfml/system/modules/server-commands/commands/server/status.cfc similarity index 97% rename from src/cfml/commands/server/status.cfc rename to src/cfml/system/modules/server-commands/commands/server/status.cfc index f82595a54..1c7db7209 100644 --- a/src/cfml/commands/server/status.cfc +++ b/src/cfml/system/modules/server-commands/commands/server/status.cfc @@ -30,7 +30,7 @@ * {code} * . **/ -component extends='commandbox.system.BaseCommand' aliases='status' excludeFromHelp=false { +component aliases='status' { // DI property name='serverService' inject='ServerService'; diff --git a/src/cfml/commands/server/stop.cfc b/src/cfml/system/modules/server-commands/commands/server/stop.cfc similarity index 95% rename from src/cfml/commands/server/stop.cfc rename to src/cfml/system/modules/server-commands/commands/server/stop.cfc index a49550aba..adce8996e 100644 --- a/src/cfml/commands/server/stop.cfc +++ b/src/cfml/system/modules/server-commands/commands/server/stop.cfc @@ -8,7 +8,7 @@ * server stop --all * {code} **/ -component extends="commandbox.system.BaseCommand" aliases="stop" excludeFromHelp=false { +component aliases="stop" { // DI property name="serverService" inject="ServerService"; diff --git a/src/cfml/system/modules/system-commands/ModuleConfig.cfc b/src/cfml/system/modules/system-commands/ModuleConfig.cfc new file mode 100644 index 000000000..a400988b5 --- /dev/null +++ b/src/cfml/system/modules/system-commands/ModuleConfig.cfc @@ -0,0 +1,11 @@ +/** +********************************************************************************* +* Copyright Since 2014 CommandBox by Ortus Solutions, Corp +* www.coldbox.org | www.ortussolutions.com +******************************************************************************** +* @author Brad Wood, Luis Majano +*/ +component { + function configure() { + } +} \ No newline at end of file diff --git a/src/cfml/system/commands/browse.cfc b/src/cfml/system/modules/system-commands/commands/browse.cfc similarity index 83% rename from src/cfml/system/commands/browse.cfc rename to src/cfml/system/modules/system-commands/commands/browse.cfc index 80ca742c0..5182b5d08 100644 --- a/src/cfml/system/commands/browse.cfc +++ b/src/cfml/system/modules/system-commands/commands/browse.cfc @@ -7,7 +7,7 @@ * {code} * **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * @URI.hint The URI to open as you would type it into your browser's address bar diff --git a/src/cfml/system/commands/cat.cfc b/src/cfml/system/modules/system-commands/commands/cat.cfc similarity index 93% rename from src/cfml/system/commands/cat.cfc rename to src/cfml/system/modules/system-commands/commands/cat.cfc index 9c7a5e1f7..248e362dc 100644 --- a/src/cfml/system/commands/cat.cfc +++ b/src/cfml/system/modules/system-commands/commands/cat.cfc @@ -18,7 +18,7 @@ * {code} * **/ -component extends="commandbox.system.BaseCommand" aliases="type" excludeFromHelp=false { +component aliases="type" { /** * You can have as many args as you want, but I'm including 4 just so diff --git a/src/cfml/system/commands/cd.cfc b/src/cfml/system/modules/system-commands/commands/cd.cfc similarity index 88% rename from src/cfml/system/commands/cd.cfc rename to src/cfml/system/modules/system-commands/commands/cd.cfc index 0f8f3d6fb..019f903f8 100644 --- a/src/cfml/system/commands/cd.cfc +++ b/src/cfml/system/modules/system-commands/commands/cd.cfc @@ -11,7 +11,7 @@ * cd ../../tests * {code} **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * @directory.hint The directory to change to diff --git a/src/cfml/system/modules/system-commands/commands/cfml.cfc b/src/cfml/system/modules/system-commands/commands/cfml.cfc new file mode 100644 index 000000000..abb47f7f7 --- /dev/null +++ b/src/cfml/system/modules/system-commands/commands/cfml.cfc @@ -0,0 +1,144 @@ +/** + * I am a shortcut to run single CFML functions via the REPL. This example runs the now() function. + * It is the equivalent to "repl now()". + * . + * {code:bash} + * cfml now + * {code} + * + * As a handy shortcut, you can invoke the "cfml" command by simply typing the name of the CFML + * function, preceded by a # sign. + * + * {code:bash} + * #now + * {code} + * + * When you pass parameters into this command, they will be passed directly along to the CFML function. + * + * {code:bash} + * #hash mypass + * #reverse abc + * {code} + * + * This really gets useful when you start piping input into CFML functions. Like other CFML commands, piped + * input will get passed as the first parameter to the function. This allows you to chain CFML functions + * from the command line like so. (Outputs "OOF") + * + * {code:bash} + * #listGetAt www.foo.com 2 . | #ucase | #reverse + * {code} + * + * Since this command defers to the REPL for execution, complex return values such as arrays or structs will be + * serialized as JSON on output. As a convenience, if the first input to an array or struct function looks like + * JSON, it will be passed directly as a literal instead of a string. + * . + * The first example averages an array. The second outputs an array of dependency names in your app by manipulating + * the JSON object that comes back from the "package list" command. + * + * {code:bash} + * #arrayAvg [1,2,3] + * package list --JSON | #structFind dependencies | #structKeyArray + * {code} + * + * You must use positional parameters if you are piping data to a CFML function, but you do have the option to use + * named parameters otherwise. Those names will be passed along directly to the CFML function, so use the CF docs to make sure + * you're using the correct parameter name. + * + * {code:bash} + * #directoryList path=D:\\ listInfo=name + * {code} + * + **/ +component{ + + /** + * @name.hint The name of the CFML function to run + **/ + function run( + required string name + boolean debug + ){ + + var functionText = arguments.name & '( '; + + // Additional param go into the function + if( arrayLen( arguments ) > 1 ) { + + // Positional params + if( isNumeric( listGetAt( structKeyList( arguments ), 2 ) ) ) { + + var i = 1; + while( ++i <= arrayLen( arguments ) ) { + + functionText &= ( i>2 ? ', ' : '' ); + + // If this is a struct or array function, we have at least one param, and it's JSON, just pass it in as complex data. + if( ( left( arguments.name, 5 ) == 'array' || left( arguments.name, 6 ) == 'struct' ) + && i==2 && isJSON( arguments[ i ] ) ) { + functionText &= '#convertJSONEscapesToCFML( arguments[ i ] )#'; + } else { + functionText &= '"#escapeArg( arguments[ i ] )#"'; + } + + } // end param loop + + + // Named params + } else { + + var i = 0; + for( var param in arguments ) { + if( param=='name' ) { + continue; + } + i++; + + functionText &= ( i>1 ? ', ' : '' ); + + functionText &= '#param#="#escapeArg( arguments[ param ] )#"'; + + } // end param loop + + + } + + + } // end additional params? + + functionText &= ' )'; + + // Run our function via the REPL + var result = command( "repl" ) + .params( functionText ) + .run( returnOutput=true, echo=false ); + + // Print out the results + print.text( result ); + + // Try to do some "smart" debugging if the response was an error + // Todo, need to have a more explicit 'error' code that comes back + if( result contains 'error' ) { + print.yellowline( "Here is the last CFML function that was run" ) + .line() + .line( functionText ) + .line(); + } + } + + private function escapeArg( required string arg ) { + arguments.arg = replaceNoCase( arguments.arg, '"', '""', 'all' ); + arguments.arg = replaceNoCase( arguments.arg, '##', '####', 'all' ); + return arguments.arg; + } + + // A complex value serialized as JSON differs from CFML struct literals in that + // double quotes are \" instead of "". Any escaped double quotes must be converted + // to the CFML version to work as an object literal. + private function convertJSONEscapesToCFML( required string arg ) { + arguments.arg = replaceNoCase( arguments.arg, '\\', '__DOUBLE_ESCAPE__', 'all' ); + arguments.arg = replaceNoCase( arguments.arg, '\"', '""', 'all' ); + arguments.arg = replaceNoCase( arguments.arg, '__DOUBLE_ESCAPE__', '\\', 'all' ); + return arguments.arg; + } + +} \ No newline at end of file diff --git a/src/cfml/system/commands/clear.cfc b/src/cfml/system/modules/system-commands/commands/clear.cfc similarity index 60% rename from src/cfml/system/commands/clear.cfc rename to src/cfml/system/modules/system-commands/commands/clear.cfc index 6731260a0..f7e7c350a 100644 --- a/src/cfml/system/commands/clear.cfc +++ b/src/cfml/system/modules/system-commands/commands/clear.cfc @@ -6,7 +6,7 @@ * {code} * **/ -component extends="commandbox.system.BaseCommand" aliases="cls" excludeFromHelp=false { +component aliases="cls" { function run() { shell.clearScreen(); diff --git a/src/cfml/system/modules/system-commands/commands/config/clear.cfc b/src/cfml/system/modules/system-commands/commands/config/clear.cfc new file mode 100644 index 000000000..ca3b59051 --- /dev/null +++ b/src/cfml/system/modules/system-commands/commands/config/clear.cfc @@ -0,0 +1,43 @@ +/** + * Remove a setting out of the commandbox.json. + * Nested attributes may be set by specifying dot-delimited names or using array notation. + * . + * {code:bash} + * config clear description + * {code} + * + **/ +component { + + property name="ConfigService" inject="ConfigService"; + property name="JSONService" inject="JSONService"; + + /** + * @property.hint Name of the property to clear + * @property.optionsUDF completeProperty + **/ + function run( required string property ) { + + var configSettings = ConfigService.getconfigSettings(); + + try { + JSONService.clear( configSettings, arguments.property ); + } catch( JSONException var e ) { + error( e.message ); + } catch( any var e ) { + rethrow; + } + + print.greenLine( 'Removed #arguments.property#' ); + + // Write the file back out. + ConfigService.setConfigSettings( configSettings ); + + } + + // Dynamic completion for property name based on contents of box.json + function completeProperty() { + return ConfigService.completeProperty(); + } + +} \ No newline at end of file diff --git a/src/cfml/system/modules/system-commands/commands/config/set.cfc b/src/cfml/system/modules/system-commands/commands/config/set.cfc new file mode 100644 index 000000000..701a105e7 --- /dev/null +++ b/src/cfml/system/modules/system-commands/commands/config/set.cfc @@ -0,0 +1,77 @@ +/** + * Set config settings in commandbox.json. + * . + * {code:bash} + * config set name=mySetting + * {code} + * . + * Nested attributes may be set by specifying dot-delimited names or using array notation. + * If the set value is JSON, it will be stored as a complex value in the commandbox.json. + * . + * Set module setting + * {code:bash} + * config set modules.myModule.mySetting=foo + * {code} + * . + * Set item in an array + * {code:bash} + * config set myArraySetting[1]="value" + * {code} + * . + * Set multiple params at once + * {code:bash} + * config set setting1=value1 setting2=value2 setting3=value3 + * {code} + * . + * Override a complex value as JSON + * {code:bash} + * config set myArraySeting="[ 'test@test.com', 'me@example.com' ]" + * {code} + * . + * Structs and arrays can be appended to using the "append" parameter. + * . + * Add an additional settings to the existing list + * This only works if the property and incoming value are both of the same complex type. + * {code:bash} + * config set myArraySetting="[ 'another value' ]" --append + * {code} + * + **/ +component { + + property name="ConfigService" inject="ConfigService"; + property name="JSONService" inject="JSONService"; + + /** + * This param is a dummy param just to get the custom completor to work. + * The actual parameter names will be whatever property name the user wants to set + * @_.hint Pass any number of property names in followed by the value to set + * @_.optionsUDF completeProperty + * @append.hint If setting an array or struct, set to true to append instead of overwriting. + **/ + function run( _, boolean append=false ) { + var thisAppend = arguments.append; + + // Remove dummy args + structDelete( arguments, '_' ); + structDelete( arguments, 'append' ); + + var configSettings = ConfigService.getconfigSettings(); + + var results = JSONService.set( configSettings, arguments, thisAppend ); + + // Write the file back out. + ConfigService.setConfigSettings( configSettings ); + + for( var message in results ) { + print.greeLine( message ); + } + + } + + // Dynamic completion for property name based on contents of box.json + function completeProperty() { + // all=true will cause "config set" to prompt all possible commandbox.json settings + return ConfigService.completeProperty( true ); + } +} \ No newline at end of file diff --git a/src/cfml/system/modules/system-commands/commands/config/show.cfc b/src/cfml/system/modules/system-commands/commands/config/show.cfc new file mode 100644 index 000000000..74f7cc7d5 --- /dev/null +++ b/src/cfml/system/modules/system-commands/commands/config/show.cfc @@ -0,0 +1,56 @@ +/** + * View configuration proprties in CommandBox. Call with no parameters to view all config properties. + * . + * Output setting + * {code:bash} + * config show settingName + * {code} + * . + * Nested attributes may be accessed by specifying dot-delimited names or using array notation. + * If the accessed property is a complex value, the JSON representation will be displayed + * . + * {code:bash} + * config show modules.myModule.settingName + * {code} + * . + * {code:bash} + * config show mySettingArray[1] + * {code} + * . + **/ +component { + + property name="ConfigService" inject="ConfigService"; + property name="JSONService" inject="JSONService"; + + /** + * @property.hint The name of the property to show. Can nested to get "deep" properties + * @property.optionsUDF completeProperty + **/ + function run( string property='' ) { + + var configSettings = ConfigService.getconfigSettings(); + + try { + + var propertyValue = JSONService.show( configSettings, arguments.property ); + + if( isSimpleValue( propertyValue ) ) { + print.line( propertyValue ); + } else { + print.line( formatterUtil.formatJson( propertyValue ) ); + } + + } catch( JSONException var e ) { + error( e.message ); + } catch( any var e ) { + rethrow; + } + + } + + // Dynamic completion for property name based on contents of commandbox.json + function completeProperty() { + return ConfigService.completeProperty(); + } +} \ No newline at end of file diff --git a/src/cfml/system/commands/cp.cfc b/src/cfml/system/modules/system-commands/commands/cp.cfc similarity index 94% rename from src/cfml/system/commands/cp.cfc rename to src/cfml/system/modules/system-commands/commands/cp.cfc index 6defc51af..f03bb99be 100644 --- a/src/cfml/system/commands/cp.cfc +++ b/src/cfml/system/modules/system-commands/commands/cp.cfc @@ -17,7 +17,7 @@ * {code} * **/ -component extends="commandbox.system.BaseCommand" aliases="copy" excludeFromHelp=false { +component aliases="copy" { /** * @path.hint The file or directory source diff --git a/src/cfml/system/commands/delete.cfc b/src/cfml/system/modules/system-commands/commands/delete.cfc similarity index 96% rename from src/cfml/system/commands/delete.cfc rename to src/cfml/system/modules/system-commands/commands/delete.cfc index afc091127..400269377 100644 --- a/src/cfml/system/commands/delete.cfc +++ b/src/cfml/system/modules/system-commands/commands/delete.cfc @@ -18,7 +18,7 @@ * delete myFolder/ --recurse * {code} **/ -component extends="commandbox.system.BaseCommand" aliases="rm,del" excludeFromHelp=false { +component aliases="rm,del" { /** * @path.hint file or directory to delete diff --git a/src/cfml/system/commands/dir.cfc b/src/cfml/system/modules/system-commands/commands/dir.cfc similarity index 94% rename from src/cfml/system/commands/dir.cfc rename to src/cfml/system/modules/system-commands/commands/dir.cfc index ee96a2478..223abe852 100644 --- a/src/cfml/system/commands/dir.cfc +++ b/src/cfml/system/modules/system-commands/commands/dir.cfc @@ -12,7 +12,7 @@ * {code} * **/ -component extends="commandbox.system.BaseCommand" aliases="ls,ll,directory" excludeFromHelp=false { +component aliases="ls,ll,directory" { /** * @directory.hint The directory to list the contents of diff --git a/src/cfml/system/commands/echo.cfc b/src/cfml/system/modules/system-commands/commands/echo.cfc similarity index 81% rename from src/cfml/system/commands/echo.cfc rename to src/cfml/system/modules/system-commands/commands/echo.cfc index 1a9882a56..7cad653aa 100644 --- a/src/cfml/system/commands/echo.cfc +++ b/src/cfml/system/modules/system-commands/commands/echo.cfc @@ -12,7 +12,7 @@ * {code} * **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * @text.hint The text to output diff --git a/src/cfml/system/commands/edit.cfc b/src/cfml/system/modules/system-commands/commands/edit.cfc similarity index 90% rename from src/cfml/system/commands/edit.cfc rename to src/cfml/system/modules/system-commands/commands/edit.cfc index b321bc62f..165f119b9 100644 --- a/src/cfml/system/commands/edit.cfc +++ b/src/cfml/system/modules/system-commands/commands/edit.cfc @@ -9,7 +9,7 @@ * {code} * **/ -component extends="commandbox.system.BaseCommand" aliases="open" excludeFromHelp=false { +component aliases="open" { /** * @path.hint Path to open natively. diff --git a/src/cfml/system/commands/execute.cfc b/src/cfml/system/modules/system-commands/commands/execute.cfc similarity index 95% rename from src/cfml/system/commands/execute.cfc rename to src/cfml/system/modules/system-commands/commands/execute.cfc index 72f0a1bd8..5b2d6d0e4 100644 --- a/src/cfml/system/commands/execute.cfc +++ b/src/cfml/system/modules/system-commands/commands/execute.cfc @@ -23,7 +23,7 @@ * {code} **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false{ +component aliases="exec"{ /** * @file.hint The file to execute diff --git a/src/cfml/system/commands/fileAppend.cfc b/src/cfml/system/modules/system-commands/commands/fileAppend.cfc similarity index 92% rename from src/cfml/system/commands/fileAppend.cfc rename to src/cfml/system/modules/system-commands/commands/fileAppend.cfc index 8bcf22326..f9f089544 100644 --- a/src/cfml/system/commands/fileAppend.cfc +++ b/src/cfml/system/modules/system-commands/commands/fileAppend.cfc @@ -18,7 +18,7 @@ * {code} * **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=true { +component excludeFromHelp=true { /** * @contents.hint Contents to append to the file diff --git a/src/cfml/system/commands/fileWrite.cfc b/src/cfml/system/modules/system-commands/commands/fileWrite.cfc similarity index 91% rename from src/cfml/system/commands/fileWrite.cfc rename to src/cfml/system/modules/system-commands/commands/fileWrite.cfc index cdef8dc87..e99bdd0ea 100644 --- a/src/cfml/system/commands/fileWrite.cfc +++ b/src/cfml/system/modules/system-commands/commands/fileWrite.cfc @@ -18,7 +18,7 @@ * {code} * **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=true { +component excludeFromHelp=true { /** * @contents.hint Contents to write to the file diff --git a/src/cfml/system/commands/grep.cfc b/src/cfml/system/modules/system-commands/commands/grep.cfc similarity index 92% rename from src/cfml/system/commands/grep.cfc rename to src/cfml/system/modules/system-commands/commands/grep.cfc index 447c6bd9d..349248573 100644 --- a/src/cfml/system/commands/grep.cfc +++ b/src/cfml/system/modules/system-commands/commands/grep.cfc @@ -17,7 +17,7 @@ * {code} * **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=true { +component excludeFromHelp=true { /** * @input.hint The piped input to be checked. diff --git a/src/cfml/system/commands/help.cfc b/src/cfml/system/modules/system-commands/commands/help.cfc similarity index 98% rename from src/cfml/system/commands/help.cfc rename to src/cfml/system/modules/system-commands/commands/help.cfc index 68a3a5c53..052649f46 100644 --- a/src/cfml/system/commands/help.cfc +++ b/src/cfml/system/modules/system-commands/commands/help.cfc @@ -20,7 +20,7 @@ * testbox run help * {code} **/ -component extends="commandbox.system.BaseCommand" aliases="h,/?,?,--help,-help" excludeFromHelp=false { +component aliases="h,/?,?,--help,-help" { property name="commandService" inject="CommandService"; diff --git a/src/cfml/system/commands/history.cfc b/src/cfml/system/modules/system-commands/commands/history.cfc similarity index 95% rename from src/cfml/system/commands/history.cfc rename to src/cfml/system/modules/system-commands/commands/history.cfc index eafde6c85..cd67da477 100644 --- a/src/cfml/system/commands/history.cfc +++ b/src/cfml/system/modules/system-commands/commands/history.cfc @@ -27,7 +27,7 @@ * {code} * **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { property name="commandHistoryFile" inject="commandHistoryFile@java"; property name="REPLScriptHistoryFile" inject="REPLScriptHistoryFile@java"; diff --git a/src/cfml/system/commands/info.cfc b/src/cfml/system/modules/system-commands/commands/info.cfc similarity index 98% rename from src/cfml/system/commands/info.cfc rename to src/cfml/system/modules/system-commands/commands/info.cfc index 22c8f4ff7..60e945cbd 100644 --- a/src/cfml/system/commands/info.cfc +++ b/src/cfml/system/modules/system-commands/commands/info.cfc @@ -6,7 +6,7 @@ * {code} * **/ -component extends="commandbox.system.BaseCommand" aliases="about" excludeFromHelp=false { +component aliases="about" { function run() { diff --git a/src/cfml/system/commands/mkdir.cfc b/src/cfml/system/modules/system-commands/commands/mkdir.cfc similarity index 59% rename from src/cfml/system/commands/mkdir.cfc rename to src/cfml/system/modules/system-commands/commands/mkdir.cfc index ac270c940..7676a8dd5 100644 --- a/src/cfml/system/commands/mkdir.cfc +++ b/src/cfml/system/modules/system-commands/commands/mkdir.cfc @@ -4,13 +4,21 @@ * {code:bash} * mkdir newDir * {code} + * + * You can also change your current working directory to the new path with the cd flag. + * . + * {code:bash} + * mkdir newDir --cd + * {code} + * **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * @directory.hint The directory to create + * @cd.hint CD into the directory after creating **/ - function run( required String directory ) { + function run( required String directory, boolean cd=false ) { // Validate directory if( !len( arguments.directory ) ) { @@ -24,6 +32,14 @@ component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=fal directorycreate( arguments.directory, true, true ); print.greenLine( 'Created #arguments.directory#' ); + + // Optionally change into the new dir + if( arguments.cd ) { + command( 'cd' ) + .params( arguments.directory ) + .run(); + } + } diff --git a/src/cfml/system/commands/more.cfc b/src/cfml/system/modules/system-commands/commands/more.cfc similarity index 93% rename from src/cfml/system/commands/more.cfc rename to src/cfml/system/modules/system-commands/commands/more.cfc index e9b6f0b52..1d4af9343 100644 --- a/src/cfml/system/commands/more.cfc +++ b/src/cfml/system/modules/system-commands/commands/more.cfc @@ -6,7 +6,7 @@ * forgebox show | more * {code} **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=true { +component excludeFromHelp=true { /** * @input.hint The piped input to be displayed. diff --git a/src/cfml/system/commands/mv.cfc b/src/cfml/system/modules/system-commands/commands/mv.cfc similarity index 93% rename from src/cfml/system/commands/mv.cfc rename to src/cfml/system/modules/system-commands/commands/mv.cfc index 1567edc60..9c3fdf03c 100644 --- a/src/cfml/system/commands/mv.cfc +++ b/src/cfml/system/modules/system-commands/commands/mv.cfc @@ -22,7 +22,7 @@ * {code} * **/ -component extends="commandbox.system.BaseCommand" aliases="rename" excludeFromHelp=false { +component aliases="rename" { /** * @path.hint The file or directory source to rename diff --git a/src/cfml/system/commands/pause.cfc b/src/cfml/system/modules/system-commands/commands/pause.cfc similarity index 83% rename from src/cfml/system/commands/pause.cfc rename to src/cfml/system/modules/system-commands/commands/pause.cfc index 929e3c205..059a7c728 100644 --- a/src/cfml/system/commands/pause.cfc +++ b/src/cfml/system/modules/system-commands/commands/pause.cfc @@ -7,7 +7,7 @@ * pause * {code} **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=true { +component excludeFromHelp=true { function run() { diff --git a/src/cfml/system/commands/prompt.cfc b/src/cfml/system/modules/system-commands/commands/prompt.cfc similarity index 84% rename from src/cfml/system/commands/prompt.cfc rename to src/cfml/system/modules/system-commands/commands/prompt.cfc index 00ca612da..c26ea24bb 100644 --- a/src/cfml/system/commands/prompt.cfc +++ b/src/cfml/system/modules/system-commands/commands/prompt.cfc @@ -7,7 +7,7 @@ * prompt "My Cool Shell> " * {code} **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * @prompt.hist The new text to use as the shell prompt diff --git a/src/cfml/system/commands/pwd.cfc b/src/cfml/system/modules/system-commands/commands/pwd.cfc similarity index 69% rename from src/cfml/system/commands/pwd.cfc rename to src/cfml/system/modules/system-commands/commands/pwd.cfc index 9f1e906a3..ada56f07d 100644 --- a/src/cfml/system/commands/pwd.cfc +++ b/src/cfml/system/modules/system-commands/commands/pwd.cfc @@ -6,7 +6,7 @@ * {code} * **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { function run() { return getCWD(); diff --git a/src/cfml/system/commands/quit.cfc b/src/cfml/system/modules/system-commands/commands/quit.cfc similarity index 85% rename from src/cfml/system/commands/quit.cfc rename to src/cfml/system/modules/system-commands/commands/quit.cfc index a1603e03c..d47f77901 100644 --- a/src/cfml/system/commands/quit.cfc +++ b/src/cfml/system/modules/system-commands/commands/quit.cfc @@ -11,7 +11,7 @@ * at a later time and "cd" to the root folder of the server. * **/ -component extends="commandbox.system.BaseCommand" aliases="exit,q,e" excludeFromHelp=false { +component aliases="exit,q,e" { function run() { shell.exit(); diff --git a/src/cfml/system/commands/recipe.cfc b/src/cfml/system/modules/system-commands/commands/recipe.cfc similarity index 98% rename from src/cfml/system/commands/recipe.cfc rename to src/cfml/system/modules/system-commands/commands/recipe.cfc index 15c3d1f60..d990b81c4 100644 --- a/src/cfml/system/commands/recipe.cfc +++ b/src/cfml/system/modules/system-commands/commands/recipe.cfc @@ -44,7 +44,7 @@ * {code} * **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { // DI Properties property name='parser' inject='Parser'; diff --git a/src/cfml/system/commands/reload.cfc b/src/cfml/system/modules/system-commands/commands/reload.cfc similarity index 86% rename from src/cfml/system/commands/reload.cfc rename to src/cfml/system/modules/system-commands/commands/reload.cfc index 506c5f9cc..126b7fdf5 100644 --- a/src/cfml/system/commands/reload.cfc +++ b/src/cfml/system/modules/system-commands/commands/reload.cfc @@ -7,7 +7,7 @@ * reload * {code} **/ -component extends="commandbox.system.BaseCommand" aliases="r" excludeFromHelp=true { +component aliases="r" excludeFromHelp=true { /** * @clearScreen.hint Clears the screen after reload diff --git a/src/cfml/system/commands/repl.cfc b/src/cfml/system/modules/system-commands/commands/repl.cfc similarity index 88% rename from src/cfml/system/commands/repl.cfc rename to src/cfml/system/modules/system-commands/commands/repl.cfc index 2f26d5ab3..aabe863e5 100644 --- a/src/cfml/system/commands/repl.cfc +++ b/src/cfml/system/modules/system-commands/commands/repl.cfc @@ -17,7 +17,7 @@ * lines in the history. The REPLs histories can be managed by the "history" command. * **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { // repl history file property name="commandHistoryFile" inject="commandHistoryFile@java"; @@ -27,15 +27,6 @@ component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=fal // repl parser property name="REPLParser" inject="REPLParser"; - /** - * Constructor - */ - function init(){ - super.init(); - - return this; - } - /** * @input.hint Optional CFML to execute. If provided, the command exits immediatley. * @script.hint Run REPL in script or tag mode @@ -118,14 +109,27 @@ component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=fal if( !isNull( results ) ){ // Make sure results is a string results = REPLParser.serializeOutput( results ); - print.boldRedLine( results ).toConsole(); + print.line( results, structKeyExists( arguments, 'input' ) ? '' : 'boldRed' ) } } catch( any e ){ + // flush out anything in buffer + print.toConsole(); // Log it logger.error( '#e.message# #e.detail#' , e.stackTrace ); - error( '#e.message##CR##e.detail#' ); - print.toConsole(); + if( quit ) { + // flush history out + newHistory.flush(); + // set back original history + shell.getReader().setHistory( commandHistoryFile ); + // This will exist the command + error( '#e.message##CR##e.detail#' ); + } else { + print.whiteOnRedLine( 'ERROR' ) + .line() + .boldRedLine( '#e.message##CR##e.detail#' ) + .line(); + } } } } diff --git a/src/cfml/system/modules/system-commands/commands/run.cfc b/src/cfml/system/modules/system-commands/commands/run.cfc new file mode 100644 index 000000000..00c1d1c0c --- /dev/null +++ b/src/cfml/system/modules/system-commands/commands/run.cfc @@ -0,0 +1,106 @@ +/** + * Execute an operating system level command in the native shell. The binary must be in the PATH, or you can specify the full + * path to it. This command will wait for the OS exectuable to complete. This cannot be used for any commands that require + * interactivity or don't exit automatically or the call will hang indefinitely. + * . + * {code:bash} + * run myApp.exe + * run /path/to/myApp + * {code} + * . + * A shortcut for running OS binaries is to prefix the binary with "!". In this mode, any other params need to be positional. + * There is no CommandBox parsing applied to the command's arguments. They are passed straight to the native shell. + * . + * {code:bash} + * !myApp.exe + * !/path/to/myApp + * !dir + * !npm ll + * !ipconfig + * !ping google.com -c 4 + * {code} + * . + * Executing Java would look like this + * . + * {code:bash} + * !java -version + * !java -jar myLib.jar + * {code} + * . + * You can even call other CLIs + * . + * {code:bash} + * !git init + * touch index.cfm + * !git add . + * !git commit -m "Initial Commit" + * {code} + * + **/ +component{ + + property name="configService" inject="configService"; + + /** + * @command.hint The full operating system command to execute including the binary and any parameters + **/ + function run( + required command + ){ + + var executeResult = ""; + var executeError = ""; + + // Prep the command to run in the OS-specific shell + if( fileSystemUtil.isWindows() ) { + // Pass through Windows' command shell, /a outputs ANSI formatting, /c runs as a command + arguments.command = [ 'cmd','/a','/c', arguments.command ]; + } else { + // Pass through bash in interactive mode to expand aliases like "ll". + // -c runs input as a command, && exists cleanly from the shell as long as the original command ran successfully + var nativeShell = configService.getSetting( 'nativeShell', '/bin/bash' ); + arguments.command = [ nativeShell,'-i','-c', arguments.command & ' && exit']; + } + + try{ + // grab the current working directory + var pwd = fileSystemUtil.resolvePath( '' ); + var CWD = createObject( 'java', 'java.io.File' ).init( pwd ); + + // execute the server command + var process = createObject( 'java', 'java.lang.Runtime' ) + .getRuntime() + .exec( '#arguments.command#', javaCast( "null", "" ), CWD ); + var commandResult = createObject( 'java', 'lucee.commons.cli.Command' ) + .execute( process ); + + // I don't like the idea of potentially removing significant whitespace, but commands like pwd + // come with an extra line break that is a pain if you want to pipe into another command + var executeResult = trim( commandResult.getOutput() ); + var executeError = trim( commandResult.getError() ); + + // Output Results + if( !isNull( executeResult ) && len( executeResult ) ) { + print.line( executeResult ); + } + // Output error + if( !isNull( executeError ) && len( executeError ) ) { + // Clean up standard error from Unix interactive shell workaround + if( !fileSystemUtil.isWindows() && right( executeError, 4 ) == 'exit' ) { + executeError = mid( executeError, 1, len( executeError )-4 ); + } + // Clean up annoying warnings abour job control in some shells. + if( !fileSystemUtil.isWindows() && findNoCase( 'bash: no job control in this shell', executeError ) ) { + executeError = replaceNoCase( executeError, 'bash: no job control in this shell', '' ); + executeError = trim( executeError ); + } + print.redLine( executeError ); + } + + } catch (any e) { + error( '#e.message##CR##e.detail#' ); + } + + } + +} diff --git a/src/cfml/system/commands/sed.cfc b/src/cfml/system/modules/system-commands/commands/sed.cfc similarity index 98% rename from src/cfml/system/commands/sed.cfc rename to src/cfml/system/modules/system-commands/commands/sed.cfc index b3a5651eb..0840333b2 100644 --- a/src/cfml/system/commands/sed.cfc +++ b/src/cfml/system/modules/system-commands/commands/sed.cfc @@ -32,7 +32,7 @@ * sed --file config.cfm s~/var/www/~/sites/wwwroot/~i > config.cfm * {code} **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { // DI Properties property name='parser' inject='Parser'; diff --git a/src/cfml/system/commands/tail.cfc b/src/cfml/system/modules/system-commands/commands/tail.cfc similarity index 95% rename from src/cfml/system/commands/tail.cfc rename to src/cfml/system/modules/system-commands/commands/tail.cfc index 2ea07998f..954a0967f 100644 --- a/src/cfml/system/commands/tail.cfc +++ b/src/cfml/system/modules/system-commands/commands/tail.cfc @@ -12,7 +12,7 @@ * tail file.txt 100 * {code} **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * @path.hint file or directory to tail diff --git a/src/cfml/system/commands/touch.cfc b/src/cfml/system/modules/system-commands/commands/touch.cfc similarity index 92% rename from src/cfml/system/commands/touch.cfc rename to src/cfml/system/modules/system-commands/commands/touch.cfc index 645416d4f..3ddef771c 100644 --- a/src/cfml/system/commands/touch.cfc +++ b/src/cfml/system/modules/system-commands/commands/touch.cfc @@ -12,7 +12,7 @@ * {code} * **/ -component extends="commandbox.system.BaseCommand" aliases="new" excludeFromHelp=false { +component aliases="new" { /** * @file.hint File to create diff --git a/src/cfml/system/commands/upgrade.cfc b/src/cfml/system/modules/system-commands/commands/upgrade.cfc similarity index 80% rename from src/cfml/system/commands/upgrade.cfc rename to src/cfml/system/modules/system-commands/commands/upgrade.cfc index 2ba57b1f4..dccdfd6e7 100644 --- a/src/cfml/system/commands/upgrade.cfc +++ b/src/cfml/system/modules/system-commands/commands/upgrade.cfc @@ -17,7 +17,7 @@ * upgrade --force * {code} **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { // DI property name="artifactDir" inject="artifactDir@constants"; @@ -27,7 +27,8 @@ component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=fal property name="progressableDownloader" inject="ProgressableDownloader"; property name="progressBar" inject="ProgressBar"; property name="semanticVersion" inject="semanticVersion"; - + property name="ConfigService" inject="ConfigService"; + /** * @latest.hint Will download bleeding edge if true, last stable version if false * @force.hint Force the update even if the version on the server is the same as locally @@ -43,8 +44,34 @@ component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=fal var boxRepoURL = '#thisArtifactsURL#ortussolutions/commandbox/box-repo.json'; var loaderRepoURL = '#thisArtifactsURL#ortussolutions/commandbox/box-loader.json'; - http url="#boxRepoURL#" file="#temp#/box-repo.json" throwOnError=false; - http url="#loaderRepoURL#" file="#temp#/box-loader.json" throwOnError=false; + http + url="#boxRepoURL#" + file="#temp#/box-repo.json" + throwOnError=false + proxyServer="#ConfigService.getSetting( 'proxy.server', '' )#" + proxyPort="#ConfigService.getSetting( 'proxy.port', 80 )#" + proxyUser="#ConfigService.getSetting( 'proxy.user', '' )#" + proxyPassword="#ConfigService.getSetting( 'proxy.password', '' )#" + result="local.boxRepoResult"; + + http + url="#loaderRepoURL#" + file="#temp#/box-loader.json" + throwOnError=false + proxyServer="#ConfigService.getSetting( 'proxy.server', '' )#" + proxyPort="#ConfigService.getSetting( 'proxy.port', 80 )#" + proxyUser="#ConfigService.getSetting( 'proxy.user', '' )#" + proxyPassword="#ConfigService.getSetting( 'proxy.password', '' )#" + result="local.loaderRepoResult"; + + // Do some error checking + if( !local.boxRepoResult.statusCode contains "200" || !fileExists( '#temp#/box-repo.json' ) || + !local.loaderRepoResult.statusCode contains "200" || !fileExists( '#temp#/box-loader.json' ) ) { + error( + "Sorry, we're having troubles accessing the interwebs now or the update site is down. Please try again later", + "Box Repo: [#local.boxRepoResult.statusCode#] Loader Repo: [#local.loaderRepoResult.statusCode#]" + ); + } var boxRepoJSON = fileRead( '#temp#/box-repo.json' ); var loaderRepoJSON = fileRead( '#temp#/box-loader.json' ); @@ -100,7 +127,7 @@ component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=fal } // Confirm installation - if( !confirm( "Do you wish to apply this update? [y/n]" ) ){ + if( !force && !confirm( "Do you wish to apply this update? [y/n]" ) ){ return; } diff --git a/src/cfml/system/commands/version.cfc b/src/cfml/system/modules/system-commands/commands/version.cfc similarity index 84% rename from src/cfml/system/commands/version.cfc rename to src/cfml/system/modules/system-commands/commands/version.cfc index dd3eb429a..020ef90e9 100644 --- a/src/cfml/system/commands/version.cfc +++ b/src/cfml/system/modules/system-commands/commands/version.cfc @@ -12,7 +12,7 @@ * {code} * . **/ -component extends="commandbox.system.BaseCommand" aliases="ver" excludeFromHelp=false { +component aliases="ver" { /** * @loader.hint Show the version of the CLI loader diff --git a/src/cfml/system/modules/task-commands/ModuleConfig.cfc b/src/cfml/system/modules/task-commands/ModuleConfig.cfc new file mode 100644 index 000000000..a400988b5 --- /dev/null +++ b/src/cfml/system/modules/task-commands/ModuleConfig.cfc @@ -0,0 +1,11 @@ +/** +********************************************************************************* +* Copyright Since 2014 CommandBox by Ortus Solutions, Corp +* www.coldbox.org | www.ortussolutions.com +******************************************************************************** +* @author Brad Wood, Luis Majano +*/ +component { + function configure() { + } +} \ No newline at end of file diff --git a/src/cfml/commands/task/create.cfc b/src/cfml/system/modules/task-commands/commands/task/create.cfc similarity index 77% rename from src/cfml/commands/task/create.cfc rename to src/cfml/system/modules/task-commands/commands/task/create.cfc index 5ec6e313f..04871df45 100644 --- a/src/cfml/commands/task/create.cfc +++ b/src/cfml/system/modules/task-commands/commands/task/create.cfc @@ -1,7 +1,7 @@ /** * Adds a task to be executed on the given interval **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * @name.hint The Task name diff --git a/src/cfml/commands/task/help.cfc b/src/cfml/system/modules/task-commands/commands/task/help.cfc similarity index 67% rename from src/cfml/commands/task/help.cfc rename to src/cfml/system/modules/task-commands/commands/task/help.cfc index 86b34d11d..ea26583e0 100644 --- a/src/cfml/commands/task/help.cfc +++ b/src/cfml/system/modules/task-commands/commands/task/help.cfc @@ -1,4 +1,4 @@ -component extends="commandbox.system.BaseCommand" excludeFromHelp=true { +component excludeFromHelp=true { function run() { diff --git a/src/cfml/commands/task/kill-all.cfc b/src/cfml/system/modules/task-commands/commands/task/kill-all.cfc similarity index 50% rename from src/cfml/commands/task/kill-all.cfc rename to src/cfml/system/modules/task-commands/commands/task/kill-all.cfc index 3d997d44d..9faeef65d 100644 --- a/src/cfml/commands/task/kill-all.cfc +++ b/src/cfml/system/modules/task-commands/commands/task/kill-all.cfc @@ -1,7 +1,7 @@ /** * Kills all running tasks **/ -component extends="commandbox.system.BaseCommand" aliases="kill" excludeFromHelp=false { +component aliases="kill" { function run( ) { print.line( "faux-kill!" ); diff --git a/src/cfml/system/modules/task-commands/commands/task/list.cfc b/src/cfml/system/modules/task-commands/commands/task/list.cfc new file mode 100644 index 000000000..d473629a6 --- /dev/null +++ b/src/cfml/system/modules/task-commands/commands/task/list.cfc @@ -0,0 +1,10 @@ +/** + * List all tasks + **/ +component { + + function run( ) { + print.line( "faux-list!" ); + } + +} \ No newline at end of file diff --git a/src/cfml/commands/task/remove.cfc b/src/cfml/system/modules/task-commands/commands/task/remove.cfc similarity index 64% rename from src/cfml/commands/task/remove.cfc rename to src/cfml/system/modules/task-commands/commands/task/remove.cfc index 09c2e75c2..ab86f74cf 100644 --- a/src/cfml/commands/task/remove.cfc +++ b/src/cfml/system/modules/task-commands/commands/task/remove.cfc @@ -1,7 +1,7 @@ /** * Remvoe a task **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * @name.hint The Task name diff --git a/src/cfml/system/modules/testbox-commands/ModuleConfig.cfc b/src/cfml/system/modules/testbox-commands/ModuleConfig.cfc new file mode 100644 index 000000000..a400988b5 --- /dev/null +++ b/src/cfml/system/modules/testbox-commands/ModuleConfig.cfc @@ -0,0 +1,11 @@ +/** +********************************************************************************* +* Copyright Since 2014 CommandBox by Ortus Solutions, Corp +* www.coldbox.org | www.ortussolutions.com +******************************************************************************** +* @author Brad Wood, Luis Majano +*/ +component { + function configure() { + } +} \ No newline at end of file diff --git a/src/cfml/commands/testbox/create/bdd.cfc b/src/cfml/system/modules/testbox-commands/commands/testbox/create/bdd.cfc similarity index 91% rename from src/cfml/commands/testbox/create/bdd.cfc rename to src/cfml/system/modules/testbox-commands/commands/testbox/create/bdd.cfc index cb785289d..3e432f296 100644 --- a/src/cfml/commands/testbox/create/bdd.cfc +++ b/src/cfml/system/modules/testbox-commands/commands/testbox/create/bdd.cfc @@ -7,7 +7,7 @@ * {code} * **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * @name.hint Name of the BDD spec to create without the .cfc. For packages, specify name as 'myPackage/myBDDSpec' @@ -40,7 +40,7 @@ component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=fal print.line(); // Read in Templates - var BDDContent = fileRead( '/commandbox/templates/testbox/bdd.txt' ); + var BDDContent = fileRead( '/testbox-commands/templates/testbox/bdd.txt' ); // Write out BDD Spec var BDDPath = '#directory#/#name#.cfc'; diff --git a/src/cfml/commands/testbox/create/help.cfc b/src/cfml/system/modules/testbox-commands/commands/testbox/create/help.cfc similarity index 87% rename from src/cfml/commands/testbox/create/help.cfc rename to src/cfml/system/modules/testbox-commands/commands/testbox/create/help.cfc index 512a381ad..c45cf6de3 100644 --- a/src/cfml/commands/testbox/create/help.cfc +++ b/src/cfml/system/modules/testbox-commands/commands/testbox/create/help.cfc @@ -1,4 +1,4 @@ -component extends="commandbox.system.BaseCommand" excludeFromHelp=true { +component excludeFromHelp=true { function run() { diff --git a/src/cfml/commands/testbox/create/unit.cfc b/src/cfml/system/modules/testbox-commands/commands/testbox/create/unit.cfc similarity index 91% rename from src/cfml/commands/testbox/create/unit.cfc rename to src/cfml/system/modules/testbox-commands/commands/testbox/create/unit.cfc index 11a7ca810..69dbe9786 100644 --- a/src/cfml/commands/testbox/create/unit.cfc +++ b/src/cfml/system/modules/testbox-commands/commands/testbox/create/unit.cfc @@ -7,7 +7,7 @@ * {code} * **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * @name.hint Name of the xUnit bundle to create without the .cfc. For packages, specify name as 'myPackage/MyTest' @@ -40,7 +40,7 @@ component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=fal print.line(); // Read in Templates - var content = fileRead( '/commandbox/templates/testbox/unit.txt' ); + var content = fileRead( '/testbox-commands/templates/testbox/unit.txt' ); // Write out BDD Spec var thisPath = '#directory#/#name#.cfc'; diff --git a/src/cfml/commands/testbox/generate/browser b/src/cfml/system/modules/testbox-commands/commands/testbox/generate/browser similarity index 100% rename from src/cfml/commands/testbox/generate/browser rename to src/cfml/system/modules/testbox-commands/commands/testbox/generate/browser diff --git a/src/cfml/commands/testbox/generate/harness.cfc b/src/cfml/system/modules/testbox-commands/commands/testbox/generate/harness.cfc similarity index 58% rename from src/cfml/commands/testbox/generate/harness.cfc rename to src/cfml/system/modules/testbox-commands/commands/testbox/generate/harness.cfc index 171ba060b..dce2a8c4e 100644 --- a/src/cfml/commands/testbox/generate/harness.cfc +++ b/src/cfml/system/modules/testbox-commands/commands/testbox/generate/harness.cfc @@ -1,7 +1,7 @@ /** * Description of command **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * diff --git a/src/cfml/commands/testbox/generate/help.cfc b/src/cfml/system/modules/testbox-commands/commands/testbox/generate/help.cfc similarity index 69% rename from src/cfml/commands/testbox/generate/help.cfc rename to src/cfml/system/modules/testbox-commands/commands/testbox/generate/help.cfc index 8fc954da8..967c96215 100644 --- a/src/cfml/commands/testbox/generate/help.cfc +++ b/src/cfml/system/modules/testbox-commands/commands/testbox/generate/help.cfc @@ -1,4 +1,4 @@ -component extends="commandbox.system.BaseCommand" excludeFromHelp=true { +component excludeFromHelp=true { function run() { diff --git a/src/cfml/commands/testbox/help.cfc b/src/cfml/system/modules/testbox-commands/commands/testbox/help.cfc similarity index 87% rename from src/cfml/commands/testbox/help.cfc rename to src/cfml/system/modules/testbox-commands/commands/testbox/help.cfc index a3f22f1a4..b342a3d55 100644 --- a/src/cfml/commands/testbox/help.cfc +++ b/src/cfml/system/modules/testbox-commands/commands/testbox/help.cfc @@ -1,4 +1,4 @@ -component extends="commandbox.system.BaseCommand" excludeFromHelp=true { +component excludeFromHelp=true { function run() { diff --git a/src/cfml/commands/testbox/open/bundle.cfc b/src/cfml/system/modules/testbox-commands/commands/testbox/open/bundle.cfc similarity index 58% rename from src/cfml/commands/testbox/open/bundle.cfc rename to src/cfml/system/modules/testbox-commands/commands/testbox/open/bundle.cfc index 171ba060b..dce2a8c4e 100644 --- a/src/cfml/commands/testbox/open/bundle.cfc +++ b/src/cfml/system/modules/testbox-commands/commands/testbox/open/bundle.cfc @@ -1,7 +1,7 @@ /** * Description of command **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * diff --git a/src/cfml/commands/testbox/open/directory.cfc b/src/cfml/system/modules/testbox-commands/commands/testbox/open/directory.cfc similarity index 58% rename from src/cfml/commands/testbox/open/directory.cfc rename to src/cfml/system/modules/testbox-commands/commands/testbox/open/directory.cfc index 171ba060b..dce2a8c4e 100644 --- a/src/cfml/commands/testbox/open/directory.cfc +++ b/src/cfml/system/modules/testbox-commands/commands/testbox/open/directory.cfc @@ -1,7 +1,7 @@ /** * Description of command **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * diff --git a/src/cfml/commands/testbox/open/help.cfc b/src/cfml/system/modules/testbox-commands/commands/testbox/open/help.cfc similarity index 68% rename from src/cfml/commands/testbox/open/help.cfc rename to src/cfml/system/modules/testbox-commands/commands/testbox/open/help.cfc index 069a52c8c..1e3a994dc 100644 --- a/src/cfml/commands/testbox/open/help.cfc +++ b/src/cfml/system/modules/testbox-commands/commands/testbox/open/help.cfc @@ -1,4 +1,4 @@ -component extends="commandbox.system.BaseCommand" excludeFromHelp=true { +component excludeFromHelp=true { function run() { diff --git a/src/cfml/commands/testbox/open/runner.cfc b/src/cfml/system/modules/testbox-commands/commands/testbox/open/runner.cfc similarity index 58% rename from src/cfml/commands/testbox/open/runner.cfc rename to src/cfml/system/modules/testbox-commands/commands/testbox/open/runner.cfc index 171ba060b..dce2a8c4e 100644 --- a/src/cfml/commands/testbox/open/runner.cfc +++ b/src/cfml/system/modules/testbox-commands/commands/testbox/open/runner.cfc @@ -1,7 +1,7 @@ /** * Description of command **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * diff --git a/src/cfml/commands/testbox/run.cfc b/src/cfml/system/modules/testbox-commands/commands/testbox/run.cfc similarity index 98% rename from src/cfml/commands/testbox/run.cfc rename to src/cfml/system/modules/testbox-commands/commands/testbox/run.cfc index a911bf551..722236e4b 100644 --- a/src/cfml/commands/testbox/run.cfc +++ b/src/cfml/system/modules/testbox-commands/commands/testbox/run.cfc @@ -11,7 +11,7 @@ * {code} * **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { // DI property name="packageService" inject="PackageService"; diff --git a/src/cfml/commands/testbox/watch.cfc b/src/cfml/system/modules/testbox-commands/commands/testbox/watch.cfc similarity index 58% rename from src/cfml/commands/testbox/watch.cfc rename to src/cfml/system/modules/testbox-commands/commands/testbox/watch.cfc index 171ba060b..dce2a8c4e 100644 --- a/src/cfml/commands/testbox/watch.cfc +++ b/src/cfml/system/modules/testbox-commands/commands/testbox/watch.cfc @@ -1,7 +1,7 @@ /** * Description of command **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * diff --git a/src/cfml/templates/testbox/bdd.txt b/src/cfml/system/modules/testbox-commands/templates/testbox/bdd.txt similarity index 100% rename from src/cfml/templates/testbox/bdd.txt rename to src/cfml/system/modules/testbox-commands/templates/testbox/bdd.txt diff --git a/src/cfml/templates/testbox/test-browser/Application.cfc b/src/cfml/system/modules/testbox-commands/templates/testbox/test-browser/Application.cfc similarity index 100% rename from src/cfml/templates/testbox/test-browser/Application.cfc rename to src/cfml/system/modules/testbox-commands/templates/testbox/test-browser/Application.cfc diff --git a/src/cfml/templates/testbox/test-browser/TestBoxLogo125.png b/src/cfml/system/modules/testbox-commands/templates/testbox/test-browser/TestBoxLogo125.png similarity index 100% rename from src/cfml/templates/testbox/test-browser/TestBoxLogo125.png rename to src/cfml/system/modules/testbox-commands/templates/testbox/test-browser/TestBoxLogo125.png diff --git a/src/cfml/templates/testbox/test-browser/index.cfm b/src/cfml/system/modules/testbox-commands/templates/testbox/test-browser/index.cfm similarity index 100% rename from src/cfml/templates/testbox/test-browser/index.cfm rename to src/cfml/system/modules/testbox-commands/templates/testbox/test-browser/index.cfm diff --git a/src/cfml/templates/testbox/test-harness/Application.cfc b/src/cfml/system/modules/testbox-commands/templates/testbox/test-harness/Application.cfc similarity index 100% rename from src/cfml/templates/testbox/test-harness/Application.cfc rename to src/cfml/system/modules/testbox-commands/templates/testbox/test-harness/Application.cfc diff --git a/src/cfml/templates/testbox/test-harness/results/TEST.properties b/src/cfml/system/modules/testbox-commands/templates/testbox/test-harness/results/TEST.properties similarity index 100% rename from src/cfml/templates/testbox/test-harness/results/TEST.properties rename to src/cfml/system/modules/testbox-commands/templates/testbox/test-harness/results/TEST.properties diff --git a/src/cfml/templates/testbox/test-harness/results/results_go_here.txt b/src/cfml/system/modules/testbox-commands/templates/testbox/test-harness/results/results_go_here.txt similarity index 100% rename from src/cfml/templates/testbox/test-harness/results/results_go_here.txt rename to src/cfml/system/modules/testbox-commands/templates/testbox/test-harness/results/results_go_here.txt diff --git a/src/cfml/templates/testbox/test-harness/runner.cfm b/src/cfml/system/modules/testbox-commands/templates/testbox/test-harness/runner.cfm similarity index 100% rename from src/cfml/templates/testbox/test-harness/runner.cfm rename to src/cfml/system/modules/testbox-commands/templates/testbox/test-harness/runner.cfm diff --git a/src/cfml/templates/testbox/test-harness/specs/BDDTest.cfc b/src/cfml/system/modules/testbox-commands/templates/testbox/test-harness/specs/BDDTest.cfc similarity index 100% rename from src/cfml/templates/testbox/test-harness/specs/BDDTest.cfc rename to src/cfml/system/modules/testbox-commands/templates/testbox/test-harness/specs/BDDTest.cfc diff --git a/src/cfml/templates/testbox/test-harness/specs/put_test_bundles_here.txt b/src/cfml/system/modules/testbox-commands/templates/testbox/test-harness/specs/put_test_bundles_here.txt similarity index 100% rename from src/cfml/templates/testbox/test-harness/specs/put_test_bundles_here.txt rename to src/cfml/system/modules/testbox-commands/templates/testbox/test-harness/specs/put_test_bundles_here.txt diff --git a/src/cfml/templates/testbox/test-harness/test.xml b/src/cfml/system/modules/testbox-commands/templates/testbox/test-harness/test.xml similarity index 100% rename from src/cfml/templates/testbox/test-harness/test.xml rename to src/cfml/system/modules/testbox-commands/templates/testbox/test-harness/test.xml diff --git a/src/cfml/templates/testbox/unit.txt b/src/cfml/system/modules/testbox-commands/templates/testbox/unit.txt similarity index 100% rename from src/cfml/templates/testbox/unit.txt rename to src/cfml/system/modules/testbox-commands/templates/testbox/unit.txt diff --git a/src/cfml/system/modules/wirebox-commands/ModuleConfig.cfc b/src/cfml/system/modules/wirebox-commands/ModuleConfig.cfc new file mode 100644 index 000000000..a400988b5 --- /dev/null +++ b/src/cfml/system/modules/wirebox-commands/ModuleConfig.cfc @@ -0,0 +1,11 @@ +/** +********************************************************************************* +* Copyright Since 2014 CommandBox by Ortus Solutions, Corp +* www.coldbox.org | www.ortussolutions.com +******************************************************************************** +* @author Brad Wood, Luis Majano +*/ +component { + function configure() { + } +} \ No newline at end of file diff --git a/src/cfml/commands/wirebox/create/aspects.cfc b/src/cfml/system/modules/wirebox-commands/commands/wirebox/create/aspects.cfc similarity index 58% rename from src/cfml/commands/wirebox/create/aspects.cfc rename to src/cfml/system/modules/wirebox-commands/commands/wirebox/create/aspects.cfc index 171ba060b..dce2a8c4e 100644 --- a/src/cfml/commands/wirebox/create/aspects.cfc +++ b/src/cfml/system/modules/wirebox-commands/commands/wirebox/create/aspects.cfc @@ -1,7 +1,7 @@ /** * Description of command **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * diff --git a/src/cfml/commands/wirebox/create/binder.cfc b/src/cfml/system/modules/wirebox-commands/commands/wirebox/create/binder.cfc similarity index 58% rename from src/cfml/commands/wirebox/create/binder.cfc rename to src/cfml/system/modules/wirebox-commands/commands/wirebox/create/binder.cfc index 171ba060b..dce2a8c4e 100644 --- a/src/cfml/commands/wirebox/create/binder.cfc +++ b/src/cfml/system/modules/wirebox-commands/commands/wirebox/create/binder.cfc @@ -1,7 +1,7 @@ /** * Description of command **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * diff --git a/src/cfml/commands/wirebox/create/dsl.cfc b/src/cfml/system/modules/wirebox-commands/commands/wirebox/create/dsl.cfc similarity index 58% rename from src/cfml/commands/wirebox/create/dsl.cfc rename to src/cfml/system/modules/wirebox-commands/commands/wirebox/create/dsl.cfc index 171ba060b..dce2a8c4e 100644 --- a/src/cfml/commands/wirebox/create/dsl.cfc +++ b/src/cfml/system/modules/wirebox-commands/commands/wirebox/create/dsl.cfc @@ -1,7 +1,7 @@ /** * Description of command **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * diff --git a/src/cfml/commands/wirebox/create/help.cfc b/src/cfml/system/modules/wirebox-commands/commands/wirebox/create/help.cfc similarity index 69% rename from src/cfml/commands/wirebox/create/help.cfc rename to src/cfml/system/modules/wirebox-commands/commands/wirebox/create/help.cfc index f660e7414..12e198f7f 100644 --- a/src/cfml/commands/wirebox/create/help.cfc +++ b/src/cfml/system/modules/wirebox-commands/commands/wirebox/create/help.cfc @@ -1,4 +1,4 @@ -component extends="commandbox.system.BaseCommand" excludeFromHelp=true { +component excludeFromHelp=true { function run() { diff --git a/src/cfml/commands/wirebox/create/scope.cfc b/src/cfml/system/modules/wirebox-commands/commands/wirebox/create/scope.cfc similarity index 58% rename from src/cfml/commands/wirebox/create/scope.cfc rename to src/cfml/system/modules/wirebox-commands/commands/wirebox/create/scope.cfc index 171ba060b..dce2a8c4e 100644 --- a/src/cfml/commands/wirebox/create/scope.cfc +++ b/src/cfml/system/modules/wirebox-commands/commands/wirebox/create/scope.cfc @@ -1,7 +1,7 @@ /** * Description of command **/ -component extends="commandbox.system.BaseCommand" aliases="" excludeFromHelp=false { +component { /** * diff --git a/src/cfml/commands/wirebox/help.cfc b/src/cfml/system/modules/wirebox-commands/commands/wirebox/help.cfc similarity index 68% rename from src/cfml/commands/wirebox/help.cfc rename to src/cfml/system/modules/wirebox-commands/commands/wirebox/help.cfc index 2204a78d4..43da506ef 100644 --- a/src/cfml/commands/wirebox/help.cfc +++ b/src/cfml/system/modules/wirebox-commands/commands/wirebox/help.cfc @@ -1,4 +1,4 @@ -component extends="commandbox.system.BaseCommand" excludeFromHelp=true { +component excludeFromHelp=true { function run() { diff --git a/src/cfml/templates/wirebox/Aspect.txt b/src/cfml/system/modules/wirebox-commands/templates/wirebox/Aspect.txt similarity index 100% rename from src/cfml/templates/wirebox/Aspect.txt rename to src/cfml/system/modules/wirebox-commands/templates/wirebox/Aspect.txt diff --git a/src/cfml/templates/wirebox/AspectScript.txt b/src/cfml/system/modules/wirebox-commands/templates/wirebox/AspectScript.txt similarity index 100% rename from src/cfml/templates/wirebox/AspectScript.txt rename to src/cfml/system/modules/wirebox-commands/templates/wirebox/AspectScript.txt diff --git a/src/cfml/templates/wirebox/WireBox.txt b/src/cfml/system/modules/wirebox-commands/templates/wirebox/WireBox.txt similarity index 100% rename from src/cfml/templates/wirebox/WireBox.txt rename to src/cfml/system/modules/wirebox-commands/templates/wirebox/WireBox.txt diff --git a/src/cfml/system/services/CommandService.cfc b/src/cfml/system/services/CommandService.cfc index a84402ef9..c13f9ad68 100644 --- a/src/cfml/system/services/CommandService.cfc +++ b/src/cfml/system/services/CommandService.cfc @@ -17,6 +17,9 @@ component accessors="true" singleton { property name='logger' inject='logbox:logger:{this}'; property name='wirebox' inject='wirebox'; property name='commandLocations' inject='commandLocations@constants'; + property name='interceptorService' inject='interceptorService'; + + property name='configured' default="false" type="boolean"; // TODO: Convert these to properties instance = { @@ -32,6 +35,7 @@ component accessors="true" singleton { * Constructor **/ function init(){ + setConfigured( false ); return this; } @@ -39,6 +43,14 @@ component accessors="true" singleton { * Configure the service */ CommandService function configure(){ + + // Check if handler mapped? + if( NOT wirebox.getBinder().mappingExists( 'commandbox.system.BaseCommand' ) ){ + // feed the base class + wirebox.registerNewInstance( name='commandbox.system.BaseCommand', instancePath='commandbox.system.BaseCommand' ) + .setAutowire( false ); + } + // map commands for( var commandLocation in commandLocations ){ @@ -50,6 +62,7 @@ component accessors="true" singleton { initCommands( commandLocation, commandLocation ); } + setConfigured( true ); return this; } @@ -114,6 +127,7 @@ component accessors="true" singleton { /** * run a command tokens * @tokens.hint tokens to run + * @piped.hint Data to pipe in to the first command **/ function runCommandTokens( required array tokens, string piped ){ @@ -121,19 +135,23 @@ component accessors="true" singleton { var commandChain = resolveCommandTokens( tokens ); // If there was piped input - if( structKeyExists( arguments, 'piped' ) && commandChain.len() && commandChain[1].found ) { - // Overwrite the first parameter with it - commandChain[1].parameters[ 1 ] = parser.escapeArg( piped ); + if( structKeyExists( arguments, 'piped' ) ) { + return runCommand( commandChain, tokens.toList( ' ' ), arguments.piped ); } - return runCommand( commandChain, tokens.toList( ' ' ) ); + return runCommand( commandChain, tokens.toList( ' ' ) ); + } /** * run a command * @commandChain.hint the chain of commands to run **/ - function runCommand( required array commandChain, required string line ){ + function runCommand( required array commandChain, required string line, string piped ){ + + if( structKeyExists( arguments, 'piped' ) ) { + var result = arguments.piped; + } // If nothing is returned, something bad happened (like an error instatiating the CFC) if( !commandChain.len() ){ @@ -149,8 +167,7 @@ component accessors="true" singleton { // If nothing was found, bail out here. if( !commandInfo.found ){ - shell.printError({message:'Command "#line#" cannot be resolved. Please type "#trim( "help #listChangeDelims( commandInfo.commandString, ' ', '.' )#" )#" for assistance.'}); - return; + throw( message='Command "#line#" cannot be resolved.', detail='Please type "#trim( "help #listChangeDelims( commandInfo.commandString, ' ', '.' )#" )#" for assistance.', type="commandException"); } // For help commands squish all the parameters together into one exactly as typed @@ -160,6 +177,13 @@ component accessors="true" singleton { namedParameters = {}, flags = {} }; + // For run don't process the parameter, just pass it right along. + } else if( commandInfo.commandReference.originalName == 'run' && commandInfo.parameters.len() ){ + var parameterInfo = { + positionalParameters = [ commandInfo.parameters[ 1 ] ], + namedParameters = {}, + flags = {} + }; // For normal commands, parse them out properly } else { var parameterInfo = parseParameters( commandInfo.parameters ); @@ -167,8 +191,7 @@ component accessors="true" singleton { // Parameters need to be ALL positional or ALL named if( arrayLen( parameterInfo.positionalParameters ) && structCount( parameterInfo.namedParameters ) ){ - shell.printError({message:"Please don't mix named and positional parameters, it makes me dizzy.#cr# #line#"}); - return; + throw( message='Please don''t mix named and positional parameters, it makes me dizzy.', detail=line, type="commandException"); } // These are the parameters declared by the command CFC @@ -176,17 +199,24 @@ component accessors="true" singleton { // If this is not the first command in the chain, // set its first parameter with the output from the last command - if( i > 1 ){ + if( structKeyExists( local, 'result' ) ){ // Clean off trailing any CR to help with piping one-liner outputs as inputs to another command if( result.endsWith( chr( 10 ) ) && len( result ) > 1 ){ result = left( result, len( result ) - 1 ); } // If we're using named parameters and this command has at least one param defined if( structCount( parameterInfo.namedParameters ) ){ + if( commandInfo.commandString == 'cfml' ) { + throw( message='Sorry, you can''t pipe data into a CFML function using named parameters since I don''t know the name of the piped parameter.', detail=line, type="commandException"); + } // Insert/overwrite the first param as our last result parameterInfo.namedParameters[ commandParams[1].name ?: '1' ] = result; } else { - parameterInfo.positionalParameters.prepend( result ); + if( commandInfo.commandString == 'cfml' ) { + parameterInfo.positionalParameters.insertAt( 2, result ); + } else { + parameterInfo.positionalParameters.prepend( result ); + } } } @@ -202,9 +232,10 @@ component accessors="true" singleton { parameterInfo.namedParameters = ensureRequiredParams( parameterInfo.namedParameters, commandParams ); // Ensure supplied params match the correct type - if( !validateParams( parameterInfo.namedParameters, commandParams ) ){ - return; - } + validateParams( parameterInfo.namedParameters, commandParams ); + + // Evaluate parameter expressions + evaluateExpressions( parameterInfo ); // Reset the printBuffer commandInfo.commandReference.CFC.reset(); @@ -222,17 +253,20 @@ component accessors="true" singleton { // Add command to the top of the stack instance.callStack.prepend( commandInfo ); + interceptorService.announceInterception( 'preCommand', { commandInfo=commandInfo, parameterInfo=parameterInfo } ); + // Run the command try { var result = commandInfo.commandReference.CFC.run( argumentCollection = parameterInfo.namedParameters ); } catch( any e ){ + // Clean up a bit + instance.callStack.clear(); + // Dump out anything the command had printed so far var result = commandInfo.commandReference.CFC.getResult(); if( len( result ) ){ shell.printString( result & cr ); } - // Clean up a bit - instance.callStack.clear(); // Now, where were we? rethrow; } @@ -244,7 +278,13 @@ component accessors="true" singleton { if( isNull( result ) ){ result = commandInfo.commandReference.CFC.getResult(); } - + var interceptData = { + commandInfo=commandInfo, + parameterInfo=parameterInfo, + result=result + }; + interceptorService.announceInterception( 'postCommand', interceptData ); + result = interceptData.result; } // End loop over command chain @@ -252,6 +292,39 @@ component accessors="true" singleton { } + /** + * Evaluates any expressions as a command string and puts the output in its place. + */ + function evaluateExpressions( required parameterInfo ) { + + // For each parameter being passed into this command + for( var paramName in parameterInfo.namedParameters ) { + + var paramValue = parameterInfo.namedParameters[ paramName ]; + // Look for an expression "foo" flagged as "__expression__foo__expression__" + var search = reFindNoCase( '__expression__.*?__expression__', paramValue, 1, true ); + + // As long as there are more expressions + while( search.pos[1] ) { + // Extract them + var expression = mid( paramValue, search.pos[1], search.len[1] ); + // Evaluate them + var result = runCommandline( mid( expression, 15, len( expression )-28 ) ) ?: ''; + + // Clean off trailing any CR to help with piping one-liner outputs as inputs to another command + if( result.endsWith( chr( 10 ) ) && len( result ) > 1 ){ + result = left( result, len( result ) - 1 ); + } + + // And stick their results in their place + parameterInfo.namedParameters[ paramName ] = replaceNoCase( paramValue, expression, result, 'one' ); + paramValue = parameterInfo.namedParameters[ paramName ]; + // Search again + var search = reFindNoCase( '__expression__.*?__expression__', paramValue, 1, true ); + } + } + } + /** * Take an array of parameters and parse them out as named or positional * @parameters.hint The array of params to parse. @@ -330,6 +403,41 @@ component accessors="true" singleton { // This is the droid you're looking for tokens = [ 'cd', drive ]; } + + // Shortcut for "run" command if first token starts with ! + if( tokens.len() && len( tokens[1] ) > 1 && tokens[1].startsWith( '!' ) ) { + // Trim the ! off + tokens[1] = right( tokens[1], len( tokens[1] ) - 1 ); + // tack on "run" + tokens.prepend( 'run' ); + } + + /* If command is "run", merge all remaining tokens into one string + * + * run cmd /c dir + * would essentially be turned into + * run "cmd /c dir" + */ + if( tokens.len() > 2 && tokens.first() == 'run' ) { + tokens = [ + 'run', + tokens.slice( 2, tokens.len()-1 ).toList( ' ' ) + ]; + } + + // Shortcut for "cfml" command if first token starts with # + if( tokens.len() && len( tokens[1] ) > 1 && tokens[1].startsWith( '##' ) ) { + // Trim the # off + tokens[1] = right( tokens[1], len( tokens[1] ) - 1 ); + + // If it looks like we have named params, convert the "name" to be named + if( tokens.len() > 1 && tokens[2] contains '=' ) { + tokens[1] = 'name=' & tokens[1]; + } + + // tack on "cfml" + tokens.prepend( 'cfml' ); + } var results = { commandString = '', @@ -358,12 +466,7 @@ component accessors="true" singleton { results.commandReference = results.commandReference[ '$' ]; // Create the command CFC instance if neccessary - var commandLoaded = lazyLoadCommandCFC( results.commandReference ); - // If there was an error loading the command - if( !commandLoaded ){ - // Error has already been displayed, so just pretend we didn't find anything. - return []; - } + lazyLoadCommandCFC( results.commandReference ); break; // If this is a folder, check and see if it has a "help" command @@ -402,14 +505,23 @@ component accessors="true" singleton { if( !structKeyExists( commandData, 'CFC' ) ){ // Create this command CFC try { - commandData.CFC = wireBox.getInstance( commandData.fullCFCPath ); + + // Check if command mapped? + if( NOT wirebox.getBinder().mappingExists( "command-" & commandData.fullCFCPath ) ){ + // feed this command to wirebox with virtual inheritance + wirebox.registerNewInstance( name="command-" & commandData.fullCFCPath, instancePath=commandData.fullCFCPath ) + .setScope( wirebox.getBinder().SCOPES.SINGLETON ) + .setThreadSafe( true ) + .setVirtualInheritance( "commandbox.system.BaseCommand" ); + } + // retrieve, build and wire from wirebox + commandData.CFC = wireBox.getInstance( "command-" & commandData.fullCFCPath ); + // This will catch nasty parse errors so the shell can keep loading } catch( any e ){ - systemOutput( 'Error creating command [#commandData.fullCFCPath#]#CR##CR#' ); + // Log the full exception with stack trace logger.error( 'Error creating command [#commandData.fullCFCPath#]. #e.message# #e.detail ?: ''#', e.stackTrace ); - // pretty print the exception - shell.printError( e ); - return false; + throw( message='Error creating command [#commandData.fullCFCPath#]', detail="#e.message# #CR# #e.detail ?: ''#", type="commandException"); } } // CFC exists check return true; @@ -489,7 +601,7 @@ component accessors="true" singleton { return; } - // must extend commandbox.system.BaseCommand, can't be Application.cfc + // must be CommandBox CFC, can't be Application.cfc if( CFCName == 'Application' || !isCommandCFC( commandData ) ){ return; } @@ -560,22 +672,7 @@ component accessors="true" singleton { */ function isCommandCFC( required struct commandData ){ var meta = arguments.commandData.commandMD; - - // Make sure command extends BaseCommand - var thisMeta = meta; - while( true ){ - // Once we find BaseCommand kick out of the loop - if( thisMeta.fullname == 'commandbox.system.BaseCommand' ){ - break; - } - // If we reach the end of the inheritance chain, we failed. - if( !structKeyExists( thisMeta, 'extends' ) ){ - return false; - } - // Moving pointer - thisMeta = thisMeta.extends; - } - + // Make sure command has a run() method for( var func in meta.functions ){ // Loop to find the "run()" method @@ -638,8 +735,7 @@ component accessors="true" singleton { && param.keyExists( "type" ) && !isValid( param.type, userNamedParams[ param.name ] ) ){ - shell.printError({message:"Parameter [#param.name#] has a value of [#userNamedParams[ param.name ]#] which is not of type [#param.type#]."}); - return false; + throw( message='Parameter [#param.name#] has a value of [#userNamedParams[ param.name ]#] which is not of type [#param.type#].', type="commandException"); } } // end for loop diff --git a/src/cfml/system/services/ConfigService.cfc b/src/cfml/system/services/ConfigService.cfc new file mode 100644 index 000000000..a1d2f01b1 --- /dev/null +++ b/src/cfml/system/services/ConfigService.cfc @@ -0,0 +1,158 @@ +/** +********************************************************************************* +* Copyright Since 2014 CommandBox by Ortus Solutions, Corp +* www.coldbox.org | www.ortussolutions.com +******************************************************************************** +* @author Brad Wood, Luis Majano +* +* I handle working with the CommandBox.json file +*/ +component accessors="true" singleton { + + // Holds the config settings in memory + property name="configSettings"; + // All known config settings-- really just for tab-completion right now + property name="possibleConfigSettings"; + // The physical path there config settings are persisted + property name="configFilePath"; + + // DI + property name='formatterUtil' inject='formatter'; + property name='ModuleService' inject='ModuleService'; + property name='JSONService' inject='JSONService'; + + /** + * Constructor + */ + function init(){ + // These aren't stored in the actual configSettings struct-- they're more for documentation + // and smart auto-completion to help people set new settings. + setPossibleConfigSettings([ + // Used in ModuleService + 'ModulesExternalLocation', + 'modulesInclude', + 'ModulesExclude', + // HTTP Proxy settings + 'proxy.server', + 'proxy.port', + 'proxy.user', + 'proxy.password', + // used in "run" command for a custom Unix shell + 'nativeShell', + // Endpoint data + 'endpoints', + 'endpoints.forgebox', + 'endpoints.forgebox.APIToken', + 'endpoints.forgebox.APIURL' + + ]); + + setConfigFilePath( '/commandbox-home/CommandBox.json' ); + + // Create the config file if neccessary + if( !fileExists( getConfigFilePath() ) ) { + fileWrite( getConfigFilePath(), '{}' ); + } + + loadConfig(); + + return this; + } + + function setConfigSettings( required struct configSettings ) { + variables.configSettings = arguments.configSettings; + saveConfig(); + } + + /** + * Get a setting from a configuration structure + * @name.hint The name of the setting. Allows for "deep" struct/array names. + * @defaultValue.hint The default value to use if setting does not exist + */ + function getSetting( required name, defaultValue ){ + + arguments.JSON = getConfigSettings(); + arguments.property = arguments.name; + + return JSONService.show( argumentCollection = arguments ); + } + + /** + * Check if a value exists in a configuration structure + * @name.hint The name of the setting. Allows for "deep" struct/array names. + */ + boolean function settingExists( required name ){ + arguments.JSON = getConfigSettings(); + arguments.property = arguments.name; + + return JSONService.check( argumentCollection = arguments ); + } + + /** + * Set a value in the application configuration settings + * @name.hint The name of the setting. Allows for "deep" struct/array names. + * @value.hint The value to set + * @thisAppend.hint Append an array or struct to existing + */ + function setSetting( required name, required value, boolean thisAppend=false ){ + + arguments.JSON = getConfigSettings(); + arguments.properties[ name ] = arguments.value; + + JSONService.set( argumentCollection = arguments ); + + saveConfig(); + return this; + } + + /** + * Remove a value in the application configuration settings + * @name.hint The name of the setting. Allows for "deep" struct/array names. + */ + function removeSetting( required name ){ + + arguments.JSON = getConfigSettings(); + arguments.property = arguments.name; + + JSONService.clear( argumentCollection = arguments ); + + saveConfig(); + return this; + } + + /** + * Loads config settings from disk + */ + function loadConfig(){ + // Don't call the setter here since we don't need to trigger a save. + variables.configSettings = deserializeJSON( fileRead( getConfigFilePath() ) ); + } + + /** + * Persists config settings to disk + */ + function saveConfig(){ + fileWrite( getConfigFilePath(), formatterUtil.formatJSON( serializeJSON( getConfigSettings() ) ) ); + + // Update ModuleService + ModuleService.overrideAllConfigSettings(); + } + + + /** + * Dynamic completion for property name based on contents of commandbox.json + * @all.hint Pass false to ONLY suggest existing setting names. True will suggest all possible settings. + */ + function completeProperty( all=false ) { + // Get all config settings currently set + var props = JSONService.addProp( [], '', '', getConfigSettings() ); + + // If we want all possible options... + if( arguments.all ) { + // ... Then add them in + props.append( getPossibleConfigSettings(), true ); + } + + return props; + } +} \ No newline at end of file diff --git a/src/cfml/system/services/EndpointService.cfc b/src/cfml/system/services/EndpointService.cfc index fce7032aa..ac9718c35 100644 --- a/src/cfml/system/services/EndpointService.cfc +++ b/src/cfml/system/services/EndpointService.cfc @@ -13,7 +13,8 @@ component accessors="true" singleton { property name="logger" inject="logbox:logger:{this}"; property name="wirebox" inject="wirebox"; property name="fileSystemUtil" inject="FileSystem"; - property name="consoleLogger" inject="logbox:logger:console"; + property name="consoleLogger" inject="logbox:logger:console"; + property name="configService" inject="configService"; // Properties property name="endpointRegistry" type="struct"; @@ -132,11 +133,76 @@ component accessors="true" singleton { /** * Inspects ID and returns endpoint object, endpointName, and ID (with endpoint stripped). - */ + */ struct function resolveEndpoint( required string ID, required string currentWorkingDirectory ) { var endpointData = resolveEndpointData( arguments.ID, arguments.currentWorkingDirectory ); endpointData[ 'endpoint' ] = getEndpoint( endpointData.endpointName ); return endpointData; } + /** + * A facade to create a user with an interactive endpoint. Keeping this logic here so I can standardize the storage + * of the APIToken and make it reusable outside of the command. + */ + function createEndpointUser( + required string endpointName, + required string username, + required string password, + required string email, + required string firstName, + required string lastName + ) { + // Get all endpoints that are registered + var endpointRegistry = getEndpointRegistry(); + // Confirm endpoint name exists + if( !endpointRegistry.keyExists( arguments.endpointName ) ) { + throw( "Sorry, the endpoint [#arguments.endpointName#] doesn't exist. Valid names are [#endpointRegistry.keyList()#]", 'endpointException' ); + } + + // Get endpoint object + var endpoint = getEndpoint( arguments.endpointName ); + + // Confirm is interactive endpoint + if( !isInstanceOf( endpoint, 'IEndpointInteractive' ) ) { + throw( "Sorry, the endpoint [#arguments.endpointName#] does not support registering users.", 'endpointException' ); } + + // Create the user + var APIToken = endpoint.createUser( argumentCollection=arguments ); + + // Store the APIToken + configService.setSetting( 'endpoints.#endpointName#.APIToken', APIToken ); + + } + + /** + * A facade to login a user with an interactive endpoint. Keeping this logic here so I can standardize the storage + * of the APIToken and make it reusable outside of the command. + */ + function loginEndpointUser( + required string endpointName, + required string username, + required string password + ) { + // Get all endpoints that are registered + var endpointRegistry = getEndpointRegistry(); + // Confirm endpoint name exists + if( !endpointRegistry.keyExists( arguments.endpointName ) ) { + throw( "Sorry, the endpoint [#arguments.endpointName#] doesn't exist. Valid names are [#endpointRegistry.keyList()#]", 'endpointException' ); + } + + // Get endpoint object + var endpoint = getEndpoint( arguments.endpointName ); + + // Confirm is interactive endpoint + if( !isInstanceOf( endpoint, 'IEndpointInteractive' ) ) { + throw( "Sorry, the endpoint [#arguments.endpointName#] does not support registering users.", 'endpointException' ); } + + // Create the user + var APIToken = endpoint.login( argumentCollection=arguments ); + + // Store the APIToken + configService.setSetting( 'endpoints.#endpointName#.APIToken', APIToken ); + + } + } \ No newline at end of file diff --git a/src/cfml/system/services/InterceptorService.cfc b/src/cfml/system/services/InterceptorService.cfc new file mode 100644 index 000000000..3a5eafc29 --- /dev/null +++ b/src/cfml/system/services/InterceptorService.cfc @@ -0,0 +1,179 @@ +/** +********************************************************************************* +* Copyright Since 2005 ColdBox Platform by Ortus Solutions, Corp +* www.coldbox.org | www.ortussolutions.com +******************************************************************************** +* @author Brad Wood, Luis Majano +* The InterceptorService that wraps the EventPoolManager and provides special treatment +* for interceptors to give them virtual inheritance and autowiring +*/ +component accessors=true singleton { + property name='Shell'; + property name='EventPoolManager'; + property name='InterceptionPoints'; + + // DI + property name='log' inject='logbox:logger:{this}'; + + /** + * @shell.inject shell + + */ + InterceptorService function init( required shell ) { + setShell( arguments.shell ); + + setInterceptionPoints( [ + // CLI lifecycle + 'onCLIStart','onCLIExit', + // Command execution lifecycle + 'preCommand','postCommand', + // Module lifecycle + 'preModuleLoad','postModuleLoad','preModuleUnLoad','postModuleUnload', + // Server lifecycle + 'onServerStart','onServerStop', + // Error handling + 'onException', + // Package lifecycle + 'preInstall','postInstall','preUninstall','postUninstall' + ] ); + + return this; + } + + + function configure() { + setEventPoolManager( getShell().getWireBox().getEventManager() ); + appendInterceptionPoints( getInterceptionPoints().toList() ); + return this; + } + + function announceInterception( required string state, struct interceptData={} ) { + getEventPoolManager().processState( state, interceptData ); + } + + /** + * @interceptor.hint The qualified class of the interceptor to register or an already instantiated object as an interceptor. + * @interceptorProperties.hint The structure of properties to register this interceptor with. + * @interceptorProperties.colddoc:generic struct + * @customPoints.hint A comma delimmited list or array of custom interception points, if the object or class sent in observes them. + * @interceptorName.hint The name to use for the interceptor when stored. If not used, we will use the name found in the object's class + */ + function registerInterceptor( + any interceptor, + struct interceptorProperties={}, + string customPoints='', + string interceptorName='' + ) { + + // determine registration names + if( !len( arguments.interceptorName ) ) { + if( isSimpleValue( arguments.interceptor ) ){ + arguments.interceptorName = listLast( arguments.interceptor, "." ); + } else { + arguments.interceptorName = listLast( getMetaData( arguments.interceptor ).name, "."); + } + } + + // Did we send in a class to instantiate + if( isSimpleValue( arguments.interceptor ) ) { + // Create the Interceptor Class + try{ + arguments.interceptor = createInterceptor( arguments.interceptor, arguments.interceptorName, arguments.interceptorProperties ); + } + catch(Any e){ + log.error("Error creating interceptor: #arguments.interceptor#. #e.message# #e.detail# #e.stackTrace#",e.tagContext); + rethrow; + } + + // Configure the Interceptor + arguments.interceptor.configure(); + + }//end if class is sent. + + getEventPoolManager().register( arguments.interceptor, arguments.interceptorName, arguments.customPoints ); + + return this; + } + + /** + * @interceptorClass.hint The class path to instantiate + * @interceptorName.hint The unique name of the interceptor + * @interceptorProperties.hint The properties + */ + function createInterceptor( + required string interceptorClass, + interceptorName, + interceptorProperties={} + ) { + var oInterceptor = ""; + var wirebox = getShell().getWireBox(); + + // Check if interceptor mapped? + if( NOT wirebox.getBinder().mappingExists( "interceptor-" & interceptorName ) ){ + // wirebox lazy load checks + wireboxSetup(); + // feed this interceptor to wirebox with virtual inheritance just in case, use registerNewInstance so its thread safe + wirebox.registerNewInstance(name="interceptor-" & interceptorName, instancePath=interceptorClass) + .setScope( wirebox.getBinder().SCOPES.SINGLETON ) + .setThreadSafe( true ) + .setVirtualInheritance( "commandbox.system.Interceptor" ) + .addDIConstructorArgument( name="shell", value=getShell() ) + .addDIConstructorArgument( name="properties", value=interceptorProperties ); + } + // retrieve, build and wire from wirebox + oInterceptor = wirebox.getInstance( "interceptor-" & interceptorName ); + // check for virtual $super, if it does, pass new properties + if( structKeyExists(oInterceptor, "$super") ){ + oInterceptor.$super.setProperties( interceptorProperties ); + } + + return oInterceptor; + } + + /** + * Verifies the setup for interceptor classes is online + */ + private function wireboxSetup() { + var wirebox = getShell().getWireBox(); + + // Check if handler mapped? + if( NOT wirebox.getBinder().mappingExists( 'commandbox.system.Interceptor' ) ){ + // feed the base class + wirebox.registerNewInstance(name='commandbox.system.Interceptor', instancePath='commandbox.system.Interceptor') + .addDIConstructorArgument( name="shell", value=getShell() ) + .addDIConstructorArgument( name="properties", value=structNew() ) + .setAutowire( false ); + } + } + + /** + * Get an interceptor according to its name from a state. + */ + function getInterceptor( required string interceptorName ) { + return getEventPoolManager().getObject( arguments.interceptorName ); + } + + /** + * Append a list of custom interception points to the CORE interception points and returns itself + * @customPoints.hint A comma delimmited list or array of custom interception points to append. If they already exists, then they will not be added again. + */ + function appendInterceptionPoints( required customPoints='' ) { + getEventPoolManager().appendInterceptionPoints( customPoints ); + return this; + } + + /** + * Get the registered event states in this event manager + */ + function getInterceptionStates() { + return getEventPoolManager().getEventStates(); + } + + /** + * Unregister an interceptor from an interception state or all states. If the state does not exists, it returns false + */ + function unregister( required string name, state='' ) { + return getEventPoolManager().unregister( arguemnts.name, arguments.state ); + } + +} \ No newline at end of file diff --git a/src/cfml/system/services/JSONService.cfc b/src/cfml/system/services/JSONService.cfc new file mode 100644 index 000000000..673ddb918 --- /dev/null +++ b/src/cfml/system/services/JSONService.cfc @@ -0,0 +1,201 @@ +/** +********************************************************************************* +* Copyright Since 2014 CommandBox by Ortus Solutions, Corp +* www.coldbox.org | www.ortussolutions.com +******************************************************************************** +* @author Brad Wood, Luis Majano +* +* I am a collection of shared functionality for dealing with JSON files +*/ +component accessors="true" singleton { + + // DI + property name="logger" inject="logbox:logger:{this}"; + + /** + * Constructor + */ + function init(){ + return this; + } + + /** + * I check for the existance of a property + */ + boolean function check( required any JSON, required string property ){ + + var fullPropertyName = 'arguments.JSON' & toBracketNotation( arguments.property ); + + return isDefined( fullPropertyName ); + } + + /** + * I get a property from a deserialized JSON object and return it + */ + function show( required any JSON, required string property, defaultValue ){ + + var fullPropertyName = 'arguments.JSON' & toBracketNotation( arguments.property ); + + if( !isDefined( fullPropertyName ) ) { + if( structKeyExists( arguments, 'defaultValue' ) ) { + return arguments.defaultValue; + } else { + throw( message='Property [#arguments.property#] doesn''t exist.', type="JSONException"); + } + } + + return evaluate( fullPropertyName ); + } + + + /** + * I set a property from a deserialized JSON object and returns an array of messages regarding the word that was done. + */ + function set( required any JSON, required struct properties, required boolean thisAppend ){ + var results = []; + + for( var prop in arguments.properties ) { + + var fullPropertyName = 'arguments.JSON' & toBracketNotation( prop ); + + var propertyValue = arguments.properties[ prop ]; + if( isJSON( propertyValue ) ) { + // We're trying to append and the target property exists + if( thisAppend && isDefined( fullPropertyName ) ) { + // The target property we're trying to append to + var targetProperty = evaluate( fullPropertyName ); + // The value we want to append + var complexValue = deserializeJSON( arguments.properties[ prop ] ); + // The target property is not simple, and matches the same data type as the incoming data + if( !isSimpleValue( targetProperty ) && ( isArray( targetProperty ) == isArray( complexValue ) ) ) { + // Make this idempotent so arrays don't get duplicate values + if( isArray( complexValue ) ) { + // For each new value + for( var newValue in complexValue ) { + // Check to see if it's already in the array + if( !targetProperty.find( newValue ) ) { + // If not, add it. + targetProperty.append( newValue ); + } + } + // structs + } else { + targetProperty.append( complexValue, true ); + } + results.append( '#arguments.properties[ prop ]# appended to #prop#' ); + continue; + } + + } + // If any of the ifs above fail, we'll fall back through to this + evaluate( '#fullPropertyName# = deserializeJSON( arguments.properties[ prop ] )' ); + } else { + evaluate( '#fullPropertyName# = arguments.properties[ prop ]' ); + } + results.append( 'Set #prop# = #arguments.properties[ prop ]#' ); + } + return results; + } + + + /** + * I clear a property from a deserialized JSON object. + */ + function clear( required any JSON, required string property ){ + + // See if this string ends with array brackets containing a number greater than 1. Ex: test[3] + var search = reFind( "\[\s*([1-9][0-9]*)\s*\]$", property, 1, true ); + + // Deal with array index + if( search.pos[1] ) { + // Index to remove + var arrayIndex = mid( property, search.pos[2], search.len[2] ); + // Path to the array + var theArray = left( property, search.pos[1]-1 ); + + // Verify the full path exists (including the array index) + + var fullPropertyName = 'arguments.JSON' & toBracketNotation( arguments.property ); + if( !isDefined( fullPropertyName ) ) { + throw( message='#arguments.property# does not exist.', type="JSONException"); + } + // Get the array reference + var fullPropertyName = 'arguments.JSON' & toBracketNotation( theArray ); + var propertyValue = evaluate( fullPropertyName ); + // Remove the index + propertyValue.deleteAt( arrayIndex ); + + // Else see if it's a dot-delimted struct path. Ex foo.bar + } else if( listLen( property, '.' ) >= 2 ) { + // Name of last key to remove + var last = listLast( property, '.' ); + // path to containing struct + var everythingBut = listDeleteAt( property, listLen( property, '.' ), '.' ); + + // Confirm it exists + var fullPropertyName = 'arguments.JSON' & toBracketNotation( everythingBut ); + + if( !isDefined( fullPropertyName ) ) { + throw( message='#arguments.property# does not exist.', type="JSONException"); + } + // Get a refernce to the containing struct + var propertyValue = evaluate( fullPropertyName ); + // Remove the key + structDelete( propertyValue, last ); + // Else just a simple propery name + } else { + // Make sure it exists + if( !structKeyExists( JSON, arguments.property ) ) { + throw( message='#arguments.property# does not exist.', type="JSONException"); + } + // Remove it + structDelete( JSON, arguments.property ); + } + + } + + + // Convert foo.bar-baz[1] to ['foo']['bar-baz'][1] + private function toBracketNotation( required string property ) { + var tmpProperty = replace( arguments.property, '[', '.[', 'all' ); + tmpProperty = replace( tmpProperty, ']', '].', 'all' ); + var fullPropertyName = ''; + for( var item in listToArray( tmpProperty, '.' ) ) { + if( item.startsWith( '[' ) ) { + fullPropertyName &= item; + } else { + fullPropertyName &= '[ "#item#" ]'; + } + } + return fullPropertyName; + } + + // Recursive function to crawl struct and create a string that represents each property. + function addProp( props, prop, safeProp, targetStruct ) { + var propValue = ( len( prop ) ? evaluate( 'targetStruct#safeProp#' ) : targetStruct ); + + if( isStruct( propValue ) ) { + // Add all of this struct's keys + for( var thisProp in propValue ) { + var newProp = listAppend( prop, thisProp, '.' ); + var newSafeProp = "#safeProp#['#thisProp#']"; + props.append( newProp ); + props = addProp( props, newProp, newSafeProp, targetStruct ); + } + } + + if( isArray( propValue ) ) { + // Add all of this array's indexes + var i = 0; + while( ++i <= propValue.len() ) { + var newProp = '#prop#[#i#]'; + var newSafeProp = '#safeProp#[#i#]'; + props.append( newProp ); + props = addProp( props, newProp, newSafeProp, targetStruct ); + } + } + + return props; + } + +} \ No newline at end of file diff --git a/src/cfml/system/services/ModuleService.cfc b/src/cfml/system/services/ModuleService.cfc new file mode 100644 index 000000000..ac16e1a53 --- /dev/null +++ b/src/cfml/system/services/ModuleService.cfc @@ -0,0 +1,799 @@ + + + + + + + + + + + + + + + + + variables.shell = arguments.shell; + + // service properties + instance.logger = ""; + instance.mConfigCache = {}; + instance.moduleRegistry = createObject( "java", "java.util.LinkedHashMap" ).init(); + instance.cfmappingRegistry = {}; + + setModuleData( {} ); + + return this; + + + + + + + + + + + + + + //Get Local Logger Now Configured + instance.logger = shell.getLogBox().getLogger(this); + + // Register The Modules + registerAllModules(); + + + + + + + // Unload all modules + unloadAll(); + + + + + + + + + + + + + + + + + + + // Add the application's module's location and the system core modules + var modLocations = [ '/commandbox/system/modules', '/commandbox/modules' ]; + // Add the application's external locations array. + modLocations.addAll( ConfigService.getSetting( "ModulesExternalLocation", [] ) ); + // iterate through locations and build the module registry in order + buildRegistry( modLocations ); + + + + + + + var foundModules = ""; + var includeModules = ConfigService.getSetting( "modulesInclude", [] ); + + // Register the initial empty module configuration holder structure + structClear( getModuleData() ); + // clean the registry as we are registering all modules + instance.moduleRegistry = createObject( "java", "java.util.LinkedHashMap" ).init(); + // Now rebuild it + rebuildModuleRegistry(); + + // Are we using an include list? + if( arrayLen( includeModules ) ){ + for( var thisModule in includeModules ){ + // does module exists in the registry? We only register what is found + if( structKeyExists( instance.moduleRegistry, thisModule ) ){ + registerModule( thisModule ); + } + } + return this; + } + + // Iterate through registry and register each module + var aModules = structKeyArray( instance.moduleRegistry ); + for( var thisModule in aModules ){ + if( canLoad( thisModule ) ){ + registerModule( thisModule ); + } + } + + return this; + + + + + + + + + registerModule( arguments.moduleName, arguments.invocationPath ); + activateModule( arguments.moduleName ); + + + + + + + + + + + // Module To Load + var modName = arguments.moduleName; + var modulesConfiguration = getModuleData(); + // CommandBox doesn't really have settings per se-- + // at least not ones I'm comfortable with modules overriding. + //var appSettings = shell.getConfigSettings(); + + + // Check if incoming invocation path is sent, if so, register as new module + if( len( arguments.invocationPath ) ){ + // Check if passed module name is already registered + if( structKeyExists( instance.moduleRegistry, arguments.moduleName ) AND !arguments.force ){ + instance.logger.warn( "The module #arguments.moduleName# has already been registered, so skipping registration" ); + return false; + } + // register new incoming location + instance.moduleRegistry[ arguments.moduleName ] = { + locationPath = "/" & replace( arguments.invocationPath,".","/","all" ), + physicalPath = expandPath( "/" & replace( arguments.invocationPath,".","/","all" ) ), + invocationPath = arguments.invocationPath + }; + } + + // Check if passed module name is not loaded into the registry + if( NOT structKeyExists( instance.moduleRegistry, arguments.moduleName ) ){ + throw( message="The module #arguments.moduleName# is not valid", + detail="Valid module names are: #structKeyList( instance.moduleRegistry )#", + type="ModuleService.InvalidModuleName" ); + } + + // Setup module metadata info + var modulesLocation = instance.moduleRegistry[ modName ].locationPath; + var modulesPath = instance.moduleRegistry[ modName ].physicalPath; + var modulesInvocationPath = instance.moduleRegistry[ modName ].invocationPath; + var modLocation = modulesPath & "/" & modName; + var isBundle = listLast( modLocation, "-" ) eq "bundle"; + + // Check if module config exists, or we have a module. + if( NOT fileExists( modLocation & "/ModuleConfig.cfc" ) && NOT isBundle ){ + instance.logger.WARN( "The module (#modName#) cannot be loaded as it does not have a ModuleConfig.cfc in its root. Path Checked: #modLocation#" ); + return false; + } + + // Module Bundle Registration + if( isBundle ){ + // Bundle Loading + var aBundleModules = directoryList( modLocation, false, "array" ); + for( var thisModule in aBundleModules ){ + // cleanup module name + var bundleModuleName = listLast( thisModule, "/\" ); + // register the bundle module + registerModule( moduleName=bundleModuleName, + invocationPath=modulesInvocationPath & "." & modName, + parent=modName, + force=true ); + } + // the bundle has loaded, it needs no config data + return true; + } + + // lock registration + lock name="module.registration.#arguments.modulename#" type="exclusive" throwontimeout="true" timeout="20"{ + + // Setup Vanilla Config information for module + var mConfig = { + // Module MetaData and Directives + title = "", + // execution aliases + aliases = [], + author ="", + webURL ="", + description ="", + version ="", + // ColdFusion mapping + cfmapping = modName, + // Models namespsace + modelNamespace = modName, + // Auto map models flag + autoMapModels = true, + // when this registration ocurred + loadTime = now(), + // Flag that denotes if the module has been activated or not + activated = false, + // Any dependencies this module requires to be loaded first + dependencies = [], + // Flag that says if this module should NOT be loaded + disabled = false, + // flag that says if this module can be activated or not + activate = true, + // Module Configurations + path = modLocation, + invocationPath = modulesInvocationPath & "." & modName, + mapping = modulesLocation & "/" & modName, + modelsInvocationPath = modulesInvocationPath & "." & modName, + modelsPhysicalPath = modLocation, + commandsInvocationPath = modulesInvocationPath & "." & modName, + commandsPhysicalPath = modLocation, + parentSettings = {}, + settings = {}, + interceptors = [], + interceptorSettings = { customInterceptionPoints = "" }, + conventions = { + modelsLocation = "models", + commandsLocation = "commands" + }, + childModules = [], + parent = arguments.parent + }; + + + // Load Module configuration from cfc and store it in module Config Cache + var oConfig = loadModuleConfiguration( mConfig, arguments.moduleName ); + // Verify if module has been disabled + if( mConfig.disabled ){ + if( instance.logger.canDebug() ){ + instance.logger.debug( "Skipping module: #arguments.moduleName# as it has been disabled!" ); + } + return false; + } else { + instance.mConfigCache[ modName ] = oConfig; + } + // Store module configuration in main modules configuration + modulesConfiguration[ modName ] = mConfig; + // Link aliases by reference in both modules list and config cache + for( var thisAlias in mConfig.aliases ){ + modulesConfiguration[ thisAlias ] = modulesConfiguration[ modName ]; + instance.mConfigCache[ thisAlias ] = instance.mConfigCache[ modName ]; + } + // Update the paths according to conventions + mConfig.modelsInvocationPath &= ".#replace( mConfig.conventions.modelsLocation, "/", ".", "all" )#"; + mConfig.modelsPhysicalPath &= "/#mConfig.conventions.modelsLocation#"; + + mConfig.commandsInvocationPath &= ".#replace( mConfig.conventions.commandsLocation, "/", ".", "all" )#"; + mConfig.commandsPhysicalPath &= "/#mConfig.conventions.commandsLocation#"; + + // Register CFML Mapping if it exists, for loading purposes + if( len( trim( mConfig.cfMapping ) ) ){ + shell.getUtil().addMapping( name=mConfig.cfMapping, path=mConfig.path ); + instance.cfmappingRegistry[ mConfig.cfMapping ] = mConfig.path; + } + // Register Custom Interception Points + shell.getInterceptorService().appendInterceptionPoints( mConfig.interceptorSettings.customInterceptionPoints ); + // Register Parent Settings + //structAppend( appSettings, mConfig.parentSettings, true ); + // Inception? + if( directoryExists( mConfig.path & "/modules" ) ){ + // register the children + var childModules = directoryList( mConfig.path & "/modules", false, "array" ); + for( var thisChild in childModules ){ + // cleanup module name + var childName = listLast( thisChild, "/\" ); + // verify ModuleConfig exists, else skip + if( fileExists( thisChild & "/ModuleConfig.cfc" ) ){ + // add to parent children + arrayAppend( mConfig.childModules, childname ); + // register it + registerModule( moduleName=childName, + invocationPath=mConfig.invocationPath & ".modules", + parent=modName ); + } else if( instance.logger.canDebug() ){ + instance.logger.debug( "Inception Module #childName# does not have a valid ModuleConfig.cfc in its root, so skipping registration" ); + } + } + } + + // Log registration + if( instance.logger.canDebug() ){ + instance.logger.debug( "Module #arguments.moduleName# registered successfully." ); + } + } // end lock + + return true; + + + + + + + // Iterate through cfmapping registry and load them + for( var thisMapping in instance.cfmappingRegistry ){ + shell.getUtil().addMapping( name=thisMapping, path=instance.cfmappingRegistry[ thisMapping ] ); + } + + + + + + + var modules = getModuleData(); + // Iterate through module configuration and activate each module + for( var moduleName in modules ){ + // Verify the exception and inclusion lists + if( canLoad( moduleName ) ){ + activateModule( moduleName ); + } + } + + + + + + + + var modules = getModuleData(); + var iData = {}; + var y = 1; + var key = ""; + var interceptorService = shell.getInterceptorService(); + var wirebox = shell.getWireBox(); + + // If module not registered, throw exception + if( NOT structKeyExists( modules, arguments.moduleName ) ){ + throw( message="Cannot activate module: #arguments.moduleName#", + detail="The module has not been registered, register the module first and then activate it.", + type="ModuleService.IllegalModuleState" ); + } + + // Check if module already activated + if( modules[ arguments.moduleName ].activated ){ + // Log it + if( instance.logger.canDebug() ){ + instance.logger.debug( "Module #arguments.moduleName# already activated, skipping activation." ); + } + return this; + } + + // Check if module CAN be activated + if( !modules[ arguments.moduleName ].activate ){ + // Log it + if( instance.logger.canDebug() ){ + instance.logger.debug( "Module #arguments.moduleName# cannot be activated as it is flagged to not activate, skipping activation." ); + } + return this; + } + + // Get module settings + var mConfig = modules[ arguments.moduleName ]; + + // Do we have dependencies to activate first + if( arrayLen( mConfig.dependencies ) ){ + for( var thisDependency in mConfig.dependencies ){ + if( instance.logger.canDebug() ){ + instance.logger.debug( "Activating #arguments.moduleName# requests dependency activation: #thisDependency#" ); + } + // Activate dependency first + activateModule( thisDependency ); + } + } + + // lock and load baby + lock name="module.activation.#arguments.moduleName#" type="exclusive" timeout="20" throwontimeout="true"{ + + // preModuleLoad interception + iData = { moduleLocation=mConfig.path,moduleName=arguments.moduleName }; + interceptorService.announceInterception( "preModuleLoad", iData ); + + // Register the Config as an observable also. + interceptorService.registerInterceptor( interceptor=instance.mConfigCache[ arguments.moduleName ], interceptorName="ModuleConfig:#arguments.moduleName#" ); + + // Register Models if it exists + if( directoryExists( mconfig.modelsPhysicalPath ) and mConfig.autoMapModels ){ + // Add as a mapped directory with module name as the namespace with correct mapping path + var packagePath = ( len( mConfig.cfmapping ) ? mConfig.cfmapping & ".#mConfig.conventions.modelsLocation#" : mConfig.modelsInvocationPath ); + if( len( mConfig.modelNamespace ) ){ + wirebox.getBinder().mapDirectory( packagePath=packagePath, namespace="@#mConfig.modelNamespace#" ); + } else { + // just register with no namespace + wirebox.getBinder().mapDirectory( packagePath=packagePath ); + } + } + + // Register commands if they exist + if( directoryExists( mconfig.commandsPhysicalPath ) ){ + var commandPath = '/' & replace( mconfig.commandsInvocationPath, '.', '/', 'all' ); + CommandService.initCommands( commandPath, commandPath ); + } + + // Register Interceptors with Announcement service + for( y=1; y lte arrayLen( mConfig.interceptors ); y++ ){ + interceptorService.registerInterceptor( interceptor=mConfig.interceptors[ y ].class, + interceptorProperties=mConfig.interceptors[ y ].properties, + interceptorName=mConfig.interceptors[ y ].name); + // Loop over module interceptors to autowire them + wirebox.autowire( target=interceptorService.getInterceptor( mConfig.interceptors[ y ].name, true ), + targetID=mConfig.interceptors[ y ].class ); + } + + // Register module routing entry point pre-pended to routes + /*if( shell.settingExists( 'sesBaseURL' ) AND len( mConfig.entryPoint ) AND NOT find( ":", mConfig.entryPoint ) ){ + interceptorService.getInterceptor( "SES", true ).addModuleRoutes( pattern=mConfig.entryPoint, module=arguments.moduleName, append=false ); + }*/ + + // Call on module configuration object onLoad() if found + if( structKeyExists( instance.mConfigCache[ arguments.moduleName ], "onLoad" ) ){ + instance.mConfigCache[ arguments.moduleName ].onLoad(); + } + + // postModuleLoad interception + iData = { moduleLocation=mConfig.path, moduleName=arguments.moduleName, moduleConfig=mConfig }; + interceptorService.announceInterception( "postModuleLoad", iData ); + + // Mark it as loaded as it is now activated + mConfig.activated = true; + + // Now activate any children + for( var thisChild in mConfig.childModules ){ + activateModule( moduleName=thisChild ); + } + + // Log it + if( instance.logger.canDebug() ){ + instance.logger.debug( "Module #arguments.moduleName# activated sucessfully." ); + } + + } // end lock + + return this; + + + + + + + + unload(arguments.moduleName); + registerModule(arguments.moduleName); + activateModule(arguments.moduleName); + + + + + + + unloadAll(); + registerAllModules(); + activateAllModules(); + + + + + + + var modules = structKeyList(getModuleData()); + + return listToArray(modules); + + + + + + + + + + + + + + + var modules = getModuleData(); + return ( isModuleRegistered( arguments.moduleName ) and modules[ arguments.moduleName ].activated ? true : false ); + + + + + + + + // This method basically unregisters the module configuration + var iData = {moduleName=arguments.moduleName}; + var interceptorService = shell.getInterceptorService(); + var x = 1; + var exceptionUnloading = ""; + + // Check if module is loaded? + if( NOT structKeyExists(getModuleData(),arguments.moduleName) ){ return false; } + + + + + + // Check if module is loaded? + if( NOT structKeyExists(getModuleData(),arguments.moduleName) ){ return false; } + + // Before unloading a module interception + interceptorService.announceInterception( "preModuleUnload",iData); + + // Call on module configuration object onLoad() if found + if( structKeyExists(instance.mConfigCache[ arguments.moduleName ],"onUnload" ) ){ + try{ + instance.mConfigCache[ arguments.moduleName ].onUnload(); + } catch( Any e ){ + instance.logger.error( "Error unloading module: #arguments.moduleName#. #e.message# #e.detail#", e ); + exceptionUnloading = e; + } + } + + // Unregister all interceptors + for(x=1; x lte arrayLen( getModuleData()[ arguments.moduleName ].interceptors ); x++){ + interceptorService.unregister( getModuleData()[ arguments.moduleName ].interceptors[ x ].name); + } + // Unregister Config object + interceptorService.unregister( "ModuleConfig:#arguments.moduleName#" ); + + // Remove SES if enabled. + /*if( shell.settingExists( "sesBaseURL" ) ){ + interceptorService.getInterceptor( "SES", true ).removeModuleRoutes( arguments.moduleName ); + }*/ + + // Remove the possible config names with the ConfigService for auto-completion + var possibleConfigSettings = []; + for( var settingName in ConfigService.getPossibleConfigSettings() ) { + if( !reFindNoCase( '^modules.#arguments.moduleName#.', settingName ) ) { + possibleConfigSettings.append( settingName ); + } + } + ConfigService.setPossibleConfigSettings( possibleConfigSettings ); + + // Remove configuration + structDelete( getModuleData(), arguments.moduleName ); + + // Remove Configuration object from Cache + structDelete( instance.mConfigCache, arguments.moduleName ); + + //After unloading a module interception + interceptorService.announceInterception( "postModuleUnload", iData ); + + // Log it + if( instance.logger.canDebug() ){ + instance.logger.debug( "Module #arguments.moduleName# unloaded successfully." ); + } + + // Do we need to throw exception? + if( !isSimpleValue( exceptionUnloading ) ){ + throw( exceptionUnloading ); + } + + + + + + + + + + // This method basically unregisters the module configuration + var modules = getModuleData(); + var key = ""; + + // Unload all modules + for(key in modules){ + unload(key); + } + + + + + + + + + var mConfig = arguments.config; + var oConfig = createObject( "component", mConfig.invocationPath & ".ModuleConfig" ); + var toLoad = ""; + var mixerUtil = shell.getUtil().getMixerUtil(); + + // Decorate It + oConfig.injectPropertyMixin = mixerUtil.injectPropertyMixin; + oConfig.getPropertyMixin = mixerUtil.getPropertyMixin; + + // MixIn Variables + oConfig.injectPropertyMixin( "shell", shell ); + oConfig.injectPropertyMixin( "moduleMapping", mConfig.mapping ); + oConfig.injectPropertyMixin( "modulePath", mConfig.path ); + oConfig.injectPropertyMixin( "logBox", shell.getLogBox() ); + oConfig.injectPropertyMixin( "log", shell.getLogBox().getLogger( oConfig) ); + oConfig.injectPropertyMixin( "wirebox", shell.getWireBox() ); + oConfig.injectPropertyMixin( "binder", shell.getWireBox().getBinder() ); + + // Configure the module + oConfig.configure(); + + // title + if( !structKeyExists( oConfig, "title" ) ){ oConfig.title = arguments.moduleName; } + mConfig.title = oConfig.title; + // aliases + if( structKeyExists( oConfig, "aliases" ) ){ + // inflate list to array + if( isSimpleValue( oConfig.aliases ) ){ oConfig.aliases = listToArray( oConfig.aliases ); } + mConfig.aliases = oConfig.aliases; + } + // author + if( !structKeyExists( oConfig, "author" ) ){ oConfig.author = ""; } + mConfig.author = oConfig.author; + // web url + if( !structKeyExists( oConfig, "webURL" ) ){ oConfig.webURL = ""; } + mConfig.webURL = oConfig.webURL; + // description + if( !structKeyExists( oConfig, "description" ) ){ oConfig.description = ""; } + mConfig.description = oConfig.description; + // version + if( !structKeyExists( oConfig, "version" ) ){ oConfig.version = ""; } + mConfig.version = oConfig.version; + // cf mapping + if( structKeyExists( oConfig, "cfmapping" ) ){ + mConfig.cfmapping = oConfig.cfmapping; + } + // model namespace override + if( structKeyExists( oConfig, "modelNamespace" ) ){ + mConfig.modelNamespace = oConfig.modelNamespace; + } + // Auto map models + if( structKeyExists( oConfig, "autoMapModels" ) ){ + mConfig.autoMapModels = oConfig.autoMapModels; + } + // Dependencies + if( structKeyExists( oConfig, "dependencies" ) ){ + // set it always as an array + mConfig.dependencies = isSimpleValue( oConfig.dependencies ) ? listToArray( oConfig.dependencies ) : oConfig.dependencies; + } + // Disabled + mConfig.disabled = false; + if( structKeyExists( oConfig,"disabled" ) ){ + mConfig.disabled = oConfig.disabled; + } + // Activated + mConfig.activate = true; + if( structKeyExists( oConfig,"activate" ) ){ + mConfig.activate = oConfig.activate; + } + + //Get the parent settings + mConfig.parentSettings = oConfig.getPropertyMixin( "parentSettings", "variables", {} ); + //Get the module settings + mConfig.settings = oConfig.getPropertyMixin( "settings", "variables", {} ); + // Override with CommandBox config settings + overrideConfigSettings( mConfig.settings, moduleName ); + + // Register the possible config names with the ConfigService for auto-completion + var possibleConfigSettings = ConfigService.getPossibleConfigSettings(); + for( var settingName in mConfig.settings ) { + possibleConfigSettings.append( 'modules.#moduleName#.#settingName#' ); + } + ConfigService.setPossibleConfigSettings( possibleConfigSettings ); + + //Get Interceptors + mConfig.interceptors = oConfig.getPropertyMixin( "interceptors", "variables", [] ); + for(var x=1; x lte arrayLen( mConfig.interceptors ); x=x+1){ + //Name check + if( NOT structKeyExists(mConfig.interceptors[x],"name" ) ){ + mConfig.interceptors[x].name = listLast(mConfig.interceptors[x].class,"." ); + } + //Properties check + if( NOT structKeyExists(mConfig.interceptors[x],"properties" ) ){ + mConfig.interceptors[x].properties = structnew(); + } + } + + //Get custom interception points + mConfig.interceptorSettings = oConfig.getPropertyMixin( "interceptorSettings","variables",structnew()); + if( NOT structKeyExists(mConfig.interceptorSettings,"customInterceptionPoints" ) ){ + mConfig.interceptorSettings.customInterceptionPoints = ""; + } + + // Get and Append Module conventions + structAppend( mConfig.conventions, oConfig.getPropertyMixin( "conventions", "variables", {} ), true ); + + return oConfig; + + + + + + + + + configSettings = ConfigService.getConfigSettings(); + if( structKeyExists( configSettings, 'modules' ) && structKeyExists( configSettings.modules, arguments.moduleName ) ) { + arguments.moduleSettings.append( configSettings.modules[ arguments.moduleName ] ); + } + + + + + + + for( var moduleName in getLoadedModules() ) { + overrideConfigSettings( getModuleData()[ moduleName ].settings, moduleName ); + } + + + + + + + + + + + var locLen = arrayLen( arguments.locations ); + + for(var x=1; x lte locLen; x++){ + if( len( trim( arguments.locations[ x ] ) ) ){ + // Get all modules found in the module location and append to module registry, only new ones are added + scanModulesDirectory( arguments.locations[ x ] ); + } + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + var excludeModules = ArrayToList( ConfigService.getSetting( "ModulesExclude", [] ) ); + + // If we have excludes and in the excludes + if( len( excludeModules ) and listFindNoCase( excludeModules, arguments.moduleName ) ){ + instance.logger.info( "Module: #arguments.moduleName# excluded from loading." ); + return false; + } + + return true; + + + + diff --git a/src/cfml/system/services/PackageService.cfc b/src/cfml/system/services/PackageService.cfc index c6e92a379..91829cd35 100644 --- a/src/cfml/system/services/PackageService.cfc +++ b/src/cfml/system/services/PackageService.cfc @@ -10,16 +10,18 @@ component accessors="true" singleton { // DI - property name="CR" inject="CR@constants"; - property name="formatterUtil" inject="formatter"; - property name="artifactService" inject="ArtifactService"; - property name="fileSystemUtil" inject="FileSystem"; - property name="pathPatternMatcher" inject="pathPatternMatcher"; + property name='CR' inject='CR@constants'; + property name='formatterUtil' inject='formatter'; + property name='artifactService' inject='ArtifactService'; + property name='fileSystemUtil' inject='FileSystem'; + property name='pathPatternMatcher' inject='pathPatternMatcher'; property name='shell' inject='Shell'; - property name="logger" inject="logbox:logger:{this}"; - property name="semanticVersion" inject="semanticVersion"; - property name="endpointService" inject="EndpointService"; - property name="consoleLogger" inject="logbox:logger:console"; + property name='logger' inject='logbox:logger:{this}'; + property name='semanticVersion' inject='semanticVersion'; + property name='endpointService' inject='EndpointService'; + property name='consoleLogger' inject='logbox:logger:console'; + property name='interceptorService' inject='interceptorService'; + property name='JSONService' inject='JSONService'; /** * Constructor @@ -72,6 +74,8 @@ component accessors="true" singleton { string packagePathRequestingInstallation = arguments.currentWorkingDirectory ){ + interceptorService.announceInterception( 'preInstall', { installArgs=arguments } ); + // If there is a package to install, install it if( len( arguments.ID ) ) { @@ -154,7 +158,7 @@ component accessors="true" singleton { // Modules are the only kind of packages that can be nested in a hierarchy, so the check only applies here. // We're also going to assume that they are in a "modules" folder. // This check also only applies if we're at least one level deep into modules. - if( packageType == 'modules' && currentWorkingDirectory != packagePathRequestingInstallation) { + if( isPackageModule( packageType ) && currentWorkingDirectory != packagePathRequestingInstallation) { // We'll update this variable as we climb back up the directory structure var movingTarget = packagePathRequestingInstallation; @@ -207,10 +211,11 @@ component accessors="true" singleton { // Next, see if the containing project has an install path configured for this dependency already. var containerBoxJSON = readPackageDescriptor( arguments.packagePathRequestingInstallation ); if( !len( installDirectory ) && structKeyExists( containerBoxJSON.installPaths, packageName ) ) { - // Get the resolved intallation path for this package + // Get the resolved installation path for this package installDirectory = fileSystemUtil.resolvePath( containerBoxJSON.installPaths[ packageName ], arguments.packagePathRequestingInstallation ); + // Back up to the "container" folder. The packge directory will be added back below - installDirectory = listDeleteAt( installDirectory, listLen( installDirectory, '/\' ), '/\' ); + installDirectory = listDeleteAt( installDirectory, listLen( installDirectory, '/\' ), '/\' ); } // Else, use directory in the target package's box.json if it exists @@ -245,6 +250,24 @@ component accessors="true" singleton { // If this is a module } else if( packageType == 'modules' ) { installDirectory = arguments.packagePathRequestingInstallation & '/modules'; + // ContentBox Widget + } else if( packageType == 'contentbox-widgets' ) { + installDirectory = arguments.packagePathRequestingInstallation & '/modules/contentbox/widgets'; + // ContentBox themes/layouts + } else if( packageType == 'contentbox-themes' || packageType == 'contentbox-layouts' ) { + installDirectory = arguments.packagePathRequestingInstallation & '/modules/contentbox/themes'; + // ContentBox Modules + } else if( packageType == 'contentbox-modules' ) { + installDirectory = arguments.packagePathRequestingInstallation & '/modules/contentbox/modules_user'; + // CommandBox Modules + } else if( packageType == 'commandbox-modules' ) { + // Override the install directories to the CommandBox CFML root + arguments.currentWorkingDirectory = expandPath( '/commandbox' ); + arguments.packagePathRequestingInstallation = expandPath( '/commandbox' ) + installDirectory = expandPath( '/commandbox/modules' ); + // Flag the shell to reload after this command is finished. + consoleLogger.warn( "Shell will be reloaded after installation." ); + shell.reload( false ); // If this is a plugin } else if( packageType == 'plugins' ) { installDirectory = arguments.packagePathRequestingInstallation & '/plugins'; @@ -427,9 +450,17 @@ component accessors="true" singleton { if( !len( arguments.ID ) && dependencies.isEmpty() ) { consoleLogger.info( "No dependencies found to install, but it's the thought that counts, right?" ); } + + interceptorService.announceInterception( 'postInstall', { installArgs=arguments } ); } + // DRY + function isPackageModule( required string packageType ) { + // Is the package type that of a module? + return ( listFindNoCase( 'modules,contentbox-modules,commandbox-modules', arguments.packageType ) > 0) ; + } + /******************************************************************************************************************/ // If the root of the current package doesn't have a box.json, check if there is a subdirectory that contains @@ -475,6 +506,7 @@ component accessors="true" singleton { required string currentWorkingDirectory ){ + interceptorService.announceInterception( 'preUninstall', { uninstallArgs=arguments } ); consoleLogger.info( '.'); consoleLogger.info( 'Uninstalling package: #arguments.ID#'); @@ -523,7 +555,7 @@ component accessors="true" singleton { // ColdBox modules are stored in a hierachy so just removing the top one removes then all // For all other packages, the depenencies are probably just in the root - if( type != 'modules' ) { + if( !isPackageModule( type ) ) { if( dependencies.count() ) { consoleLogger.debug( "Uninstalling dependencies first..." ); @@ -578,6 +610,7 @@ component accessors="true" singleton { consoleLogger.info( "'#arguments.ID#' has been uninstalled" ); + interceptorService.announceInterception( 'postUninstall', { uninstallArgs=arguments } ); } /** @@ -739,7 +772,7 @@ component accessors="true" singleton { // TODO: Get author info from default CommandBox config // Read the default JSON file and deserialize it. - var boxJSON = DeserializeJSON( fileRead( '/commandBox/templates/box.json.txt' ) ); + var boxJSON = DeserializeJSON( fileRead( '/commandBox/system/config/box.json.txt' ) ); // Replace things passed via parameters boxJSON = boxJSON.append( arguments.defaults ); @@ -774,14 +807,14 @@ component accessors="true" singleton { // ...Read it. boxJSON = fileRead( getDescriptorPath( arguments.directory ) ); - // Validate the file is valid JSOn + // Validate the file is valid JSON if( isJSON( boxJSON ) ) { - // Merge this JSON with defaults return deserializeJSON( boxJSON ); + } else { + consoleLogger.warn( 'Warning: package has an invalid box.json file. [#arguments.directory#]' ); } } - // Just return defaults return {}; } @@ -947,38 +980,10 @@ component accessors="true" singleton { } else { var boxJSON = readPackageDescriptorRaw( arguments.directory ); } - props = addProp( props, '', '', boxJSON ); + props = JSONService.addProp( props, '', '', boxJSON ); } return props; } - // Recursive function to crawl box.json and create a string that represents each property. - private function addProp( props, prop, safeProp, boxJSON ) { - var propValue = ( len( prop ) ? evaluate( 'boxJSON#safeProp#' ) : boxJSON ); - - if( isStruct( propValue ) ) { - // Add all of this struct's keys - for( var thisProp in propValue ) { - var newProp = listAppend( prop, thisProp, '.' ); - var newSafeProp = "#safeProp#['#thisProp#']"; - props.append( newProp ); - props = addProp( props, newProp, newSafeProp, boxJSON ); - } - } - - if( isArray( propValue ) ) { - // Add all of this array's indexes - var i = 0; - while( ++i <= propValue.len() ) { - var newProp = '#prop#[#i#]'; - var newProp = '#safeProp#[#i#]'; - var newSafeProp = newProp; - props.append( newProp ); - props = addProp( props, newProp, newSafeProp, boxJSON ); - } - } - - return props; - } } \ No newline at end of file diff --git a/src/cfml/system/services/ServerService.cfc b/src/cfml/system/services/ServerService.cfc index ffc6e710b..36b0a9d8b 100644 --- a/src/cfml/system/services/ServerService.cfc +++ b/src/cfml/system/services/ServerService.cfc @@ -8,7 +8,7 @@ * I manage servers * */ -component accessors="true" singleton{ +component accessors="true" singleton { /** * Where the server libs are located @@ -35,9 +35,16 @@ component accessors="true" singleton{ */ property name="jarPath"; /** - * The default rewrites configuration file + * Default server settings */ - property name="rewritesDefaultConfig" inject="rewritesDefaultConfig@constants"; + property name="defaultServerJSON"; + + property name='rewritesDefaultConfig' inject='rewritesDefaultConfig@constants'; + property name='interceptorService' inject='interceptorService'; + property name='JSONService' inject='JSONService'; + property name='packageService' inject='packageService'; + property name='consoleLogger' inject='logbox:logger:console'; + property name='wirebox' inject='wirebox'; /** * Constructor @@ -96,131 +103,286 @@ component accessors="true" singleton{ if( !directoryExists( variables.customServerDirectory ) ){ directoryCreate( variables.customServerDirectory ); } - + return this; } + function onDIComplete() { + + setDefaultServerJSON( { + name : '', + openBrowser : true, + stopsocket : 0, + debug : false, + trayicon : '#variables.libdir#/trayicon.png', + jvm : { + heapSize : 512, + args : '' + }, + web : { + host : '127.0.0.1', + directoryBrowsing : true, + webroot : '', + http : { + port : 0, + enable : true + }, + ssl : { + enable : false, + port : 1443, + cert : '', + key : '', + keyPass : '' + }, + rewrites : { + enable : false, + config : variables.rewritesDefaultConfig + } + }, + app : { + logDir : '', + libDirs : '', + webConfigDir : '', + serverConfigDir :variables.serverHomeDirectory, + webXML : '' + }, + runwar : { + args : '' + } + } ); + } + /** * Start a server instance * - * @serverInfo.hint The server information struct: [ webroot, name, port, host, stopSocket, logDir, status, statusInfo, HTTPEnable, SSLEnable, RewritesEnable, RewritesConfig ] - * @openBrowser.hint Open a web browser or not - * @force.hint force start if status is not stopped - * @debug.hint sets debug log level + * @serverProps.hint A struct of settings to influence how to start the server **/ function start( - Struct serverInfo, - Boolean openBrowser, - Boolean force=false, - Boolean debug=false + Struct serverProps ){ - var launchUtil = java.LaunchUtil; + + // Discover by shortname or server and get server info + var serverInfo = getServerInfoByDiscovery( + directory = serverProps.directory, + name = serverProps.name ?: '' + ); + + // Was it found, or new server? + if( structIsEmpty( serverInfo ) ){ + // We need a new entry + serverInfo = getServerInfo( serverProps.directory ); + } + + // Get package descriptor + var boxJSON = packageService.readPackageDescriptor( serverInfo.webroot ); + // Get server descriptor + var serverJSON = readServerJSON( serverInfo.webroot ); + // Get defaults + var defaults = getDefaultServerJSON(); + + // Backwards compat with boxJSON default port. Remove in a future version + // The property in box.json is deprecated. + if( boxJSON.defaultPort > 0 ) { + + // Remove defaultPort from box.json and pretend it was + // manually typed which will cause server.json to save it. + serverProps.port = boxJSON.defaultPort; + + // Update box.json to remove defaultPort from disk + boxJSON.delete( 'defaultPort' ); + packageService.writePackageDescriptor( boxJSON, serverInfo.webroot ); + } - // get webroot info - var webroot = arguments.serverInfo.webroot; - var webhash = hash( arguments.serverInfo.webroot ); + // Save hand-entered properties in our server.json for next time + for( var prop in serverProps ) { + if( !isNull( serverProps[ prop ] ) && prop != 'directory' && prop != 'saveSettings' ) { + switch(prop) { + case "port": + serverJSON[ 'web' ][ 'http' ][ 'port' ] = serverProps[ prop ]; + break; + case "host": + serverJSON[ 'web' ][ 'host' ] = serverProps[ prop ]; + break; + case "stopPort": + serverJSON[ 'stopsocket' ] = serverProps[ prop ]; + break; + case "webConfigDir": + serverJSON[ 'app' ][ 'webConfigDir' ] = serverProps[ prop ]; + break; + case "serverConfigDir": + serverJSON[ 'app' ][ 'serverConfigDir' ] = serverProps[ prop ]; + break; + case "libDirs": + serverJSON[ 'app' ][ 'libDirs' ] = serverProps[ prop ]; + break; + case "webXML": + serverJSON[ 'app' ][ 'webXML' ] = serverProps[ prop ]; + break; + case "HTTPEnable": + serverJSON[ 'web' ][ 'HTTP' ][ 'enable' ] = serverProps[ prop ]; + break; + case "SSLEnable": + serverJSON[ 'web' ][ 'SSL' ][ 'enable' ] = serverProps[ prop ]; + break; + case "SSLPort": + serverJSON[ 'web' ][ 'SSL' ][ 'port' ] = serverProps[ prop ]; + break; + case "SSLCert": + serverJSON[ 'web' ][ 'SSL' ][ 'cert' ] = serverProps[ prop ]; + break; + case "SSLKey": + serverJSON[ 'web' ][ 'SSL' ][ 'key' ] = serverProps[ prop ]; + break; + case "SSLKeyPass": + serverJSON[ 'web' ][ 'SSL' ][ 'keyPass' ] = serverProps[ prop ]; + break; + case "rewritesEnable": + serverJSON[ 'web' ][ 'rewrites' ][ 'enable' ] = serverProps[ prop ]; + break; + case "rewritesConfig": + serverJSON[ 'web' ][ 'rewrites' ][ 'config' ] = serverProps[ prop ]; + break; + case "heapSize": + serverJSON[ 'JVM' ][ 'heapSize' ] = serverProps[ prop ]; + break; + case "JVMArgs": + serverJSON[ 'JVM' ][ 'args' ] = serverProps[ prop ]; + break; + case "runwarArgs": + serverJSON[ 'runwar' ][ 'args' ] = serverProps[ prop ]; + break; + default: + serverJSON[ prop ] = serverProps[ prop ]; + } // end switch + } // end if + } // for loop - // default server name, ports, options - var name = arguments.serverInfo.name is "" ? listLast( webroot, "\/" ) : arguments.serverInfo.name; - var portNumber = arguments.serverInfo.port == 0 ? getRandomPort( arguments.serverInfo.host ) : arguments.serverInfo.port; - var stopPort = arguments.serverInfo.stopsocket == 0 ? getRandomPort( arguments.serverInfo.host ) : arguments.serverInfo.stopsocket; - var HTTPEnable = isNull( arguments.serverInfo.HTTPEnable ) ? true : arguments.serverInfo.HTTPEnable; - var SSLEnable = isNull( arguments.serverInfo.SSLEnable ) ? false : arguments.serverInfo.SSLEnable; - var SSLPort = isNull( arguments.serverInfo.sslPort ) ? 1443 : arguments.serverInfo.sslPort; - var SSLCert = isNull( arguments.serverInfo.sslCert ) ? "" : arguments.serverInfo.sslCert; - var SSLKey = isNull( arguments.serverInfo.sslKey ) ? "" : arguments.serverInfo.sslKey; - var SSLKeyPass = isNull( arguments.serverInfo.sslKeyPass ) ? "" : arguments.serverInfo.sslKeyPass; + if( !serverJSON.isEmpty() && serverProps.saveSettings ) { + saveServerJSON( serverInfo.webroot, serverJSON ); + } + + + // Setup serverinfo according to params + // Hand-entered values take precendence, then settings saved in server.json, and finally defaults. + // The big servers.json is only used to keep a record of the last values the server was started with + serverInfo.debug = serverProps.debug ?: serverJSON.debug ?: defaults.debug; + serverInfo.openbrowser = serverProps.openbrowser ?: serverJSON.openbrowser ?: defaults.openbrowser; + serverInfo.name = serverProps.name ?: listLast( serverInfo.webroot, "\/" ); + serverInfo.host = serverProps.host ?: serverJSON.web.host ?: defaults.web.host; + serverInfo.port = serverProps.port ?: serverJSON.web.http.port ?: getRandomPort( serverInfo.host ); + serverInfo.stopsocket = serverProps.stopsocket ?: serverJSON.stopsocket ?: getRandomPort( serverInfo.host ); + serverInfo.webConfigDir = serverProps.webConfigDir ?: serverJSON.app.webConfigDir ?: getCustomServerFolder( serverInfo ); + serverInfo.serverConfigDir = serverProps.serverConfigDir ?: serverJSON.app.serverConfigDir ?: defaults.app.serverConfigDir; + serverInfo.libDirs = serverProps.libDirs ?: serverJSON.app.libDirs ?: defaults.app.libDirs; + serverInfo.trayIcon = serverProps.trayIcon ?: serverJSON.trayIcon ?: defaults.trayIcon; + serverInfo.webXML = serverProps.webXML ?: serverJSON.app.webXML ?: defaults.app.webXML; + serverInfo.SSLEnable = serverProps.SSLEnable ?: serverJSON.web.SSL.enable ?: defaults.web.SSL.enable; + serverInfo.HTTPEnable = serverProps.HTTPEnable ?: serverJSON.web.HTTP.enable ?: defaults.web.HTTP.enable; + serverInfo.SSLPort = serverProps.SSLPort ?: serverJSON.web.SSL.port ?: defaults.web.SSL.port; + serverInfo.SSLCert = serverProps.SSLCert ?: serverJSON.web.SSL.cert ?: defaults.web.SSL.cert; + serverInfo.SSLKey = serverProps.SSLKey ?: serverJSON.web.SSL.key ?: defaults.web.SSL.key; + serverInfo.SSLKeyPass = serverProps.SSLKeyPass ?: serverJSON.web.SSL.keyPass ?: defaults.web.SSL.keyPass; + serverInfo.rewritesEnable = serverProps.rewritesEnable ?: serverJSON.web.rewrites.enable ?: defaults.web.rewrites.enable; + serverInfo.rewritesConfig = serverProps.rewritesConfig ?: serverJSON.web.rewrites.config ?: defaults.web.rewrites.config; + serverInfo.heapSize = serverProps.heapSize ?: serverJSON.JVM.heapSize ?: defaults.JVM.heapSize; + serverInfo.directoryBrowsing = serverProps.directoryBrowsing ?: serverJSON.web.directoryBrowsing ?: defaults.web.directoryBrowsing; + serverInfo.JVMargs = serverProps.JVMargs ?: serverJSON.JVM.args ?: defaults.JVM.args; + serverInfo.runwarArgs = serverProps.runwarArgs ?: serverJSON.runwar.args ?: defaults.runwar.args; - // setup default tray icon if empty - var trayIcon = len( arguments.serverInfo.trayIcon ) ? arguments.serverInfo.trayIcon : "#variables.libdir#/trayicon.png"; + serverInfo.logdir = serverInfo.webConfigDir & "/log"; + + interceptorService.announceInterception( 'onServerStart', { serverInfo=serverInfo } ); + var launchUtil = java.LaunchUtil; + // Setup lib directory, add more if defined by server info var libDirs = variables.libDir; - if ( Len( Trim( arguments.serverInfo.libDirs ?: "" ) ) ) { - libDirs = ListAppend( libDirs, arguments.serverInfo.libDirs ); + if ( Len( Trim( serverInfo.libDirs ?: "" ) ) ) { + libDirs = ListAppend( libDirs, serverInfo.libDirs ); } - // URL rewriting - var rewritesEnable = isNull( arguments.serverInfo.rewritesEnable ) ? false : arguments.serverInfo.rewritesEnable; - var rewritesConfig = isNull( arguments.serverInfo.rewritesConfig ) ? "" : arguments.serverInfo.rewritesConfig; - - // config directory locations - var configDir = len( arguments.serverInfo.webConfigDir ) ? arguments.serverInfo.webConfigDir : getCustomServerFolder( arguments.serverInfo ); - var serverConfigDir = len( arguments.serverInfo.serverConfigDir ) ? arguments.serverInfo.serverConfigDir : variables.serverHomeDirectory; - // log directory location - var logdir = configdir & "/log"; - if( !directoryExists( logDir ) ){ directoryCreate( logDir ); } + if( !directoryExists( serverInfo.logDir ) ){ directoryCreate( serverInfo.logDir ); } // The process native name - var processName = name is "" ? "CommandBox" : name; + var processName = serverInfo.name is "" ? "CommandBox" : serverInfo.name; // The java arguments to execute: Shared server, custom web configs - var args = " -Xmx#serverInfo.heapSize#m -Xms#serverInfo.heapSize#m" + var args = " #serverInfo.JVMargs# -Xmx#serverInfo.heapSize#m -Xms#serverInfo.heapSize#m" & " -javaagent:""#libdir#/lucee-inst.jar"" -jar ""#variables.jarPath#""" - & " -war ""#webroot#"" --background=true --port #portNumber# --host #arguments.serverInfo.host# --debug #debug#" - & " --stop-port #stopPort# --processname ""#processName#"" --log-dir ""#logdir#""" - & " --open-browser #openbrowser# --open-url http://#arguments.serverInfo.host#:#portNumber#" - & " --cfengine-name lucee --server-name ""#name#"" --lib-dirs ""#libDirs#""" - & " --tray-icon ""#trayIcon#"" --tray-config ""#libdir#/traymenu.json""" - & " --cfml-web-config ""#configdir#"" --cfml-server-config ""#serverConfigDir#"""; + & " -war ""#serverInfo.webroot#"" --background=true --port #serverInfo.port# --host #serverInfo.host# --debug #serverInfo.debug#" + & " --stop-port #serverInfo.stopsocket# --processname ""#processName#"" --log-dir ""#serverInfo.logDir#""" + & " --open-browser #serverInfo.openbrowser# --open-url http://#serverInfo.host#:#serverInfo.port#" + & " --cfengine-name lucee --server-name ""#serverInfo.name#"" --lib-dirs ""#libDirs#""" + & " --tray-icon ""#serverInfo.trayIcon#"" --tray-config ""#libdir#/traymenu.json""" + & " --directoryindex ""#serverInfo.directoryBrowsing#"" --cfml-web-config ""#serverInfo.webConfigDir#""" + & " --cfml-server-config ""#serverInfo.serverConfigDir#"" #serverInfo.runwarArgs# "; // Incorporate SSL to command - if( SSLEnable ){ - args &= " --http-enable #HTTPEnable# --ssl-enable #SSLEnable# --ssl-port #SSLPort#"; + if( serverInfo.SSLEnable ){ + args &= " --http-enable #serverInfo.HTTPEnable# --ssl-enable #serverInfo.SSLEnable# --ssl-port #serverInfo.SSLPort#"; } - if( SSLEnable && SSLCert != "") { - args &= " --ssl-cert ""#SSLCert#"" --ssl-key ""#SSLKey#"" --ssl-keypass ""#SSLKeyPass#"""; + if( serverInfo.SSLEnable && serverInfo.SSLCert != "") { + args &= " --ssl-cert ""#serverInfo.SSLCert#"" --ssl-key ""#serverInfo.SSLKey#"" --ssl-keypass ""#serverInfo.SSLKeyPass#"""; } // Incorporate web-xml to command - if ( Len( Trim( arguments.serverInfo.webXml ?: "" ) ) ) { - args &= " --web-xml-path ""#arguments.serverInfo.webXml#"""; + if ( Len( Trim( serverInfo.webXml ?: "" ) ) ) { + args &= " --web-xml-path ""#serverInfo.webXml#"""; } // Incorporate rewrites to command - args &= " --urlrewrite-enable #rewritesEnable#"; - if( !len( rewritesConfig ) ){ - rewritesConfig = variables.rewritesDefaultConfig; - } - if( rewritesEnable ){ - rewritesConfig = fileSystemUtil.resolvePath( rewritesConfig ); - if( !fileExists(rewritesConfig) ){ - return "URL rewrite config not found #rewritesConfig#"; + args &= " --urlrewrite-enable #serverInfo.rewritesEnable#"; + + if( serverInfo.rewritesEnable ){ + serverInfo.rewritesConfig = fileSystemUtil.resolvePath( serverInfo.rewritesConfig ); + if( !fileExists(serverInfo.rewritesConfig) ){ + return "URL rewrite config not found #serverInfo.rewritesConfig#"; } - args &= " --urlrewrite-file ""#rewritesConfig#"""; + args &= " --urlrewrite-file ""#serverInfo.rewritesConfig#"""; } - - // add back port and log information and persist server information - arguments.serverInfo.port = portNumber; - arguments.serverInfo.stopsocket = stopPort; - arguments.serverInfo.logdir = logdir; - setServerInfo( arguments.serverInfo ); - - // If server is stoped or forced, start it - if( arguments.serverInfo.status == "stopped" || force) { - // change status to starting + persist - arguments.serverInfo.status = "starting"; - setServerInfo( serverInfo ); - // thread the execution - thread name="server#webhash##createUUID()#" serverInfo=arguments.serverInfo args=args { - try{ - // execute the server command - var executeResult = ''; - var executeError = ''; - execute name=variables.javaCommand arguments=attributes.args timeout="50" variable="executeResult" errorVariable="executeError"; - // save server info and persist - arguments.serverInfo.statusInfo = { command:variables.javaCommand, arguments:attributes.args, result:executeResult & ' ' & executeError }; - arguments.serverInfo.status="running"; - setServerInfo( serverInfo ); - } catch (any e) { - logger.error( "Error starting server: #e.message# #e.detail#", arguments ); - arguments.serverInfo.statusInfo.result &= executeResult & ' ' & executeError; - arguments.serverInfo.status="unknown"; - setServerInfo( arguments.serverInfo ); - } + + // Persist server information + setServerInfo( serverInfo ); + + // change status to starting + persist + serverInfo.status = "starting"; + setServerInfo( serverInfo ); + // thread the execution + var threadName = 'server#hash( serverInfo.webroot )##createUUID()#'; + thread name="#threadName#" serverInfo=serverInfo args=args { + try{ + // execute the server command + var executeResult = ''; + var executeError = ''; + // save server info and persist + serverInfo.statusInfo = { command:variables.javaCommand, arguments:attributes.args, result:'' }; + setServerInfo( serverInfo ); + execute name=variables.javaCommand arguments=attributes.args timeout="50" variable="executeResult" errorVariable="executeError"; + serverInfo.status="running"; + } catch (any e) { + logger.error( "Error starting server: #e.message# #e.detail#", arguments ); + serverInfo.statusInfo.result &= e.message & ' ' & e.detail; + serverInfo.status="unknown"; + } finally { + serverInfo.statusInfo.result = serverInfo.statusInfo.result & executeResult & ' ' & executeError; + setServerInfo( serverInfo ); } - return "The server for #webroot# is starting on #arguments.serverInfo.host#:#portNumber#... type 'server status' to see result"; - } else { - return "Cannot start! The server is currently in the #arguments.serverInfo.status# state!#chr(10)#Use force=true or the 'server forget' command "; } + + // She'll be coming 'round the mountain when she comes... + consoleLogger.warn( "The server for #serverInfo.webroot# is starting on #serverInfo.host#:#serverInfo.port#... type 'server status' to see result" ); + + // If this is a one off command, wait for the thread to finish, otherwise the JVM will shutdown before + // the server is started and the json files get updated. + if( shell.getShellType() == 'command' ) { + thread action="join" name="#threadName#"; + + // Pull latest info that was saved in the thread and output it. Since we made the + // user wait for the thread to finish, we might as well tell them what happened. + wirebox.getinstance( name='CommandDSL', initArguments={ name : 'server status' } ) + .params( name = serverInfo.name ) + .run(); + } + + } /** @@ -230,6 +392,9 @@ component accessors="true" singleton{ * @returns struct of [ error, messages ] **/ struct function stop( required struct serverInfo ){ + + interceptorService.announceInterception( 'onServerStop', { serverInfo=serverInfo } ); + var launchUtil = java.LaunchUtil; var stopsocket = arguments.serverInfo.stopsocket; var args = "-jar ""#variables.jarPath#"" -stop --stop-port #val( stopsocket )# -host #arguments.serverInfo.host# --background false"; @@ -259,6 +424,7 @@ component accessors="true" singleton{ if( !arguments.all ){ var servers = getServers(); var serverdir = getCustomServerFolder( arguments.serverInfo ); + var serverJSONPath = arguments.serverInfo.webroot & '/server.json'; // try to delete from config first structDelete( servers, hash( arguments.serverInfo.webroot ) ); @@ -274,6 +440,11 @@ component accessors="true" singleton{ logger.error( '#e.message# #e.detail#' , e.stackTrace ); } } + + // Delete server.json if it exists + if( fileExists( serverJSONPath ) ) { + fileDelete( serverJSONPath ); + } // return message return "Poof! Wiped out server " & serverInfo.name; } else { @@ -485,8 +656,50 @@ component accessors="true" singleton{ SSLKeyPass : "", rewritesEnable : false, rewritesConfig : "", - heapSize : 512 + heapSize : 512, + directoryBrowsing : true, + JVMargs : "", + runwarArgs : "" }; } + /** + * Read a server.json file. If it doesn't exist, returns an empty struct + * This only returns properties specifically set in the file. + */ + struct function readServerJSON( required string directory ) { + var filePath = arguments.directory & '/server.json'; + if( fileExists( filePath ) ) { + return deserializeJSON( fileRead( filePath ) ); + } else { + return {}; + } + } + + /** + * Save a server.json file. + */ + function saveServerJSON( required string directory, required struct data ) { + var filePath = arguments.directory & '/server.json'; + fileWrite( filePath, formatterUtil.formatJSON( serializeJSON( arguments.data ) ) ); + } + + + /** + * Dynamic completion for property name based on contents of server.json + * @directory.hint web root + * @all.hint Pass false to ONLY suggest existing setting names. True will suggest all possible settings. + */ + function completeProperty( required directory, all=false ) { + // Get all config settings currently set + var props = JSONService.addProp( [], '', '', readServerJSON( arguments.directory ) ); + + // If we want all possible options... + if( arguments.all ) { + // ... Then add them in + props = JSONService.addProp( props, '', '', getDefaultServerJSON() ); + } + + return props; + } } diff --git a/src/cfml/system/util/CommandDSL.cfc b/src/cfml/system/util/CommandDSL.cfc new file mode 100644 index 000000000..64d7007e9 --- /dev/null +++ b/src/cfml/system/util/CommandDSL.cfc @@ -0,0 +1,178 @@ +/** +********************************************************************************* +* Copyright Since 2014 CommandBox by Ortus Solutions, Corp +* www.coldbox.org | www.ortussolutions.com +******************************************************************************** +* @author Brad Wood, Luis Majano +* +* I am a helper object for executing commands via a DSL. Create me and call my +* methods to build up a command chain, then .run() will execute me. +* +* I am a transient and hold state. Do not share me with your friends. +* +*/ +component accessors=true { + + property name='command'; + property name='params'; + property name='piped'; + property name='flags'; + property name='append'; + property name='overwrite'; + + + // DI + property name='parser' inject='parser'; + property name='shell' inject='shell'; + + /** + * Create a new, executable command + * + * @name.hint I am the command to execute + **/ + function init( name ) { + + if( !structKeyExists( arguments, 'name' ) ) { + throw( 'Command name not provided' ); + } + + setCommand( arguments.name ); + setPiped( [] ); + setParams( [] ); + setFlags( [] ); + setAppend( '' ); + setOverwrite( '' ); + return this; + } + + /** + * Add params to the command + **/ + function params() { + + setParams( arguments ); + return this; + } + + /** + * Convert params to named or positional arguments + **/ + private array function processParams() { + var processedParams = []; + if( !arraylen( getParams() ) ) { + return processedParams; + } + + // Positional params + if( isNumeric( listFirst( structKeyList( getParams() ) ) ) ) { + for( var param in getParams() ) { + processedParams.append( '"#parser.escapeArg( getParams()[ param ] )#"' ); + } + // Named params + } else { + for( var param in getParams() ) { + processedParams.append( '#param#="#parser.escapeArg( getParams()[ param ] )#"' ); + } + } + + return processedParams; + } + + /** + * Add flags to the command + **/ + function flags() { + + for( var param in arguments ) { + var thisParam = arguments[ param ]; + getFlags().append( ( thisParam.startsWith( '--' ) ? '' : '--' ) & thisParam ); + } + + return this; + } + + /** + * Append results to file + **/ + function append( required path ) { + setAppend( '"#parser.escapeArg( arguments.path )#"' ); + return this; + } + + /** + * overwrite file with results + **/ + function overwrite( required path ) { + setOverwrite( '"#parser.escapeArg( arguments.path )#"' ); + return this; + } + + /** + * Pipe additional commands + **/ + function pipe( commandDSL ) { + + if( !structKeyExists( arguments, 'commandDSL' ) ) { + throw( 'Please pass a commandDSL to pipe' ); + } + + if( !isObject( arguments.commandDSL ) ) { + throw( 'What you passed to pipe isn''t a commandDSL instance.' ); + } + + getPiped().append( arguments.commandDSL ); + return this; + } + + /** + * Turn this CFC into an array of command tokens + **/ + array function getTokens() { + var tokens = []; + // Break the command name on the spaces + tokens.append( listToArray( getCommand(), ' ' ), true ); + tokens.append( processParams(), true ); + tokens.append( getFlags(), true ); + + if( len( getOverwrite() ) ) { + tokens.append( '>' ); + tokens.append( getOverwrite() ); + } + + if( len( getAppend() ) ) { + tokens.append( '>>' ); + tokens.append( getAppend() ); + } + + for( var piperton in getPiped() ) { + tokens.append( '|' ); + tokens.append( piperton.getTokens(), true ); + } + + return tokens; + } + + /** + * Turn this CFC into a string representation + **/ + string function getCommandString() { + return getTokens().toList( ' ' ); + } + + /** + * Run this command + **/ + string function run( returnOutput=false, string piped, boolean echo=false ) { + + if( arguments.echo ) { + shell.callCommand( 'echo "#parser.escapeArg( getCommandString() )#"' ); + } + + if( structkeyExists( arguments, 'piped' ) ) { + return shell.callCommand( getTokens(), arguments.returnOutput, arguments.piped ); + } else { + return shell.callCommand( getTokens(), arguments.returnOutput ); + } + } + +} \ No newline at end of file diff --git a/src/cfml/system/util/Executor.cfc b/src/cfml/system/util/Executor.cfc index 25e8e4671..65397b9b1 100644 --- a/src/cfml/system/util/Executor.cfc +++ b/src/cfml/system/util/Executor.cfc @@ -12,7 +12,9 @@ */ component { - property name="fileSystemUtil" inject="FileSystem"; + property name="$fileSystemUtil" inject="FileSystem"; + property name="$shell" inject="shell"; + property name="$wirebox" inject="wirebox"; /** * Execute an existing file @@ -20,7 +22,7 @@ component { * @vars.hint Struct of vars to set so the template can access them */ function runFile( required template, struct vars = {} ){ - arguments.template = fileSystemUtil.makePathRelative( template ); + arguments.template = $fileSystemUtil.makePathRelative( template ); // Mix the incoming vars into the "variables" scope. structAppend( variables, vars ); @@ -45,7 +47,7 @@ component { var tmpFileAbsolute = arguments.directory & "/" & tmpFile; // generate cfml command to write to file - var CFMLFileContents = ( arguments.script ? "" & arguments.code & "" : arguments.codearguments.directory ); + var CFMLFileContents = ( arguments.script ? "" & arguments.code & "" : arguments.code ); // write out our cfml command fileWrite( tmpFileAbsolute, CFMLFileContents ); @@ -79,4 +81,8 @@ component { } } + function getInstance(){ + return $wirebox.getInstance( argumentCollection = arguments ); + } + } \ No newline at end of file diff --git a/src/cfml/system/util/ForgeBox.cfc b/src/cfml/system/util/ForgeBox.cfc index cdc350942..e63dfd0f8 100644 --- a/src/cfml/system/util/ForgeBox.cfc +++ b/src/cfml/system/util/ForgeBox.cfc @@ -25,6 +25,7 @@ or just add DEBUG to the root logger + @@ -33,7 +34,7 @@ or just add DEBUG to the root logger - this.ORDER = { + this.ORDER = { POPULAR = "popular", NEW = "new", RECENT = "recent", @@ -47,6 +48,7 @@ or just add DEBUG to the root logger // Setup Properties variables.APIURL = "http://www.coldbox.org/api/forgebox"; + //variables.APIURL = "http://forgebox.stg.ortussolutions.com/api/v1/"; variables.installURL = "http://www.coldbox.org/forgebox/install/"; variables.types = ""; @@ -62,7 +64,7 @@ or just add DEBUG to the root logger var results = ""; // Invoke call - results = makeRequest(resource="types"); + results = makeRequest(resource="json/types"); // error if( results.error ){ @@ -101,7 +103,7 @@ or just add DEBUG to the root logger }; // Invoke call - results = makeRequest(resource="entries",parameters=params); + results = makeRequest(resource="json/entries",parameters=params); // error if( results.error ){ throw( "Error making ForgeBox REST Call", 'forgebox', results.response.messages ); @@ -118,7 +120,7 @@ or just add DEBUG to the root logger var results = ""; // Invoke call - results = makeRequest(resource="entry/#arguments.slug#"); + results = makeRequest(resource="json/entry/#arguments.slug#"); // error if( results.error ){ @@ -136,7 +138,7 @@ or just add DEBUG to the root logger var results = ""; // Invoke call - results = makeRequest(resource="slugcheck/#arguments.slug#"); + results = makeRequest(resource="json/slugcheck/#arguments.slug#"); // error if( results.error ){ @@ -175,7 +177,47 @@ or just add DEBUG to the root logger + + + + /** + * Registers a new user in ForgeBox + */ + function register( + required string username, + required string password, + required string email, + required string fName, + required string lName ) { + + var results = makeRequest( resource="register", parameters=arguments, method='post' ); + + // error + if( results.error ){ + throw( "Sorry, the user could not be added.", 'forgebox', arrayToList( results.response.messages ) ); + } + + return results.response.data; + } + /** + * Authenticates a user in ForgeBox + */ + function login( + required string username, + required string password ) { + + var results = makeRequest( resource="authenticate", parameters=arguments, method='post' ); + + // error + if( results.error ){ + throw( "Sorry, the user could not be logged in.", 'forgebox', arrayToList( results.response.messages ) ); + } + + return results.response.data; + } + + @@ -191,6 +233,7 @@ or just add DEBUG to the root logger var HTTPResults = ""; var param = ""; var jsonRegex = "^(\{|\[)(.)*(\}|\])$"; + var APIURL = configService.getSetting( 'endpoints.forgebox.APIURL', getAPIURL() ); // Default Content Type if( NOT structKeyExists(arguments.headers,"content-type") ){ @@ -200,7 +243,7 @@ or just add DEBUG to the root logger diff --git a/src/cfml/system/util/Parser.cfc b/src/cfml/system/util/Parser.cfc index d86f20315..26eca509a 100644 --- a/src/cfml/system/util/Parser.cfc +++ b/src/cfml/system/util/Parser.cfc @@ -104,7 +104,7 @@ component { } // We're starting a quoted string - if( ( char == '"' || char == "'" ) && !isEscaped ) { + if( ( char == '"' || char == "'" || char == "`" ) && !isEscaped ) { inQuotes = true; quoteChar = char; } @@ -177,6 +177,9 @@ component { // Unwrap quotes from value if used value = unwrapQuotes( value ); + // Mark expressions now while escaped chars are removed + value = markExpressions( value ); + name = replaceEscapedChars( name ); value = replaceEscapedChars( value ); @@ -186,6 +189,10 @@ component { } else { // Unwrap quotes from value if used param = unwrapQuotes( param ); + + // Mark expressions now while escaped chars are removed + param = markExpressions( param ); + param = replaceEscapedChars( param ); results.positionalParameters.append( param ); } @@ -196,11 +203,19 @@ component { } + /** + * Find any strings encased in backticks and flags them as a CommandBox expression + */ + function markExpressions( required argValue ) { + return reReplaceNoCase( argValue, '`(.*?)`', '__expression__\1__expression__', 'all' ); + } + /** * Escapes a value and for inclusion in a command * The following replacements are made: * " --> \" * ' --> \' + * ` --> \` * = --> \= * [line break] --> \n * [tab] --> \t @@ -209,6 +224,7 @@ component { arguments.argValue = replace( arguments.argValue, '\', "\\", "all" ); arguments.argValue = replace( arguments.argValue, '"', '\"', 'all' ); arguments.argValue = replace( arguments.argValue, "'", "\'", "all" ); + arguments.argValue = replace( arguments.argValue, "`", "\`", "all" ); arguments.argValue = replace( arguments.argValue, "=", "\=", "all" ); arguments.argValue = replace( arguments.argValue, CR, "\n", "all" ); arguments.argValue = replace( arguments.argValue, chr( 9 ), "\t", "all" ); @@ -218,7 +234,9 @@ component { // ----------------------------- Private --------------------------------------------- private function unwrapQuotes( theString ) { - if( left( theString, 1 ) == '"' or left( theString, 1 ) == "'") { + // If the value is wrapped with backticks, leave them be. That is a signal to the CommandService + // that the string is special and needs to be evaluated as an expression. + if( left( theString, 1 ) == '"' || left( theString, 1 ) == "'" ) { return mid( theString, 2, len( theString ) - 2 ); } return theString; @@ -228,6 +246,7 @@ component { theString = replaceNoCase( theString, "\\", '__backSlash__', "all" ); theString = replaceNoCase( theString, "\'", '__singleQuote__', "all" ); theString = replaceNoCase( theString, '\"', '__doubleQuote__', "all" ); + theString = replaceNoCase( theString, '\`', '__backtick__', "all" ); theString = replaceNoCase( theString, '\n', '__newLine__', "all" ); theString = replaceNoCase( theString, '\t', '__tab__', "all" ); return replaceNoCase( theString, '\=', '__equalSign__', "all" ); @@ -237,6 +256,7 @@ component { theString = replaceNoCase( theString, '__backSlash__', "\", "all" ); theString = replaceNoCase( theString, '__singleQuote__', "'", "all" ); theString = replaceNoCase( theString, '__doubleQuote__', '"', "all" ); + theString = replaceNoCase( theString, '__backtick__', '`', "all" ); theString = replaceNoCase( theString, '__newLine__', CR, "all" ); theString = replaceNoCase( theString, '__tab__', chr( 9 ), "all" ); return replaceNoCase( theString, '__equalSign__', '=', "all" ); diff --git a/src/cfml/system/util/ProgressableDownloader.cfc b/src/cfml/system/util/ProgressableDownloader.cfc index d9d13e86d..a9b610224 100644 --- a/src/cfml/system/util/ProgressableDownloader.cfc +++ b/src/cfml/system/util/ProgressableDownloader.cfc @@ -10,6 +10,8 @@ */ component singleton { + property name='ConfigService' inject='ConfigService'; + /** * Call me to download a file with a status callback * @downloadURL.hint The remote URL to download @@ -104,7 +106,22 @@ component singleton { outputStream.close(); inputStream.close(); - return '#connection.responseCode# #connection.responseMessage#'; + var returnStruct = { + responseCode = connection.responseCode, + responseMessage = connection.responseMessage, + headers = {} + }; + var headerMapSize = connection.getHeaderFields().size(); + var i = 0; // Skipping the first index on purpose. It's handled in responseCode and responseMessage + while( i++ - + - - + + // instance data - instance = { + instance = { // injector reference injector = arguments.injector, // Binder Reference @@ -40,160 +40,163 @@ Description : // uuid helper uuid = createobject("java", "java.util.UUID"), // mixer util - mixerUtil = createObject("component","wirebox.system.aop.MixerUtil").init() + mixerUtil = createObject("component","wirebox.system.aop.MixerUtil").init() }; - + + // class id code + instance.classID = instance.system.identityHashCode( this ); + // Default Generation Path? if( NOT structKeyExists(instance.properties,"generationPath") ){ instance.properties.generationPath = "/wirebox/system/aop/tmp"; } - + // Class Dictionary Reload if( NOT structKeyExists(instance.properties,"classMatchReload") ){ instance.properties.classMatchReload = false; } - + return this; - - + + - return instance.classMatchDictionary; - + return instance.classMatchDictionary; + - - + + var mapping = arguments.interceptData.mapping; var target = arguments.interceptData.target; var mappingName = ""; var idCode = ""; - + // check if target already mixed, if so just return, nothing else to do or if the mapping is an aspect if( structKeyExists(target,"$wbAOPMixed") OR mapping.isAspect() ){ return; } - + // Setup variables mappingName = lcase( mapping.getName() ); idCode = instance.system.identityHashCode( target ); - + // Check if incoming mapping name is already class matched? if( NOT structKeyExists(instance.classMatchDictionary, mappingName ) ){ // Register this incoming mapping for class aspect matching buildClassMatchDictionary( target, mapping, idCode ); } - - // Now, we check if we have any aspects to apply to this class according to class matchers + + // Now, we check if we have any aspects to apply to this class according to class matchers if( arrayLen( instance.classMatchDictionary[mappingName] ) ){ AOPBuilder(target=target, mapping=mapping, dictionary=instance.classMatchDictionary[mappingName], idCode=idCode); - } - + } + - - + + - + - + - + // check again, double lock if( NOT structKeyExists(instance.classMatchDictionary, mappingName ) ){ - + // Discover matching for the class via all aspect bindings for(x=1; x LTE bindingsLen; x++){ - + // class match? If so, add to dictionary of matched aspects if( aspectBindings[x].classes.matchClass(arguments.target, arguments.mapping) ){ - arrayAppend( matchedAspects, aspectBindings[x] ); + arrayAppend( matchedAspects, aspectBindings[x] ); } - - }// end for discovery - + + }// end for discovery + // Log if( instance.log.canDebug() ){ instance.log.debug("Aspect class matching dictionary built for mapping: #mappingName#, aspects: #matchedAspects.toString()#"); } - + // Store matched dictionary - instance.classMatchDictionary[ mappingName ] = matchedAspects; - - } // end if in dictionary + instance.classMatchDictionary[ mappingName ] = matchedAspects; + + } // end if in dictionary - + - - + + - + - + // check if weaved already - if( structKeyExists(arguments.target,"$wbAOPMixed") ){ return; } - + if( structKeyExists(arguments.target,"$wbAOPMixed") ){ return; } + // decorate target with AOP capabilities decorateAOPTarget(arguments.target,arguments.mapping); - + // Process methods via metadata and apply aspects if they match processTargetMethods(target=arguments.target,mapping=arguments.mapping,metadata=arguments.mapping.getObjectMetadata(),dictionary=arguments.dictionary); - + // finalize AOP arguments.target.$wbAOPMixed = true; - - + + - - - + + + - + var functions = ""; var fncLen = ""; var x = 1; var y = 1; var matchedMethodAspects = ""; - + // check if there are functions, else exit if( NOT structKeyExists(arguments.metadata,"functions") ){ return; } - + // Get Function info functions = arguments.metadata.functions; fncLen = arrayLen(functions); - + for(x=1; x LTE fncLen; x++){ - + // check if function already proxied, if so, skip it if( structKeyExists(arguments.target.$wbAOPTargets, functions[x].name ) ){ continue; } - + // init matched aspects to weave matchedMethodAspects = []; - + // function not proxied yet, let's iterate over aspects and see if we can match for(y=1; y LTE arrayLen(arguments.dictionary); y++){ // does the jointpoint match against aspect methods @@ -203,25 +206,25 @@ Description : if ( instance.log.canDebug() ){ instance.log.debug("Target: (#arguments.mapping.getName()#) Method:(#functions[x].name#) matches aspects #arguments.dictionary[y].aspects.toString()#"); } - } + } } - + // Build the the AOP advisor with the function pointcut and matched aspects? if( arrayLen( matchedMethodAspects ) ){ weaveAdvice(target=arguments.target,mapping=arguments.mapping,jointpoint=functions[x].name,jointPointMD=functions[x],aspects=matchedMethodAspects); } - + } - + // Discover inheritance? Recursion if( structKeyExists(arguments.metadata,"extends") ){ processTargetMethods(arguments.target, arguments.mapping, arguments.metadata.extends, arguments.dictionary); } - + - - - + + + @@ -237,13 +240,13 @@ Description : }; var mappingName = arguments.mapping.getName(); var mdJSON = urlEncodedFormat( serializeJSON( arguments.jointPointMD ) ); - + // MD proxy Defaults fncMD.name = arguments.jointPointMD.name; if( structKeyExists(arguments.jointPointMD,"access") ){ fncMD.access = arguments.jointPointMD.access; } if( structKeyExists(arguments.jointPointMD,"output") ){ fncMD.output = arguments.jointPointMD.output; } if( structKeyExists(arguments.jointPointMD,"returntype") ){ fncMD.returntype = arguments.jointPointMD.returnType; } - + // Create Original Method Proxy Signature if( fncMD.access eq "public" ){ udfOut.append('#lb#'); @@ -258,15 +261,15 @@ Description : target=this, targetName="#mappingName#", targetMapping=this.$wbAOPTargetMapping, - interceptors=this.$wbAOPTargets["#arguments.jointPoint#"].interceptors); + interceptors=this.$wbAOPTargets["#arguments.jointPoint#"].interceptors); // execute and return return invocation.proceed(); - + '); - + try{ - + // Write it out to the generation space instance.mixerUtil.writeAspect( expandedFile, udfOUt.toString() ); // Save jointpoint in method targets alongside the interceptors @@ -276,11 +279,11 @@ Description : // Mix In generated aspect arguments.target.$wbAOPInclude( tmpFile ); // Remove Temp Aspect from disk - instance.mixerUtil.removeAspect( expandedFile ); + instance.mixerUtil.removeAspect( expandedFile ); // debug info if( instance.log.canDebug() ){ instance.log.debug("Target (#mappingName#) weaved with new (#arguments.jointpoint#) method and with the following aspects: #arguments.aspects.toString()#"); - } + } } catch(Any e){ // Remove Stub, just in case. @@ -290,29 +293,29 @@ Description : instance.log.error("Exception mixing in AOP aspect for (#mappingName#): #e.message# #e.detail#", e); } // throw the exception - instance.mixerUtil.throwIt("Exception mixing in AOP aspect for (#mappingName#)",e.message & e.detail & e.stacktrace,"WireBox.aop.Mixer.MixinException"); - } - + throw("Exception mixing in AOP aspect for (#mappingName#)",e.message & e.detail & e.stacktrace,"WireBox.aop.Mixer.MixinException"); + } + - - - + + + var x = 1; var interceptors = []; - + // Get aspects from injector and add to our interceptor array for(x=1; x lte arrayLen(arguments.aspects); x++){ arrayAppend( interceptors, instance.injector.getInstance( arguments.aspects[x] ) ); } - - return interceptors; - + + return interceptors; + - - - + + + @@ -331,8 +334,8 @@ Description : // Log it if possible if( instance.log.canDebug() ){ instance.log.debug("AOP Decoration finalized for Mapping: #arguments.mapping.getName()#"); - } - - - + } + + + \ No newline at end of file diff --git a/src/cfml/system/wirebox/system/aop/MixerUtil.cfc b/src/cfml/system/wirebox/system/aop/MixerUtil.cfc index 79b5fd7a6..b637d7e3c 100644 --- a/src/cfml/system/wirebox/system/aop/MixerUtil.cfc +++ b/src/cfml/system/wirebox/system/aop/MixerUtil.cfc @@ -1,7 +1,7 @@  - + - - + + - return this; - + return this; + - - - + + + @@ -32,56 +32,48 @@ Description : }; - - - + + + - - - + + + - + - - - + + + structDelete(this,arguments.methodName); - structDelete(variables,arguments.methodName); - + structDelete(variables,arguments.methodName); + - + - - - - - - - - - - - + + + - + fileWrite(arguments.genPath, arguments.code); - + - - - + + + - + if( fileExists(arguments.filePath) ){ fileDelete( arguments.filePath ); } - + \ No newline at end of file diff --git a/src/cfml/system/wirebox/system/aop/aspects/CFTransaction.cfc b/src/cfml/system/wirebox/system/aop/aspects/CFTransaction.cfc index bb106d224..0257e581e 100644 --- a/src/cfml/system/wirebox/system/aop/aspects/CFTransaction.cfc +++ b/src/cfml/system/wirebox/system/aop/aspects/CFTransaction.cfc @@ -1,7 +1,7 @@  - - - - - - - - - - variables.configStruct = structnew(); - setconfigStruct(arguments.configStruct); - return this; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - "configStruct.#arguments.key#" = arguments.value; - - - - - - - - - - - \ No newline at end of file diff --git a/src/cfml/system/wirebox/system/core/collections/ScopeStorage.cfc b/src/cfml/system/wirebox/system/core/collections/ScopeStorage.cfc index 93e78b4a7..573156505 100644 --- a/src/cfml/system/wirebox/system/core/collections/ScopeStorage.cfc +++ b/src/cfml/system/wirebox/system/core/collections/ScopeStorage.cfc @@ -1,7 +1,7 @@  + + + - - xmlConverter = createObject("component", "wirebox.system.core.conversion.XMLConverter"); - return this; - + @@ -34,23 +34,23 @@ Description : - - - - + + + + - + - + - + - + @@ -60,12 +60,12 @@ Description : if( len( arguments.jsonCallback ) > 0 ){ results = "#arguments.jsonCallback#(#results#)"; } - + - + @@ -76,10 +76,10 @@ Description : args.rootName = arguments.xmlRootName; if( len( trim( arguments.xmlColumnList ) ) ){ args.columnlist = arguments.xmlColumnList; } // Marshal to xml - results = xmlConverter.toXML(argumentCollection=args); + results = xmlConverter.toXML( argumentCollection=args ); - + @@ -92,34 +92,34 @@ Description : #arguments.data# - + - + - - - + + + - + - + - - - + + + diff --git a/src/cfml/system/wirebox/system/core/conversion/JSON.cfc b/src/cfml/system/wirebox/system/core/conversion/JSON.cfc deleted file mode 100644 index 69d8aa7c9..000000000 --- a/src/cfml/system/wirebox/system/core/conversion/JSON.cfc +++ /dev/null @@ -1,225 +0,0 @@ - - - - - - - - return this; - - - - - - - - - - - - - - - - - - - - - - - - - - - - return isJSON( arguments.data ); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/cfml/system/wirebox/system/core/conversion/ObjectMarshaller.cfc b/src/cfml/system/wirebox/system/core/conversion/ObjectMarshaller.cfc index 8f747f4b4..d667c5271 100644 --- a/src/cfml/system/wirebox/system/core/conversion/ObjectMarshaller.cfc +++ b/src/cfml/system/wirebox/system/core/conversion/ObjectMarshaller.cfc @@ -1,177 +1,97 @@ - - - - - - var engine = ""; - var version = ""; - var CFMLEngine = createObject("component","wirebox.system.core.util.CFMLEngine").init(); - - engine = CFMLEngine.getEngine(); - version = CFMLEngine.getVersion(); - - // Algorithm detection - instance = structnew(); - instance.algorithm = "generic"; - if( engine eq CFMLEngine.RAILO ){ instance.algorithm = "railo"; } - if( engine eq CFMLEngine.ADOBE and version GTE 9 ){ instance.algorithm = "objectSave"; } - - return this; - - - - - - - - var binaryData = ""; - - // Which algorithm to use? - switch(instance.algorithm){ - case "generic" : { - binaryData = serializeGeneric(arguments.target); - break; - } - case "railo" : { - binaryData = serializeRailo(arguments.target); - break; - } - case "objectSave" : { - binaryData = serializeWithObjectSave(arguments.target); - break; - } - } - - // Save to File? - if( structKeyExists(arguments,"filePath") ){ - saveToFile(arguments.filePath,binaryData); - } - - return binaryData; - - - - - - - - - var obj = ""; - - // Read From File? - if( structKeyExists(arguments,"filePath") ){ - arguments.binaryObject = readFile(arguments.filePath); - } - - // Which algorithm to use? - switch(instance.algorithm){ - case "generic" : { - obj = deserializeGeneric(arguments.binaryObject); - break; - } - case "railo" : { - obj = deserializeRailo(arguments.binaryObject); - break; - } - case "objectSave" : { - obj = deserializeWithObjectLoad(arguments.binaryObject); - break; - } - } - - return obj; - - - - - - - - - - - - - - - - - - - - - - - - - - - - // check if string - if( not isBinary(arguments.binaryObject) ){ arguments.binaryObject = toBinary(arguments.binaryObject); } - - return objectLoad(arguments.binaryObject); - - - - - - - - var ByteArrayOutput = CreateObject("java", "java.io.ByteArrayOutputStream").init(); - var ObjectOutput = CreateObject("java", "java.io.ObjectOutputStream").init(ByteArrayOutput); - - // Serialize the incoming object. - ObjectOutput.writeObject(arguments.target); - ObjectOutput.close(); - - return toBase64(ByteArrayOutput.toByteArray()); - - - - - - - - var ByteArrayInput = CreateObject("java", "java.io.ByteArrayInputStream").init(toBinary(arguments.binaryObject)); - var ObjectInput = CreateObject("java", "java.io.ObjectInputStream").init(ByteArrayInput); - var obj = ""; - - obj = ObjectInput.readObject(); - objectInput.close(); - - return obj; - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file +* Allows you to serialize/deserialize objects +*/ +component accessors="true"{ + + /** + * Constructor + */ + function init(){ + return this; + } + + /** + * Serialize an object and optionally save it into a file. + * @target The complex object, such as a query or CFC, that will be serialized. + * @filePath The path of the file in which to save the serialized data. + */ + function serializeObject( required any target, string filePath ){ + var binaryData = serializeWithObjectSave( arguments.target ); + + // Save to File? + if( structKeyExists( arguments,"filePath" ) ){ + fileWrite( arguments.filePath, binaryData ); + } + + return binaryData; + } + + + /** + * Deserialize an object using a binary object or a filepath + * @target The binary object to inflate + * @filePath The location of the file that has the binary object to inflate + */ + function deserializeObject( any binaryObject, string filePath ){ + // Read From File? + if( structKeyExists( arguments,"filePath" ) ){ + arguments.binaryObject = fileRead( arguments.filePath ); + } + + return deserializeWithObjectLoad(arguments.binaryObject); + } + + /** + * Serialize via objectSave() + * @target The complex object, such as a query or CFC, that will be serialized. + */ + function serializeWithObjectSave( any target ){ + return toBase64( objectSave( arguments.target ) ); + } + + /** + * Deserialize via ObjectLoad + * @binaryObject The binary object to inflate + */ + function deserializeWithObjectLoad( any binaryObject ){ + // check if string + if( not isBinary( arguments.binaryObject ) ){ arguments.binaryObject = toBinary( arguments.binaryObject ); } + + return objectLoad( arguments.binaryObject ); + } + + /** + * Serialize via generic Java + * @target The binary object to inflate + */ + function serializeGeneric( any target ){ + var byteArrayOutput = createObject( "java", "java.io.ByteArrayOutputStream").init(); + var objectOutput = createObject( "java", "java.io.ObjectOutputStream").init( byteArrayOutput ); + + // Serialize the incoming object. + objectOutput.writeObject( arguments.target ); + objectOutput.close(); + + return toBase64( byteArrayOutput.toByteArray() ); + } + + /** + * Serialize via generic Java + * @target The binary object to inflate + */ + function deserializeGeneric( any binaryObject ){ + var byteArrayInput = createObject( "java", "java.io.ByteArrayInputStream").init( toBinary( arguments.binaryObject ) ); + var ObjectInput = createObject( "java", "java.io.ObjectInputStream").init( byteArrayInput ); + var obj = ""; + + obj = objectInput.readObject(); + objectInput.close(); + + return obj; + } + +} \ No newline at end of file diff --git a/src/cfml/system/wirebox/system/core/conversion/XMLConverter.cfc b/src/cfml/system/wirebox/system/core/conversion/XMLConverter.cfc index 8a7ba9d03..b7e4911b3 100644 --- a/src/cfml/system/wirebox/system/core/conversion/XMLConverter.cfc +++ b/src/cfml/system/wirebox/system/core/conversion/XMLConverter.cfc @@ -1,9 +1,9 @@  - + @@ -37,7 +37,7 @@ Modifications - + @@ -48,12 +48,12 @@ Modifications var buffer = createObject("java","java.lang.StringBuffer").init(''); - + // Header if( arguments.addHeader ){ buffer.append(''); } - + // Object Check if( isObject(arguments.data) ){ buffer.append( objectToXML(argumentCollection=arguments) ); @@ -75,75 +75,75 @@ Modifications arguments.data = listToArray(arguments.data,arguments.delimiter); buffer.append( arrayToXML(argumentCollection=arguments) ); } - + return buffer.toString(); - + - + var buffer = createObject('java','java.lang.StringBuffer').init(''); - var target = arguments.data; + var target = arguments.data; var x = 1; var dataLen = arrayLen(target); var thisValue = ""; var rootElement = "array"; var itemElement = "item"; - - // Root Name + + // Root Name if( len(arguments.rootName) ){ rootElement = arguments.rootName; } - + //Create Root buffer.append("<#rootElement#>"); - + - + - + - + - + #thisValue#")> - + ")> - + - + - + - + - + ')> @@ -164,14 +164,14 @@ Modifications "> #value#")> - + - + - ")> + ")> - + ")> @@ -189,10 +189,10 @@ Modifications var args = structnew(); var rootElement = "struct"; var objectType = ""; - + // Root Element if( len(arguments.rootName) ){ rootElement = arguments.rootName; } - + // Declare Root if( isObject(arguments.data) ){ rootElement = "object"; @@ -201,7 +201,7 @@ Modifications else{ buffer.append("<#rootElement#>"); } - + // Content for(key in target){ // Null Checks @@ -217,14 +217,14 @@ Modifications } buffer.append("<#lcase(key)#>#thisValue#"); } - + // End Root buffer.append(""); - + return buffer.toString(); - + @@ -238,31 +238,31 @@ Modifications var thisValue = ""; var x = 0; var newValue = ""; - + // Root Element Override if( len(arguments.rootName) ){ rootElement = arguments.rootName; } - + // Declare Root buffer.append('<#rootElement# type="#md.name#">'); - + // if no properties to marshall, then return blank if( structKeyExists(md,"properties") ){ - + // loop over properties for(x=1; x lte ArrayLen(md.properties); x=x+1){ // check the property name exists and if it has a marshal annotation of false - if( structKeyExists(md.properties[x],"name") + if( structKeyExists(md.properties[x],"name") OR NOT structKeyExists(md.properties[x],"marhsal") OR md.properties[x]["marshal"] EQ true ){ thisName = md.properties[x].name; thisValue = evaluate("target.get#thisName#()"); - + // Value Defined? if( not isDefined("thisValue") ){ thisValue = ""; } - + // Translate Value if( NOT isSimpleValue( thisValue ) ){ thisValue = translateValue(arguments, thisValue); @@ -270,18 +270,18 @@ Modifications else{ thisValue = safeText(thisValue,arguments.useCDATA); } - + buffer.append("<#lcase(thisName)#>#thisValue#"); - + }//end if property has a name, else skip - + }// end loop over properties - + }// end if no properties detected - + // End Root buffer.append(""); - + return buffer.toString(); @@ -299,7 +299,7 @@ Modifications return toXML(argumentCollection=newArgs); - + @@ -318,36 +318,36 @@ Modifications var string = arguments.value; - string = replaceNoCase(string,chr(8218),'&##8218;','all'); // � - string = replaceNoCase(string,chr(402),'&##402;','all'); // � - string = replaceNoCase(string,chr(8222),'&##8222;','all'); // � - string = replaceNoCase(string,chr(8230),'&##8230;','all'); // � - string = replaceNoCase(string,chr(8224),'&##8224;','all'); // � - string = replaceNoCase(string,chr(8225),'&##8225;','all'); // � - string = replaceNoCase(string,chr(710),'&##710;','all'); // � - string = replaceNoCase(string,chr(8240),'&##8240;','all'); // � - string = replaceNoCase(string,chr(352),'&##352;','all'); // � - string = replaceNoCase(string,chr(8249),'&##8249;','all'); // � - string = replaceNoCase(string,chr(338),'&##338;','all'); // � - string = replaceNoCase(string,chr(8216),'&##8216;','all'); // � - string = replaceNoCase(string,chr(8217),'&##8217;','all'); // � - string = replaceNoCase(string,chr(8220),'&##8220;','all'); // � - string = replaceNoCase(string,chr(8221),'&##8221;','all'); // � - string = replaceNoCase(string,chr(8226),'&##8226;','all'); // � - string = replaceNoCase(string,chr(8211),'&##8211;','all'); // � - string = replaceNoCase(string,chr(8212),'&##8212;','all'); // � - string = replaceNoCase(string,chr(732),'&##732;','all'); // � - string = replaceNoCase(string,chr(8482),'&##8482;','all'); // � - string = replaceNoCase(string,chr(353),'&##353;','all'); // � - string = replaceNoCase(string,chr(8250),'&##8250;','all'); // � - string = replaceNoCase(string,chr(339),'&##339;','all'); // � - string = replaceNoCase(string,chr(376),'&##376;','all'); // � - string = replaceNoCase(string,chr(376),'&##376;','all'); // � - string = replaceNoCase(string,chr(8364),'&##8364','all'); // � + string = replaceNoCase(string,chr(8218),'&##8218;','all'); // � + string = replaceNoCase(string,chr(402),'&##402;','all'); // � + string = replaceNoCase(string,chr(8222),'&##8222;','all'); // � + string = replaceNoCase(string,chr(8230),'&##8230;','all'); // � + string = replaceNoCase(string,chr(8224),'&##8224;','all'); // � + string = replaceNoCase(string,chr(8225),'&##8225;','all'); // � + string = replaceNoCase(string,chr(710),'&##710;','all'); // � + string = replaceNoCase(string,chr(8240),'&##8240;','all'); // � + string = replaceNoCase(string,chr(352),'&##352;','all'); // � + string = replaceNoCase(string,chr(8249),'&##8249;','all'); // � + string = replaceNoCase(string,chr(338),'&##338;','all'); // � + string = replaceNoCase(string,chr(8216),'&##8216;','all'); // � + string = replaceNoCase(string,chr(8217),'&##8217;','all'); // � + string = replaceNoCase(string,chr(8220),'&##8220;','all'); // � + string = replaceNoCase(string,chr(8221),'&##8221;','all'); // � + string = replaceNoCase(string,chr(8226),'&##8226;','all'); // � + string = replaceNoCase(string,chr(8211),'&##8211;','all'); // � + string = replaceNoCase(string,chr(8212),'&##8212;','all'); // � + string = replaceNoCase(string,chr(732),'&##732;','all'); // � + string = replaceNoCase(string,chr(8482),'&##8482;','all'); // � + string = replaceNoCase(string,chr(353),'&##353;','all'); // � + string = replaceNoCase(string,chr(8250),'&##8250;','all'); // � + string = replaceNoCase(string,chr(339),'&##339;','all'); // � + string = replaceNoCase(string,chr(376),'&##376;','all'); // � + string = replaceNoCase(string,chr(376),'&##376;','all'); // � + string = replaceNoCase(string,chr(8364),'&##8364','all'); // � return string; - + diff --git a/src/cfml/system/wirebox/system/core/dynamic/BeanPopulator.cfc b/src/cfml/system/wirebox/system/core/dynamic/BeanPopulator.cfc index e21585a43..c86aa69c5 100644 --- a/src/cfml/system/wirebox/system/core/dynamic/BeanPopulator.cfc +++ b/src/cfml/system/wirebox/system/core/dynamic/BeanPopulator.cfc @@ -1,7 +1,7 @@  - JSONUtil = createObject("component","wirebox.system.core.conversion.JSON").init(); mixerUtil = createObject("component","wirebox.system.core.dynamic.MixerUtil").init(); return this; @@ -40,7 +39,7 @@ Description : // Inflate JSON - arguments.memento = JSONUtil.decode(arguments.JSONString); + arguments.memento = deserializeJSON( arguments.JSONString ); // populate and return return populateFromStruct(argumentCollection=arguments); @@ -168,7 +167,7 @@ Description : return populateFromStruct(argumentCollection=arguments); - + @@ -198,10 +197,10 @@ Description : newMemento[ trueName ] = arguments.memento[ key ]; } } - + // override memento arguments.memento = newMemento; - + //populate bean and return return populateFromStruct( argumentCollection=arguments ); @@ -284,7 +283,7 @@ Description : // Is property in empty-to-null include list? if( ( len( arguments.nullEmptyInclude ) && listFindNoCase( arguments.nullEmptyInclude, key ) ) ) { nullValue = true; - } + } // Is property in empty-to-null exclude list, or is exclude list "*"? if( ( len( arguments.nullEmptyExclude ) AND listFindNoCase( arguments.nullEmptyExclude, key ) ) ){ nullValue = false; @@ -322,11 +321,11 @@ Description : targetEntityName = getComponentMetaData( relationalMeta[ key ].cfc ).entityName; } catch( any e ) { - getUtil().throwIt(type="BeanPopulator.PopulateBeanException", + throw(type="BeanPopulator.PopulateBeanException", message="Error populating bean #getMetaData(beanInstance).name# relationship of #key#. The component #relationalMeta[ key ].cfc# could not be found.", detail="#e.Detail#
#e.message#
#e.tagContext.toString()#"); } - + } // if targetEntityName was successfully found if( len( targetEntityName) ) { @@ -359,7 +358,7 @@ Description : keyValue = evaluate("item.get#structKeyColumn#()"); } catch( Any e ) { - getUtil().throwIt(type="BeanPopulator.PopulateBeanException", + throw(type="BeanPopulator.PopulateBeanException", message="Error populating bean #getMetaData(beanInstance).name# relationship of #key#. The structKeyColumn #structKeyColumn# could not be resolved.", detail="#e.Detail#
#e.message#
#e.tagContext.toString()#"); } @@ -379,7 +378,7 @@ Description : if( isSimpleValue( propertyValue ) && trim( propertyValue ) != "" ) { propertyValue = EntityLoadByPK( targetEntityName, propertyValue ); } - } + } } // if target entity name found } // Populate the property as a null value @@ -391,7 +390,7 @@ Description : else { evaluate( "beanInstance.set#key#( propertyValue )" ); } - + } // end if setter or scope injection }// end if prop ignored @@ -408,9 +407,9 @@ Description : else{ arguments.keyTypeAsString = propertyValue.getClass().toString(); } - getUtil().throwIt(type="BeanPopulator.PopulateBeanException", - message="Error populating bean #getMetaData(beanInstance).name# with argument #key# of type #arguments.keyTypeAsString#.", - detail="#e.Detail#
#e.message#
#e.tagContext.toString()#"); + throw(type="BeanPopulator.PopulateBeanException", + message="Error populating bean #getMetaData(beanInstance).name# with argument #key# of type #arguments.keyTypeAsString#.", + detail="#e.Detail#
#e.message#
#e.tagContext.toString()#"); }
@@ -426,8 +425,8 @@ Description : for( var i = 1; i <= arrayLen( properties ); i++ ) { var property = properties[ i ]; // if property has a name, a fieldtype, and is not the ID, add to maps - if( structKeyExists( property, "fieldtype" ) && - structKeyExists( property, "name" ) && + if( structKeyExists( property, "fieldtype" ) && + structKeyExists( property, "name" ) && !listFindNoCase( "id,column", property.fieldtype ) ) { meta[ property.name ] = property; } diff --git a/src/cfml/system/wirebox/system/core/dynamic/HTMLHelper.cfc b/src/cfml/system/wirebox/system/core/dynamic/HTMLHelper.cfc new file mode 100644 index 000000000..2c84d5327 --- /dev/null +++ b/src/cfml/system/wirebox/system/core/dynamic/HTMLHelper.cfc @@ -0,0 +1,1758 @@ + + + + + + + + + variables.controller = arguments.controller; + + return this; + + + + + + + + + + + var str = ''; + if( arguments.addToHeader ){ + $htmlhead( str ); + } else { + return str; + } + + + + + + + + + var str = ''; + if( arguments.addToHeader ){ + $htmlhead( str ); + } else { + return str; + } + + + + + + + + + + + var sb = createObject("java","java.lang.StringBuffer").init(''); + var x = 1; + var thisAsset = ""; + var event = controller.getRequestService().getContext(); + var asyncStr = ""; + var deferStr = ""; + + // Global location settings + var jsPath = ""; + var cssPath = ""; + if( settingExists("htmlhelper_js_path") ){ jsPath = getSetting('htmlhelper_js_path'); } + if( settingExists("htmlhelper_css_path") ){ cssPath = getSetting('htmlhelper_css_path'); } + + // Async HTML5 attribute + if( arguments.async ){ asyncStr = " async='async'"; } + // Defer HTML5 attribute + if( arguments.defer ){ deferStr = " defer='defer'"; } + + // request assets storage + event.paramValue(name="cbox_assets",value="",private=true); + + for(x=1; x lte listLen(arguments.asset); x=x+1){ + thisAsset = trim( listGetAt( arguments.asset, x ) ); + // Is asset already loaded + if( NOT listFindNoCase(event.getValue(name="cbox_assets",private=true),thisAsset) ){ + + // Load Asset + if( findNoCase(".js", thisAsset) ){ + sb.append(''); + } + else{ + sb.append(''); + } + + // Store It as Loaded + event.setValue(name="cbox_assets",value=listAppend(event.getValue(name="cbox_assets",private=true),thisAsset),private=true); + } + } + + //Load it + if( arguments.sendToHeader AND len(sb.toString())){ + $htmlhead(sb.toString()); + } + else{ + return sb.toString(); + } + + + + + + + ",arguments.count)> + + + + + + + + + + + + + #arguments.title#"> + + + + + + + + + var buffer = createObject("java","java.lang.StringBuffer").init( "<#arguments.tag#" ); + + // append tag attributes + flattenAttributes( arguments, "tag,content", buffer ).append( '>#arguments.content#' ); + + return buffer.toString(); + + + + + + + + + + var buffer = createObject("java","java.lang.StringBuffer").init("#arguments.text#' ); + + return buffer.toString(); + + + + + + + + + + + + + + + var buffer = createObject( "java", "java.lang.StringBuffer" ).init( "#arguments.text#' ); + + return buffer.toString(); + + + + + + + + + + + + + + + + var buffer = createObject("java","java.lang.StringBuffer").init("'); + + //Load it + if( arguments.sendToHeader AND len(buffer.toString())){ + $htmlhead(buffer.toString()); + } + else{ + return buffer.toString(); + } + + + + + + + + + + + + + + + + + var buffer = createObject("java","java.lang.StringBuffer").init("'); + + return buffer.toString(); + + + + + + + + + + + + + + + + + + + + + + + + + + + var str = createObject("java","java.lang.StringBuffer").init(''); + var attrs = ""; + var key = ""; + + // ID Normalization + normalizeID(arguments); + + // Start Table + str.append(""); + + // Buffer Reference + arguments.buffer = str; + + // Convert Query To Table Body + if( isQuery(arguments.data) ){ + queryToTable(argumentCollection=arguments); + } + // Convert Array to Table Body + else if( isArray(arguments.data) and arrayLen(arguments.data) ){ + + // Check first element for an object, if it is then convert to query + if( isObject(arguments.data[1]) ){ + arguments.data = entityToQuery(arguments.data); + queryToTable(argumentCollection=arguments); + } + else{ + arrayToTable(argumentCollection=arguments); + } + } + + // Finalize table + str.append(""); + + return str.toString(); + + + + + + + + + + + var x = 1; + var buffer = createObject("java","java.lang.StringBuffer").init(""); + var tmpType = ""; + + // prep type + if( arguments.type eq "equiv" ){ arguments.type = "http-equiv"; }; + + // Array of structs or simple value + if( isSimpleValue(arguments.name) ){ + buffer.append(''); + } + + if(isArray(arguments.name)){ + for(x=1; x lte arrayLen(arguments.name); x=x+1 ){ + if( NOT structKeyExists(arguments.name[x], "type") ){ + arguments.name[x].type = "name"; + } + if( arguments.name[x].type eq "equiv" ){ + arguments.name[x].type = "http-equiv"; + } + + buffer.append(''); + } + } + + //Load it + if( arguments.sendToHeader AND len(buffer.toString())){ + $htmlhead(buffer.toString()); + } + else{ + return buffer.toString(); + } + + + + + + + + switch( arguments.type ){ + case 'html5' : { return ''; } + case 'xhtml11' : { return ''; } + case 'xhtml1-strict' : { return ''; } + case 'xhtml1-trans' : { return ''; } + case 'xhtml1-frame' : { return ''; } + case 'html4-strict' : { return ''; } + case 'html4-trans' : { return ''; } + case 'html4-frame' : { return ''; } + } + + + + + + + + + + // Cleanup and slugify the string + var slug = lcase(trim(arguments.str)); + + slug = reReplace(slug,"[^a-z0-9-\s#arguments.allow#]","","all"); + slug = trim ( reReplace(slug,"[\s-]+", " ", "all") ); + slug = reReplace(slug,"\s", "-", "all"); + + // is there a max length restriction + if ( arguments.maxlength ) {slug = left ( slug, arguments.maxlength );} + + return slug; + + + + + + + + + + + + var buffer = createObject("java","java.lang.StringBuffer").init("'); + + return buffer.toString(); + + + + + + + + + + + + + + + + + + var video = createObject("java","java.lang.StringBuffer").init("'); + return video.toString(); + } + + // create source tags + video.append(">"); + for(x=1; x lte arrayLen(arguments.src); x++){ + arguments.src[x] = prepareBaseLink(arguments.noBaseURL, arguments.src[x]); + video.append(''); + } + video.append(""); + + return video.toString(); + + + + + + + + + + + + + + + var audio = createObject("java","java.lang.StringBuffer").init("'); + return audio.toString(); + } + + // create source tags + audio.append(">"); + for(x=1; x lte arrayLen(arguments.src); x++){ + arguments.src[x] = prepareBaseLink(arguments.noBaseURL, arguments.src[x]); + audio.append(''); + } + audio.append(""); + + return audio.toString(); + + + + + + + + + + + var canvas = createObject("java","java.lang.StringBuffer").init(""); + + return canvas.toString(); + + + + + + + + + + + + + + var formBuffer = createObject( "java", "java.lang.StringBuffer" ).init( "" ); + + return formBuffer.toString(); + + + + + + "> + + + + + + + + var buffer = createObject("java","java.lang.StringBuffer").init('"); + + // add Legend? + if( len(arguments.legend) ){ + buffer.append("#arguments.legend#"); + } + + return buffer.toString(); + + + + + + "> + + + + + + + + + + + var buffer = createObject("java","java.lang.StringBuffer").init(''); + + // wrapper? + wrapTag(buffer,arguments.wrapper); + + // get content + if( NOT len(content) ){ arguments.content = makePretty(arguments.field); } + arguments.for = arguments.field; + + // create label tag + buffer.append("#arguments.content#"); + + //wrapper? + wrapTag(buffer,arguments.wrapper,1); + + return buffer.toString(); + + + + + + + + + + + + + + + + + + + + + var buffer = createObject("java","java.lang.StringBuffer").init(''); + + // ID Normalization + normalizeID(arguments); + // group wrapper? + wrapTag(buffer,arguments.groupWrapper); + // label? + if( len(arguments.label) ){ buffer.append( this.label(field=arguments.id,content=arguments.label,wrapper=arguments.labelWrapper,class=arguments.labelClass) ); } + + //wrapper? + wrapTag(buffer,arguments.wrapper); + + // disabled fix + if( arguments.disabled ){ arguments.disabled = "disabled"; } + else{ arguments.disabled = ""; } + // readonly fix + if( arguments.readonly ){ arguments.readonly = "readonly"; } + else{ arguments.readonly = ""; } + + // Entity Binding? + bindValue(arguments); + + // create textarea + buffer.append("#arguments.value#"); + + //wrapper? + wrapTag(buffer,arguments.wrapper,1); + // group wrapper? + wrapTag(buffer,arguments.groupWrapper,1); + return buffer.toString(); + + + + + + + + + + + + + + + + + + arguments.type="password"; + return inputField(argumentCollection=arguments); + + + + + + + + + + + + + + + + + + arguments.type="url"; + return inputField(argumentCollection=arguments); + + + + + + + + + + + + + + + + + + arguments.type="email"; + return inputField(argumentCollection=arguments); + + + + + + + + + + + + + + + + arguments.type="hidden"; + return inputField(argumentCollection=arguments); + + + + + + + + + + + + + + + + + + arguments.type="text"; + return inputField(argumentCollection=arguments); + + + + + + + + + + + + + + + + + var buffer = createObject("java","java.lang.StringBuffer").init(''); + + // ID Normalization + normalizeID(arguments); + // group wrapper? + wrapTag(buffer,arguments.groupWrapper); + // label? + if( len(arguments.label) ){ buffer.append( this.label(field=arguments.id,content=arguments.label,wrapper=arguments.labelWrapper,class=arguments.labelClass) ); } + + //wrapper? + wrapTag(buffer,arguments.wrapper); + + // disabled fix + if( arguments.disabled ){ arguments.disabled = "disabled"; } + else{ arguments.disabled = ""; } + + // create textarea + buffer.append("#arguments.value#"); + + //wrapper? + wrapTag(buffer,arguments.wrapper,1); + // group wrapper? + wrapTag(buffer,arguments.groupWrapper,1); + return buffer.toString(); + + + + + + + + + + + + + + + + arguments.type="file"; + return inputField(argumentCollection=arguments); + + + + + + + + + + + + + + + + + + arguments.type="checkbox"; + return inputField(argumentCollection=arguments); + + + + + + + + + + + + + + + + + + arguments.type="radio"; + return inputField(argumentCollection=arguments); + + + + + + + + + + + + + + + arguments.type="submit"; + return inputField(argumentCollection=arguments); + + + + + + + + + + + + + + + arguments.type="reset"; + return inputField(argumentCollection=arguments); + + + + + + + + + + + + + + + arguments.type="image"; + return inputField(argumentCollection=arguments); + + + + + + + + + + + + var buffer = createObject("java","java.lang.StringBuffer").init(''); + var val = ""; + var nameVal = ""; + var x = 1; + var qColumns = ""; + var thisName = ""; + var thisValue = ""; + + // check if an array? So we can do array of objects check + if( isArray(arguments.values) AND arrayLen(arguments.values) ){ + // Check first element for an object, if it is then convert to query + if( isObject(arguments.values[1]) ){ + arguments.values = entityToQuery(arguments.values); + } + } + // is this a simple value, if so, inflate it + if( isSimpleValue(arguments.values) ){ + arguments.values = listToArray(arguments.values); + } + + // setup local variables + val = arguments.values; + nameVal = arguments.values; + + // query normalization? + if( isQuery(val) ){ + // check if column sent? Else select the first column + if( NOT len(column) ){ + // select the first one + qColumns = listToArray( arguments.values.columnList ); + arguments.column = qColumns[1]; + } + // column for values + val = getColumnArray(arguments.values,arguments.column); + nameVal = val; + // name column values + if( len(arguments.nameColumn) ){ + nameVal = getColumnArray(arguments.values,arguments.nameColumn); + } + } + + // values + for(x=1; x lte arrayLen(val); x++){ + + thisValue = val[x]; + thisName = nameVal[x]; + + // struct normalizing + if( isStruct( val[x] ) ){ + // Default + thisName = thisValue; + + // check for value? + if( structKeyExists(val[x], "value") ){ thisValue = val[x].value; } + if( structKeyExists(val[x], "name") ){ thisName = val[x].name; } + + // Check if we have a column to use for the default value + if( structKeyExists( val[x], arguments.column ) ){ thisValue = val[x][column]; } + + // Do we have name column + if( len( arguments.nameColumn ) ){ + if( structKeyExists( val[x], arguments.nameColumn ) ){ thisName = val[x][nameColumn]; } + } + else{ + if( structKeyExists( val[x], arguments.column ) ){ thisName = val[x][column]; } + } + + } + + // create option + buffer.append('"); + + } + + return buffer.toString(); + + + + + + + + + + + + + + + + + + + + + + + + + + var buffer = createObject("java","java.lang.StringBuffer").init(''); + + // ID Normalization + normalizeID(arguments); + // group wrapper? + wrapTag(buffer,arguments.groupWrapper); + // label? + if( len(arguments.label) ){ buffer.append( this.label(field=arguments.id,content=arguments.label,wrapper=arguments.labelWrapper,class=arguments.labelClass) ); } + + //wrapper? + wrapTag(buffer,arguments.wrapper); + + // disabled fix + if( arguments.disabled ){ arguments.disabled = "disabled"; } + else{ arguments.disabled = ""; } + // multiple fix + if( arguments.multiple ){ arguments.multiple = "multiple"; } + else{ arguments.multiple = ""; } + + // create select + buffer.append(""); + + // binding of option + bindValue(arguments); + if( structKeyExists(arguments,"value") AND len(arguments.value) ){ + arguments.selectedValue = arguments.value; + } + + // options, are they inflatted already or do we inflate + if( isSimpleValue(arguments.options) AND findnocase("",arguments.options) ){ + buffer.append( arguments.options ); + } + else{ + buffer.append( this.options(arguments.options,arguments.column,arguments.nameColumn,arguments.selectedIndex,arguments.selectedValue) ); + } + + // finalize select + buffer.append(""); + + //wrapper? + wrapTag(buffer,arguments.wrapper,1); + // group wrapper? + wrapTag(buffer,arguments.groupWrapper, 1); + + return buffer.toString(); + + + + + + + + + + + + + + + + + + + + + var buffer = createObject( "java", "java.lang.StringBuffer" ).init( '' ); + var excludeList = "label,wrapper,labelWrapper,groupWrapper,labelClass,bind,bindProperty"; + + // ID Normalization + normalizeID( arguments ); + // group wrapper? + wrapTag( buffer, arguments.groupWrapper ); + // label? + if( len( arguments.label ) ){ buffer.append( this.label( field=arguments.id, content=arguments.label, wrapper=arguments.labelWrapper, class=arguments.labelClass ) ); } + //wrapper? + wrapTag( buffer, arguments.wrapper ); + + // disabled fix + if( arguments.disabled ){ arguments.disabled = "disabled"; } + else{ arguments.disabled = ""; } + // checked fix + if( arguments.checked ){ arguments.checked = "checked"; } + else{ arguments.checked = ""; } + // readonly fix + if( arguments.readonly ){ arguments.readonly = "readonly"; } + else{ arguments.readonly = ""; } + + // binding? + bindValue( arguments ); + + // create textarea + buffer.append("" ); + + //wrapper? + wrapTag( buffer, arguments.wrapper, 1 ); + // group wrapper? + wrapTag( buffer, arguments.groupWrapper, 1 ); + + return buffer.toString(); + + + + + + + + + + + + + + + + + var buffer = createObject("java","java.lang.StringBuffer").init(''); + var md = getMetadata( arguments.entity ); + var x = 1; + var y = 1; + var prop = ""; + var args = {}; + var loc = {}; + + // if no properties just return. + if( NOT structKeyExists(md,"properties") ){ return ""; } + + // iterate properties array + for(x=1; x lte arrayLen(md.properties); x++ ){ + prop = md.properties[x]; + + // setup some defaults + loc.persistent = true; + loc.ormtype = "string"; + loc.fieldType = "column"; + loc.insert = true; + loc.update = true; + loc.formula = ""; + loc.readonly = false; + if( structKeyExists(prop,"persistent") ){ loc.persistent = prop.persistent; } + if( structKeyExists(prop,"ormtype") ){ loc.ormtype = prop.ormtype; } + if( structKeyExists(prop,"fieldType") ){ loc.fieldType = prop.fieldType; } + if( structKeyExists(prop,"insert") ){ loc.insert = prop.insert; } + if( structKeyExists(prop,"update") ){ loc.update = prop.update; } + if( structKeyExists(prop,"formula") ){ loc.formula = prop.formula; } + if( structKeyExists(prop,"readonly") ){ loc.readonly = prop.readonly; } + + // html 5 data items + arguments["data-ormtype"] = loc.ormtype; + arguments["data-insert"] = loc.insert; + arguments["data-update"] = loc.update; + + // continue on non-persistent ones or formulas or readonly + loc.orm = ORMGetSession(); + if( NOT loc.persistent OR len(loc.formula) OR loc.readOnly OR + ( loc.orm.contains(arguments.entity) AND NOT loc.update ) OR + ( NOT loc.orm.contains(arguments.entity) AND NOT loc.insert ) + ){ continue; } + + switch(loc.fieldType){ + //primary key as hidden field + case "id" : { + args = { + name=prop.name,bind=arguments.entity + }; + buffer.append( hiddenField(argumentCollection=args) ); + break; + } + case "many-to-many" : { + // prepare lookup args + loc.criteria = {}; + loc.sortorder = ""; + loc.column = ""; + loc.nameColumn = ""; + loc.selectColumn = ""; + loc.values = []; + loc.relArray = []; + arguments["data-ormtype"] = "many-to-many"; + + // is key found in manytoone arg + if( structKeyExists(arguments.manytomany, prop.name) ){ + if( structKeyExists(arguments.manytomany[prop.name],"valueColumn") ){ loc.column = arguments.manytomany[prop.name].valueColumn; } + else{ + throw(message="The 'valueColumn' property is missing from the '#prop.name#' relationship data, which is mandatory", + detail="A structure of data to help with many to one relationships on how they are presented. Possible key values for each key are [valuecolumn='',namecolumn='',criteria={},sortorder=string,selectColumn='']. Example: {criteria={productid=1},sortorder='Department desc'}", + type="EntityFieldsInvalidRelationData"); + } + if( structKeyExists(arguments.manytomany[prop.name],"nameColumn") ){ loc.nameColumn = arguments.manytomany[prop.name].nameColumn; } + else{ + loc.nameColumn = arguments.manytomany[prop.name].valueColumn; + } + if( structKeyExists(arguments.manytomany[prop.name],"criteria") ){ loc.criteria = arguments.manytomany[prop.name].criteria; } + if( structKeyExists(arguments.manytomany[prop.name],"sortorder") ){ loc.sortorder = arguments.manytomany[prop.name].sortorder; } + if( structKeyExists(arguments.manytomany[prop.name],"selectColumn") ){ loc.selectColumn = arguments.manytomany[prop.name].selectColumn; } + } + else{ + throw(message="There is no many to many information for the '#prop.name#' relationship in the entityFields() arguments. Please make sure you create one", + detail="A structure of data to help with many to one relationships on how they are presented. Possible key values for each key are [valuecolumn='',namecolumn='',criteria={},sortorder=string,selectColumn='']. Example: {criteria={productid=1},sortorder='Department desc'}", + type="EntityFieldsInvalidRelationData"); + } + + // values should be an array of objects, so let's convert them + loc.relArray = evaluate("arguments.entity.get#prop.name#()"); + if( isNull(loc.relArray) ){ loc.relArray = []; } + if( NOT len(loc.selectColumn) AND arrayLen(loc.relArray) ){ + // if select column is empty, then select first property as select value, not perfect but hey better than nothing + loc.selectColumn = getMetadata( loc.relArray[1] ).properties[1].name; + } + // iterate and select + for(y=1; y lte arrayLen(loc.relArray); y++){ + arrayAppend(loc.values, evaluate("loc.relArray[y].get#loc.selectColumn#()") ); + } + // generation args + args = { + name=prop.name, options=entityLoad( prop.cfc, loc.criteria, loc.sortorder ), column=loc.column, nameColumn=loc.nameColumn, + multiple=true, label=prop.name, labelwrapper=arguments.labelWrapper, labelClass=arguments.labelClass, wrapper=arguments.fieldwrapper, + groupWrapper=arguments.groupWrapper, selectedValue=arrayToList( loc.values ) + }; + structAppend(args,arguments); + buffer.append( this.select(argumentCollection=args) ); + break; + } + // one to many display + case "one-to-many" : { + loc.orm = ORMGetSession(); + // A new or persisted entity? If new, then skip out + if( NOT loc.orm.contains(arguments.entity) OR NOT arguments.showRelations){ + break; + } + arguments["data-ormtype"] = "one-to-many"; + // We just show them as a nice table because we are not scaffolding, just display + // values should be an array of objects, so let's convert them + loc.relArray = evaluate("arguments.entity.get#prop.name#()"); + if( isNull(loc.relArray) ){ loc.relArray = []; } + + // Label Generation + args = { + field=prop.name, wrapper=arguments.labelWrapper, class=arguments.labelClass + }; + structAppend(args,arguments); + buffer.append( this.label(argumentCollection=args) ); + + // Table Generation + if( arrayLen(loc.relArray) ){ + args = { + name=prop.name, data=loc.relArray + }; + structAppend(args,arguments); + buffer.append( this.table(argumentCollection=args) ); + } + else{ + buffer.append("

None Found

"); + } + + break; + } + // one to many display + case "one-to-one" : { + loc.orm = ORMGetSession(); + // A new or persisted entity? If new, then skip out + if( NOT loc.orm.contains(arguments.entity) OR NOT arguments.showRelations){ + break; + } + + arguments["data-ormtype"] = "one-to-one"; + // We just show them as a nice table because we are not scaffolding, just display + // values should be an array of objects, so let's convert them + loc.data = evaluate("arguments.entity.get#prop.name#()"); + if( isNull(loc.data) ){ loc.relArray = []; } + else{ loc.relArray = [ loc.data ]; } + + // Label Generation + args = { + field=prop.name, wrapper=arguments.labelWrapper, class=arguments.labelClass + }; + structAppend(args,arguments); + buffer.append( this.label(argumentCollection=args) ); + + // Table Generation + if( arrayLen(loc.relArray) ){ + args = { + name=prop.name, data=loc.relArray + }; + structAppend(args,arguments); + buffer.append( this.table(argumentCollection=args) ); + } + else{ + buffer.append("

None Found

"); + } + break; + } + // many to one + case "many-to-one" : { + arguments["data-ormtype"] = "many-to-one"; + // prepare lookup args + loc.criteria = {}; + loc.sortorder = ""; + loc.column = ""; + loc.nameColumn = ""; + // is key found in manytoone arg + if( structKeyExists(arguments.manytoone, prop.name) ){ + // Verify the valueColumn which is mandatory + if( structKeyExists(arguments.manytoone[prop.name],"valueColumn") ){ loc.column = arguments.manytoone[prop.name].valueColumn; } + else{ + throw(message="The 'valueColumn' property is missing from the '#prop.name#' relationship data, which is mandatory", + detail="A structure of data to help with many to one relationships on how they are presented. Possible key values for each key are [valuecolumn='',namecolumn='',criteria={},sortorder=string]. Example: {criteria={productid=1},sortorder='Department desc'}", + type="EntityFieldsInvalidRelationData"); + } + if( structKeyExists(arguments.manytoone[prop.name],"nameColumn") ){ loc.nameColumn = arguments.manytoone[prop.name].nameColumn; } + else { loc.nameColumn = arguments.manytoone[prop.name].valueColumn; } + if( structKeyExists(arguments.manytoone[prop.name],"criteria") ){ loc.criteria = arguments.manytoone[prop.name].criteria; } + if( structKeyExists(arguments.manytoone[prop.name],"sortorder") ){ loc.sortorder = arguments.manytoone[prop.name].sortorder; } + } + else{ + throw(message="There is no many to one information for the '#prop.name#' relationship in the entityFields() arguments. Please make sure you create one", + detail="A structure of data to help with many to one relationships on how they are presented. Possible key values for each key are [valuecolumn='',namecolumn='',criteria={},sortorder=string]. Example: {criteria={productid=1},sortorder='Department desc'}", + type="EntityFieldsInvalidRelationData"); + } + // generation args + args = { + name=prop.name, options=entityLoad( prop.cfc, loc.criteria, loc.sortorder ), + column=loc.column, nameColumn=loc.nameColumn, + label=prop.name, bind=arguments.entity, labelwrapper=arguments.labelWrapper, labelClass=arguments.labelClass, + wrapper=arguments.fieldwrapper, groupWrapper=arguments.groupWrapper + }; + structAppend(args,arguments); + buffer.append( this.select(argumentCollection=args) ); + break; + } + // columns + case "column" : { + + // booleans? + if( structKeyExists(prop,"ormtype") and prop.ormtype eq "boolean"){ + // boolean select or radio buttons + if( arguments.booleanSelect ){ + args = { + name=prop.name, options=[true,false], label=prop.name, bind=arguments.entity, labelwrapper=arguments.labelWrapper, labelClass=arguments.labelClass, + wrapper=arguments.fieldwrapper, groupWrapper=arguments.groupWrapper + }; + structAppend(args,arguments); + buffer.append( this.select(argumentCollection=args) ); + } + else{ + args = { + name=prop.name, value="true", label="True", bind=arguments.entity, labelwrapper=arguments.labelWrapper, labelClass=arguments.labelClass, + groupWrapper=arguments.groupWrapper, wrapper=arguments.fieldWrapper + }; + structAppend(args,arguments); + buffer.append( this.radioButton(argumentCollection=args) ); + args.value="false"; + args.label="false"; + buffer.append( this.radioButton(argumentCollection=args) ); + } + continue; + } + // text args + args = { + name=prop.name, label=prop.name, bind=arguments.entity, labelwrapper=arguments.labelWrapper, labelClass=arguments.labelClass, + wrapper=arguments.fieldwrapper, groupWrapper=arguments.groupWrapper + }; + structAppend(args,arguments); + // text and textarea fields + if( len(arguments.textareas) AND listFindNoCase(arguments.textareas, prop.name) ){ + buffer.append( this.textarea(argumentCollection=args) ); + } + else{ + buffer.append( this.textfield(argumentCollection=args) ); + } + }// end case column + + }// end switch + + }// end for loop + + return buffer.toString(); +
+
+ + + + + + + + + + + var str = arguments.buffer; + var attrs = ""; + var x = 1; + var y = 1; + var key = ""; + var cols = structKeyArray( data[ 1 ] ); + + // Render Headers + for(x=1; x lte arrayLen(cols); x=x+1){ + // Display? + if( passIncludeExclude(cols[x],arguments.includes,arguments.excludes) ){ + str.append("#cols[x]#"); + } + } + str.append(""); + + // Render Body + str.append(""); + for(x=1; x lte arrayLen(arguments.data); x=x+1){ + str.append(""); + for(y=1; y lte arrayLen(cols); y=y+1){ + // Display? + if( passIncludeExclude(cols[y],arguments.includes,arguments.excludes) ){ + str.append("#arguments.data[x][cols[y]]#"); + } + } + str.append(""); + } + + + + + + + + + + + var str = arguments.buffer; + var cols = listToArray(arguments.data.columnList); + var x = 1; + var y = 1; + + // Render Headers + for(x=1; x lte arrayLen(cols); x=x+1){ + // Display? + if( passIncludeExclude(cols[x],arguments.includes,arguments.excludes) ){ + str.append("#cols[x]#"); + } + } + str.append(""); + + // Render Body + str.append(""); + for(x=1; x lte arguments.data.recordcount; x=x+1){ + str.append(""); + for(y=1; y lte arrayLen(cols); y=y+1){ + // Display? + if( passIncludeExclude(cols[y],arguments.includes,arguments.excludes) ){ + str.append("#arguments.data[cols[y]][x]#"); + } + } + str.append(""); + } + + + + + + + + + + + var val = arguments.values; + var x = 1; + var str = createObject("java","java.lang.StringBuffer").init(""); + var br = chr(13); + var args = ""; + + // list or array or query? + if( isSimpleValue(val) ){ val = listToArray(val); } + if( isQuery(val) ){ val = getColumnArray(val,arguments.column); } + + // start tag + str.append("<#arguments.tag#"); + // flatten extra attributes via arguments + flattenAttributes(arguments,"tag,values,column",str).append(">"); + + // values + for(x=1; x lte arrayLen(val); x=x+1){ + + if( isArray(val[x]) ){ + str.append( toHTMLList(arguments.tag,val[x],arguments.column) ); + } + else{ + str.append("
  • #val[x]#
  • "); + } + + } + + str.append(""); + return str.toString(); +
    +
    + + + + + + var entityValue = ""; + + // binding? + if( isObject( arguments.args.bind ) ){ + // do we have a bindProperty, else default it from the name + if( NOT len( arguments.args.bindProperty ) ){ + + // check if name exists else throw exception + if( NOT structKeyExists( arguments.args, "name" ) OR NOT len( arguments.args.name ) ){ + throw( type="HTMLHelper.NameBindingException", message="The 'name' argument was not passed and not binding property was passed, so we can't bind dude!" ); + } + + // bind name property + arguments.args.bindProperty = arguments.args.name; + } + + // entity value + entityValue = evaluate( "arguments.args.bind.get#arguments.args.bindProperty#()" ); + if( isNull( entityValue ) ){ entityValue = ""; } + // Verify if the value is an entity, if it is, then use the 'column' to retrieve the value + if( isObject( entityValue ) ){ entityValue = evaluate( "entityValue.get#arguments.args.column#()" ); } + + // If radio or checkbox button, check it + if( structKeyExists( arguments.args, "type" ) AND listFindNoCase( "radio,checkbox", arguments.args.type ) ){ + // is incoming value eq to property value with boolean aspects + if( structKeyExists( arguments.args, "value" ) and + isBoolean( arguments.args.value ) and + yesNoFormat( arguments.args.value ) EQ yesNoFormat( entityValue ) ){ + arguments.args.checked = true; + } + // else with no boolean evals + else if( structKeyExists( arguments.args, "value" ) and arguments.args.value EQ entityValue ){ + arguments.args.checked = true; + } + } + else{ + // If there is no incoming value, then bind it + arguments.args.value = entityValue; + } + } + + + + + + + + if( structKeyExists(arguments.args,"name") AND len(arguments.args.name) AND NOT structKeyExists(arguments.args,"id") ){ + arguments.args.id = arguments.args.name; + } + + + + + + + + + + var slash = ""; + if( len( arguments.tag ) ){ + if( arguments.end ){ slash = "/"; } + arguments.buffer.append("<#slash##arguments.tag#>"); + } + + + + + + + + return ucase( left( arguments.text, 1 ) ) & removeChars( lcase( replace( arguments.text, "_", " ") ), 1, 1 ); + + + + + + + + + var baseURL = replacenocase( controller.getRequestService().getContext().getSESbaseURL() ,"index.cfm",""); + // return if base is eempty + if( NOT len(baseURL) ){ return arguments.src; } + + // Check if we have a base URL + if( arguments.noBaseURL eq FALSE and NOT find("://",arguments.src)){ + arguments.src = baseURL & "/" & arguments.src; + } + return arguments.src; + + + + + + + + + + var disp = true; + // Include List? + if( len(arguments.includes) AND NOT listFindNoCase(arguments.includes,arguments.value) ){ + disp = false; + } + // Exclude List? + if( len(arguments.excludes) AND listFindNoCase(arguments.excludes,arguments.value) ){ + disp = false; + } + return disp; + + + + + + + + + + var key = ""; + var datakey = ""; + + // global exclusions + arguments.excludes &= ",fieldWrapper,labelWrapper,entity,booleanSelect,textareas,manytoone,onetomany,sendToHeader,bind"; + + for(key in arguments.target){ + // Excludes + if( len( arguments.excludes ) AND listFindNoCase( arguments.excludes, key ) ){ + continue; + } + // Normal Keys + if( structKeyExists( arguments.target, key ) AND isSimpleValue( arguments.target[ key ] ) AND len( arguments.target[ key ] ) ){ + arguments.buffer.append(' #lcase( key )#="#HTMLEditFormat( arguments.target[ key ] )#"'); + } + // data keys + if( isStruct( arguments.target[ key ] ) ){ + for( dataKey in arguments.target[ key ] ){ + if( isSimplevalue( arguments.target[ key ][ dataKey ] ) AND len( arguments.target[ key ][ dataKey ] ) ){ + arguments.buffer.append(' #lcase( key )#-#lcase( dataKey )#="#HTMLEditFormat( arguments.target[ key ][ datakey ] )#"'); + } + } + } + + } + + return arguments.buffer; + + + + + + + + + + + + + + + + + + + + + + + + + + + var arValues = []; + + if( arguments.qry.recordcount ){ + for( var i = 1; i LTE arguments.qry.recordcount; i++){ + ArrayAppend( arValues, arguments.qry[ arguments.columnName ][ i ] ); + } + } + + return arValues; + + + + + + + + + +
    \ No newline at end of file diff --git a/src/cfml/system/wirebox/system/core/dynamic/MixerUtil.cfc b/src/cfml/system/wirebox/system/core/dynamic/MixerUtil.cfc index c9c426f34..42d82eaae 100644 --- a/src/cfml/system/wirebox/system/core/dynamic/MixerUtil.cfc +++ b/src/cfml/system/wirebox/system/core/dynamic/MixerUtil.cfc @@ -1,7 +1,7 @@  - + - + // get new name if( !len( arguments.newName ) ){ arguments.newName = arguments.method; } - // expose it - this[ arguments.newName ] = variables[ arguments.method ]; + + // stash it away + if( !structKeyExists( this, "$exposedMethods") ){ + this.$exposedMethods = {}; + } + this.$exposedMethods[ arguments.method ] = variables[ arguments.method ]; + + // replace with proxy. + this[ arguments.newName ] = this.methodProxy; + + // Create alias if needed + if( arguments.newName != arguments.method ){ + this.$exposedMethods[ arguments.newName ] = this.$exposedMethods[ arguments.method ]; + } + + return this; + + + + + + + var methodName = getFunctionCalledName(); + + if( !structKeyExists( this.$exposedMethods, methodName ) ){ + throw( message="The exposed method you are calling: #methodName# does not exist", + detail="Exposed methods are #structKeyList( this.$exposedMethods )#", + type="ExposedMethodProxy" ); + } + + var method = this.$exposedMethods[ methodName ]; + return method( argumentCollection=arguments ); @@ -164,7 +195,7 @@ Description : - + diff --git a/src/cfml/system/wirebox/system/core/events/EventPool.cfc b/src/cfml/system/wirebox/system/core/events/EventPool.cfc index 126d4e451..887d449e9 100644 --- a/src/cfml/system/wirebox/system/core/events/EventPool.cfc +++ b/src/cfml/system/wirebox/system/core/events/EventPool.cfc @@ -1,7 +1,7 @@  - + // Append Custom Statess appendInterceptionPoints(arguments.customStates); @@ -109,8 +111,8 @@ Description : } // Throw Exception - getUtil().throwit(message="Object: #arguments.name# not found in any event pool state: #structKeyList(poolContainer)#.", - type="EventPoolManager.ObjectNotFound"); + throw(message="Object: #arguments.name# not found in any event pool state: #structKeyList(poolContainer)#.", + type="EventPoolManager.ObjectNotFound"); diff --git a/src/cfml/system/wirebox/system/core/util/CFMLEngine.cfc b/src/cfml/system/wirebox/system/core/util/CFMLEngine.cfc index 794f636f2..76b18abf5 100644 --- a/src/cfml/system/wirebox/system/core/util/CFMLEngine.cfc +++ b/src/cfml/system/wirebox/system/core/util/CFMLEngine.cfc @@ -1,210 +1,75 @@ - - - - - - - - //setup the engine properties - this.ADOBE = "ADOBE"; - this.BLUEDRAGON = "BLUEDRAGON"; - this.RAILO = "RAILO"; - - // JDK Version - this.JDK_VERSION = CreateObject("java", "java.lang.System").getProperty("java.version"); - - // Engine Turn off/on features - instance = structnew(); - - instance.adobe = structnew(); - instance.adobe.mt = true; - instance.adobe.json = true; - instance.adobe.ramResource = true; - instance.adobe.onmm = true; - instance.adobe.validation = true; - instance.adobe.instanceCheck = true; - - instance.railo = structnew(); - instance.railo.mt = true; - instance.railo.json = true; - instance.railo.ramResource = true; - instance.railo.onmm = true; - instance.railo.validation = true; - instance.railo.instanceCheck = true; - - instance.bluedragon = structnew(); - instance.bluedragon.mt = true; - instance.bluedragon.json = true; - instance.bluedragon.ramResource = false; - instance.bluedragon.onmm = true; - instance.bluedragon.validation = false; - instance.bluedragon.instanceCheck = true; - - return this; - - - - - - - - - if ( server.coldfusion.productname eq "BlueDragon" ){ return server.bluedragon.edition; } - return listfirst(server.coldfusion.productversion); - - - - - - - var engine = "ADOBE"; - - if ( server.coldfusion.productname eq "BlueDragon" ){ - engine = "BLUEDRAGON"; - } - else if ( server.coldfusion.productname eq "Railo" ){ - engine = "RAILO"; - } - - return engine; - - - - - - - var version = getVersion(); - var engine = getEngine(); - - if ( (engine eq this.ADOBE and version gte 9) or - (engine eq this.RAILO) ){ - return (true AND featureCheck("ramResource",engine)); - } - else{ - return false; - } - - - - - - - var version = getVersion(); - var engine = getEngine(); - - if ( (engine eq this.ADOBE and version gte 8) or - (engine eq this.BLUEDRAGON and version gte 7) or - (engine eq this.RAILO) ){ - return (true AND featureCheck("onmm",engine)); - } - else{ - return false; - } - - - - - - - - var version = getVersion(); - var engine = getEngine(); - - if ( (engine eq this.ADOBE and version gte 9 and getToken(server.coldfusion.productversion,3,",") gte 1) or - (engine eq this.ADOBE and version gte 10) or - (engine eq this.BLUEDRAGON and version gte 7) or - (engine eq this.RAILO) ){ - return (true AND featureCheck("validation",engine)); - } - else{ - return false; - } - - - - - - - var version = getVersion(); - var engine = getEngine(); - - if ( (engine eq this.ADOBE and version gte 8) or - (engine eq this.BLUEDRAGON and version gte 7) or - (engine eq this.RAILO) ){ - return (true AND featureCheck("mt",engine)); - } - else{ - return false; - } - - - - - - - var version = getVersion(); - var engine = getEngine(); - - if ( (engine eq this.ADOBE and version gte 8) or - (engine eq this.BLUEDRAGON and version gte 7) or - (engine eq this.RAILO) ){ - return (true AND featureCheck("instanceCheck",engine)); - } - else{ - return false; - } - - - - - - - var version = getVersion(); - var engine = getEngine(); - - if ( (engine eq this.ADOBE and version gte 8) or - (engine eq this.RAILO and version gte 8) ){ - return (true AND featureCheck("json",engine)); - } - else{ - return false; - } - - - - - - - var version = getVersion(); - var engine = getEngine(); - - if ( (engine eq this.ADOBE and version gte 8) or - (engine eq this.RAILO) ){ - return true; - } - else{ - return false; - } - - - - - - - - - - - - - \ No newline at end of file +* Allows you to maninpulate determine CFML engine capabilities +*/ +component { + + //setup the engine properties + this.ADOBE = "ADOBE"; + this.RAILO = "RAILO"; + this.LUCEE = "LUCEE"; + + // JDK Version + this.JDK_VERSION = CreateObject( "java", "java.lang.System" ).getProperty( "java.version" ); + + /** + * Constructor + */ + function init() { + // Engine Turn off/on features + instance = structnew(); + // adobe features + instance.adobe = {}; + // railo only features + instance.railo = {}; + // lucee only features + instance.lucee = {}; + + return this; + + } + +// ------------------------------------------- PUBLIC ------------------------------------------- + + /** + * Returns the current running CFML major version + */ + numeric function getVersion() { + return listfirst( server.coldfusion.productversion ); + } + + /** + * Returns the current running CFML full version + */ + string function getFullVersion() { + return server.coldfusion.productversion; + } + + /** + * Get the current CFML Engine + */ + string function getEngine() { + var engine = this.adobe; + + if ( server.coldfusion.productname eq "Railo" ){ + engine = this.railo; + } else if ( server.coldfusion.productname eq "Lucee" ){ + engine = this.lucee; + } + + return engine; + } + + /** + * Feature Active Check + * @feature.hint The feature to check + * @engine.hint The engine we are checking + */ + boolean function featureCheck( required string feature, required string engine ) { + return instance[ arguments.engine ][ arguments.feature ]; + } + +} \ No newline at end of file diff --git a/src/cfml/system/wirebox/system/core/util/CFMappingHelper.cfc b/src/cfml/system/wirebox/system/core/util/CFMappingHelper.cfc new file mode 100644 index 000000000..8e9f28065 --- /dev/null +++ b/src/cfml/system/wirebox/system/core/util/CFMappingHelper.cfc @@ -0,0 +1,44 @@ +/** +******************************************************************************** +* Copyright Since 2005 ColdBox Framework by Luis Majano and Ortus Solutions, Corp +* www.ortussolutions.com +******************************************************************************** +* Allows you to maninpulate CF mappings +*/ +component{ + + /** + * For Adobe CF, Slight difference in older versions + */ + function addMapping( required string name, required string path ){ + + if ( listFirst( server.coldfusion.productVersion ) == 9 ) { + addMappingCF9( name, path); + } else if ( listFirst( server.coldfusion.productVersion ) == 10 ) { + addMappingCF10( name, path); + } else { + addMappingCF( name, path); + } + } + + // No workaround neccessary for CF11 and up + function addMappingCF( required string name, required string path ) { + var appSettings = getApplicationMetadata(); + appSettings.mappings[ arguments.name ] = arguments.path; + } + + // For CF10, Add the mappings into the the application settings map + // This is because getApplicationMetadata().mappings is null if none exist + function addMappingCF10( required string name, required string path ) { + var appSettings = application.getApplicationSettingsMap(); + appSettings.mappings[ arguments.name ] = arguments.path; + } + + // CF9 is same as CF10, but with Slightly different method name + function addMappingCF9( required string name, required string path ) { + var appSettings = application.getApplicationSettings(); + appSettings.mappings[ arguments.name ] = arguments.path; + } + + +} \ No newline at end of file diff --git a/src/cfml/system/wirebox/system/core/util/DateUtils.cfc b/src/cfml/system/wirebox/system/core/util/DateUtils.cfc deleted file mode 100644 index 049813041..000000000 --- a/src/cfml/system/wirebox/system/core/util/DateUtils.cfc +++ /dev/null @@ -1 +0,0 @@ - /* Test for Z */ if( datebits.main contains "Z" ){ /* Set Offset to 0 and replace the Z with nothing. */ datebits.offset = "+00:00"; datebits.main = replace(arguments.datetime, "Z", "", "ONE"); } /* test for containz + */ else if( datebits.main contains "+"){ /* Split offset and remove it from main datetime */ datebits.offset = "+" & ListLast(datebits.main,"+"); datebits.main = replace(datebits.main,datebits.offset,"","ONE"); } else{ /* Split negative offset and remove it from main datetime */ datebits.offset = "-" & ListLast(datebits.main,"-"); datebits.main = replace(datebits.main,datebits.offset,"","ONE"); } /* If no seconds, add them */ if( listLen(datebits.main, ":") lt 3){ datebits.main = datebits.main & ":00"; } /* If it has fractional seconds, round it up. BIG DEAL!! */ roundedSeconds = numberFormat(round(listLast(datebits.main,":")),"00"); datebits.main = listSetAt(datebits.main, listLen(datebits.main,":"), roundedSeconds,":"); /* Append All */ datebits.main = datebits.main & datebits.offset; /* Wddx hack to get a datetime object */ wddxPacket = "
    #datebits.main#"; var formatter = CreateObject("java", "java.text.SimpleDateFormat").init("EEE, dd MMM yyyy HH:mm:ss Z"); var parsePosition = CreateObject("java", "java.text.ParsePosition").init(0); var refLocal = structnew(); refLocal.results = arguments.datetime; // Parse the date if( len(arguments.datetime) neq 0 ) refLocal.results = formatter.parse(arguments.datetime, parsePosition); // Null Check if( structKeyExists(refLocal,"results") ){ return refLocal.results; } // Return Default. return arguments.datetime; \ No newline at end of file diff --git a/src/cfml/system/wirebox/system/core/util/FileUtils.cfc b/src/cfml/system/wirebox/system/core/util/FileUtils.cfc index de6cdfd56..3ea45d8fa 100644 --- a/src/cfml/system/wirebox/system/core/util/FileUtils.cfc +++ b/src/cfml/system/wirebox/system/core/util/FileUtils.cfc @@ -1,9 +1 @@ - var objFile = createObject("java","java.io.File").init(JavaCast("string",arguments.filename)); // Calculate adjustments fot timezone and daylightsavindtime var Offset = ((GetTimeZoneInfo().utcHourOffset)+1)*-3600; // Date is returned as number of seconds since 1-1-1970 return DateAdd('s', (Round(objFile.lastModified()/1000))+Offset, CreateDateTime(1970, 1, 1, 0, 0, 0)); var objFile = createObject("java","java.io.File"); objFile.init(JavaCast("string", filename)); if ( arguments.sizeFormat eq "bytes" ) return objFile.length(); if ( arguments.sizeFormat eq "kbytes" ) return (objFile.length()/1024); if ( arguments.sizeFormat eq "mbytes" ) return (objFile.length()/(1048576)); if ( arguments.sizeFormat eq "gbytes" ) return (objFile.length()/1073741824); var fileObj = createObject("java","java.io.File").init(JavaCast("string",arguments.filename)); return fileObj.delete(); var fileObj = createObject("java","java.io.File").init(JavaCast("string",arguments.filename)); fileObj.createNewFile(); var FileObj = CreateObject("java","java.io.File").init(JavaCast("String",arguments.Filename)); return FileObj.canWrite(); var FileObj = CreateObject("java","java.io.File").init(JavaCast("String",arguments.Filename)); return FileObj.canRead(); var FileObj = CreateObject("java","java.io.File").init(JavaCast("String",arguments.Filename)); return FileObj.isFile(); var FileObj = CreateObject("java","java.io.File").init(JavaCast("String",arguments.Filename)); return FileObj.isDirectory(); var FileObj = CreateObject("java","java.io.File").init(JavaCast("String",arguments.path)); if(FileObj.isAbsolute()){ return arguments.path; } else{ return ExpandPath(arguments.path); } if ( listFindNoCase(this.CHAR_SETS,lcase(arguments.charset)) ) return this.DEFAULT_CHAR_SET; else return arguments.charset; - - - - - - - - \ No newline at end of file + var objFile = createObject("java","java.io.File").init(JavaCast("string",arguments.filename)); // Calculate adjustments fot timezone and daylightsavindtime var Offset = ((GetTimeZoneInfo().utcHourOffset)+1)*-3600; // Date is returned as number of seconds since 1-1-1970 return DateAdd('s', (Round(objFile.lastModified()/1000))+Offset, CreateDateTime(1970, 1, 1, 0, 0, 0)); var objFile = createObject("java","java.io.File"); objFile.init(JavaCast("string", filename)); if ( arguments.sizeFormat eq "bytes" ) return objFile.length(); if ( arguments.sizeFormat eq "kbytes" ) return (objFile.length()/1024); if ( arguments.sizeFormat eq "mbytes" ) return (objFile.length()/(1048576)); if ( arguments.sizeFormat eq "gbytes" ) return (objFile.length()/1073741824); var fileObj = createObject("java","java.io.File").init(JavaCast("string",arguments.filename)); return fileObj.delete(); var fileObj = createObject("java","java.io.File").init(JavaCast("string",arguments.filename)); fileObj.createNewFile(); var FileObj = CreateObject("java","java.io.File").init(JavaCast("String",arguments.Filename)); return FileObj.canWrite(); var FileObj = CreateObject("java","java.io.File").init(JavaCast("String",arguments.Filename)); return FileObj.canRead(); var FileObj = CreateObject("java","java.io.File").init(JavaCast("String",arguments.Filename)); return FileObj.isFile(); var FileObj = CreateObject("java","java.io.File").init(JavaCast("String",arguments.Filename)); return FileObj.isDirectory(); var FileObj = CreateObject("java","java.io.File").init(JavaCast("String",arguments.path)); if(FileObj.isAbsolute()){ return arguments.path; } else{ return ExpandPath(arguments.path); } if ( listFindNoCase(this.CHAR_SETS,lcase(arguments.charset)) ) return this.DEFAULT_CHAR_SET; else return arguments.charset; \ No newline at end of file diff --git a/src/cfml/system/wirebox/system/core/util/RailoMappingHelper.cfc b/src/cfml/system/wirebox/system/core/util/RailoMappingHelper.cfc new file mode 100644 index 000000000..8ce4e3185 --- /dev/null +++ b/src/cfml/system/wirebox/system/core/util/RailoMappingHelper.cfc @@ -0,0 +1,19 @@ +/** +******************************************************************************** +* Copyright Since 2005 ColdBox Framework by Luis Majano and Ortus Solutions, Corp +* www.ortussolutions.com +******************************************************************************** +* Creation of mappings via Railo/Lucee +*/ +component{ + + /** + * Engine caches app mappings, but gives us a method to update them via the application "tag" + */ + function addMapping( required string name, required string path ) { + var mappings = getApplicationSettings().mappings; + mappings[ arguments.name ] = arguments.path; + application action='update' mappings='#mappings#'; + } + +} \ No newline at end of file diff --git a/src/cfml/system/wirebox/system/core/util/RequestBuffer.cfc b/src/cfml/system/wirebox/system/core/util/RequestBuffer.cfc index 530a30b44..de45bc936 100644 --- a/src/cfml/system/wirebox/system/core/util/RequestBuffer.cfc +++ b/src/cfml/system/wirebox/system/core/util/RequestBuffer.cfc @@ -1,7 +1,7 @@  - + diff --git a/src/cfml/system/wirebox/system/core/util/Util.cfc b/src/cfml/system/wirebox/system/core/util/Util.cfc index 00919767b..d7637c9b7 100644 --- a/src/cfml/system/wirebox/system/core/util/Util.cfc +++ b/src/cfml/system/wirebox/system/core/util/Util.cfc @@ -1,7 +1,7 @@  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - var md = ""; - var moreChecks = true; - - // Get cf7 nasty metadata, remove by 3.1 - md = getMetadata(arguments.obj); - if( NOT structKeyExists(md, "extends") ){ - return false; - } - md = md.extends; - - while(moreChecks){ - // Check inheritance family? - if( md.name eq arguments.family){ - return true; - } - // Else check further inheritance? - else if ( structKeyExists(md, "extends") ){ - md = md.extends; - } - else{ - return false; - } - } - - return false; - - - - - + var familyPath = ""; switch(arguments.family){ case "handler" : { familyPath = "wirebox.system.EventHandler"; break; } - case "plugin" : { familyPath = "wirebox.system.Plugin"; break; } case "interceptor" : { familyPath = "wirebox.system.Interceptor"; break; } default:{ - throwit('Invalid family sent #arguments.family#'); + throw('Invalid family sent #arguments.family#'); } } - if( structKeyExists(getFunctionList(), "isInstanceOf") ){ - return isInstanceOf(arguments.target,familyPath); - } - else{ - return isInstanceCheck(arguments.target,familyPath); - } + return isInstanceOf( arguments.target, familyPath ); - + var baseObject = ""; @@ -260,10 +178,9 @@ Description : switch(arguments.family){ case "handler" : { familyPath = "wirebox.system.EventHandler"; break; } - case "plugin" : { familyPath = "wirebox.system.Plugin"; break; } case "interceptor" : { familyPath = "wirebox.system.Interceptor"; break; } default:{ - throwit('Invalid family sent #arguments.family#'); + throw('Invalid family sent #arguments.family#'); } } @@ -307,7 +224,7 @@ Description : - + @@ -369,4 +286,30 @@ Description : + + + + + + var mappingHelper = ""; + + // Detect server + if( listFindNoCase( "Railo,Lucee", server.coldfusion.productname ) ) { + mappingHelper = new RailoMappingHelper(); + } else { + mappingHelper = new CFMappingHelper(); + } + + // Add / registration + if( left( arguments.name, 1 ) != "/" ){ + arguments.name = "/#arguments.name#"; + } + + // Add mapping + mappingHelper.addMapping( arguments.name, arguments.path ); + + return this; + + + \ No newline at end of file diff --git a/src/cfml/system/wirebox/system/core/util/Validator.cfc b/src/cfml/system/wirebox/system/core/util/Validator.cfc deleted file mode 100644 index d37b683c1..000000000 --- a/src/cfml/system/wirebox/system/core/util/Validator.cfc +++ /dev/null @@ -1,108 +0,0 @@ - - - - - - - - return this; - - - - - - - function checkAlphaOnly(str){ - if( reFindNoCase("^[a-zA-Z\s]*$",arguments.str) eq 0){ return false; } - else{ return true; } - } - - function checkBoolean(str){ return isBoolean(arguments.str); } - - function checkDate(str){ return isValid("date",arguments.str); } - - function checkEmail(str){ return isValid("email",arguments.str); } - - function checkEurodate(str){ return isValid("eurodate",arguments.str); } - - function checkExactLen(str,length){ return ( len(arguments.str) eq arguments.length); } - - function checkNumeric(str){ return isValid("numeric",arguments.str); } - - function checkGUID(str){ return isValid("guid",arguments.str); } - - function checkInteger(str){ return isValid("integer",arguments.str); } - - function checkMaxLen(str,length){ return (len(arguments.str) lte arguments.length); } - - function checkMinLen(str,length){ return (len(arguments.str) gte arguments.length); } - - function checkRange(str,min,max){ return isValid("range",arguments.str,arguments.min,arguments.max); } - - function checkRegex(str,regex){ return isValid("regex",arguments.str,arguments.regex); } - - function checkSameAsNoCase(str1,str2){ - if( compareNoCase(arguments.str1,arguments.str2) eq 0){ return true; } - else{ return false; } - } - - function checkSameAs(str1,str2){ - if( compare(arguments.str1,arguments.str2) eq 0){ return true; } - else{ return false; } - } - - function checkSSN(str){ return isValid("ssn",arguments.str); } - - function checkString(str){ return isValid("string",arguments.str); } - - function checkTelephone(str){ return isValid("telephone",arguments.str); } - - function checkURL(str){ return isValid("URL",arguments.str); } - - function checkUUID(str){ return isValid("UUID",arguments.str); } - - function checkUSDate(str){ return isValid("usdate",arguments.str); } - - function checkZipCode(str){ return isValid("zipcode",arguments.str); } - - function checkIPAddress(str){ - if( refindnocase("\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b",arguments.str) eq 0 ){ return false; } - else{ return true; } - } - - \ No newline at end of file diff --git a/src/cfml/system/wirebox/system/core/util/Zip.cfc b/src/cfml/system/wirebox/system/core/util/Zip.cfc deleted file mode 100644 index 326b482ad..000000000 --- a/src/cfml/system/wirebox/system/core/util/Zip.cfc +++ /dev/null @@ -1,651 +0,0 @@ - - - - - - - - configure(); - return this; - - - - - - - //This plugin's properties - instance = structnew(); - instance.ioFile = CreateObject("java","java.io.File"); - instance.ioInput = CreateObject("java","java.io.FileInputStream"); - instance.ioOutput = CreateObject("java","java.io.FileOutputStream"); - instance.ioBufOutput = CreateObject("java","java.io.BufferedOutputStream"); - instance.zipFile = CreateObject("java","java.util.zip.ZipFile"); - instance.zipEntry = CreateObject("java","java.util.zip.ZipEntry"); - instance.zipInput = CreateObject("java","java.util.zip.ZipInputStream"); - instance.zipOutput = CreateObject("java","java.util.zip.ZipOutputStream"); - instance.gzInput = CreateObject("java","java.util.zip.GZIPInputStream"); - instance.gzOutput = CreateObject("java","java.util.zip.GZIPOutputStream"); - instance.objDate = CreateObject("java","java.util.Date"); - - /* Set Localized Variables */ - instance.os = Server.OS.Name; - instance.slash = createObject("java","java.lang.System").getProperty("file.separator"); - - //LM. To fix Overflow. - instance.filename = ""; - - return this; - - - - - - - - - - - - - - - - - /* Default variables */ - var i = 0; - var l = 0; - var buffer = RepeatString(" ",1024).getBytes(); - var entryPath = ""; - var entryFile = ""; - var localfiles = ""; - var path = ""; - var skip = ""; - - try{ - /* Initialize Zip file */ - instance.ioOutput.init(PathFormat(arguments.zipFilePath)); - instance.filename = getFileFromPath(arguments.zipFilePath); - instance.zipOutput.init(instance.ioOutput); - instance.zipOutput.setLevel(arguments.compression); - - /* Get files list array */ - if( structKeyExists(arguments, "files") and arguments.files neq "") - localfiles = ListToArray(PathFormat(arguments.files), "|"); - else if( structKeyExists(arguments,"directory") and arguments.directory neq ""){ - localfiles = FilesList(arguments.directory, arguments.filter, arguments.recurse); - arguments.directory = PathFormat(arguments.directory); - } - - /* Loop over files array */ - for(i=1; i LTE ArrayLen(localfiles); i=i+1){ - if(FileExists(localfiles[i])){ - path = localfiles[i]; - - // Get entry path and file - entryPath = GetDirectoryFromPath(path); - entryFile = GetFileFromPath(path); - - // Remove drive letter from path - if(arguments.savePaths EQ "yes" AND Right(ListFirst(entryPath, instance.slash), 1) EQ ":") - entryPath = ListDeleteAt(entryPath, 1, instance.slash); - // Remove directory from path - else if(arguments.savePaths EQ "no"){ - if( structKeyExists(arguments, "directory") and arguments.directory neq "" ) - entryPath = ReplaceNoCase(entryPath, arguments.directory, "", "ALL"); - else if(structKeyExists(arguments, "files") and arguments.files neq "") - entryPath = ""; - } - - // Remove slash at first - if(Len(entryPath) GT 1 AND Left(entryPath, 1) EQ instance.slash) entryPath = Right(entryPath, Len(entryPath)-1); - else if(Len(entryPath) EQ 1 AND Left(entryPath, 1) EQ instance.slash) entryPath = "" ; - - // Skip if entry with the same name already exsits - try { - instance.ioFile.init(path); - instance.ioInput.init(instance.ioFile.getPath()); - - instance.zipEntry.init(entryPath & entryFile); - instance.zipOutput.putNextEntry(instance.zipEntry); - - l = instance.ioInput.read(buffer); - - while(l GT 0){ - instance.zipOutput.write(buffer, 0, l); - l = instance.ioInput.read(buffer); - } - - instance.zipOutput.closeEntry(); - instance.ioInput.close(); - } - - catch(java.util.zip.ZipException ex) - { skip = "yes"; } - } - } - - /* Close Zip file */ - instance.zipOutput.close(); - - /* Return true */ - return true; - } - - catch(Any expr) - { - /* Close Zip file */ - instance.zipOutput.close(); - - /* Return false */ - return false; - } - - - - - - - - - - - - - - - /* NOTICE: There is no function in the Java API to delete entrys from a Zip file. - So we have to create a workaround for this function. At first we create - a new temporary Zip file and save there all entrys, excluded the delete - files. Then we delete the orginal Zip file and rename the temporary Zip - file. */ - - /* Default variables */ - var l = 0; - var buffer = RepeatString(" ",1024).getBytes(); - var entries = ""; - var entry = ""; - var inStream = ""; - var zipTemp = ""; - var zipRename = ""; - /* Convert to the right path format */ - arguments.zipFilePath = PathFormat(arguments.zipFilePath); - - try{ - /* Open Zip file and get Zip file entries */ - instance.zipFile.init(arguments.zipFilePath); - entries = instance.zipFile.entries(); - - /* Create a new temporary Zip file */ - instance.ioOutput.init(PathFormat(arguments.zipFilePath & ".temp")); - instance.zipOutput.init(instance.ioOutput); - - /* Loop over Zip file entries */ - while(entries.hasMoreElements()){ - entry = entries.nextElement(); - - if(NOT entry.isDirectory()){ - /* Create a new entry in the temporary Zip file */ - if(NOT ListFindNoCase(arguments.files, entry.getName(), "|")){ - // Set entry compression - instance.zipOutput.setLevel(entry.getMethod()); - - // Create new entry in the temporary Zip file - instance.zipEntry.init(entry.getName()); - instance.zipOutput.putNextEntry(instance.zipEntry); - - inStream = instance.zipFile.getInputStream(entry); - l = inStream.read(buffer); - - while(l GT 0){ - instance.zipOutput.write(buffer, 0, l); - l = inStream.read(buffer); - } - - // Close entry - instance.zipOutput.closeEntry(); - } - } - } - - /* Close the orginal Zip and the temporary Zip file */ - instance.zipFile.close(); - instance.zipOutput.close(); - - /* Delete the orginal Zip file */ - instance.ioFile.init(arguments.zipFilePath).delete(); - - /* Rename the temporary Zip file */ - zipTemp = instance.ioFile.init(arguments.zipFilePath & ".temp"); - zipRename = instance.ioFile.init(arguments.zipFilePath); - zipTemp.renameTo(zipRename); - - /* Return true */ - return true; - } - - catch(Any expr) - { - /* Close the orginal Zip and the temporary Zip file */ - instance.zipOutput.close(); - instance.zipFile.close(); - - /* Delete the temporary Zip file, if exists */ - if(FileExists(arguments.zipFilePath & ".temp")) - instance.ioFile.init(arguments.zipFilePath & ".temp").delete(); - - /* Return false */ - return false; - } - - - - - - - - - - - - - - - - - /* Default variables */ - var l = 0; - var entries = ""; - var entry = ""; - var name = ""; - var path = ""; - var filePath = ""; - var buffer = RepeatString(" ",1024).getBytes(); - var lastChr = ""; - var lenPath = ""; - var inStream = ""; - var skip = ""; - - /* Convert to the right path format */ - arguments.zipFilePath = PathFormat(arguments.zipFilePath); - arguments.extractPath = PathFormat(arguments.extractPath); - - /* Check if the 'extractPath' string is closed */ - lastChr = Right(arguments.extractPath, 1); - - /* Set an slash at the end of string */ - if(lastChr NEQ instance.slash) - arguments.extractPath = arguments.extractPath & instance.slash; - - try{ - /* Open Zip file */ - instance.zipFile.init(arguments.zipFilePath); - - /* Zip file entries */ - entries = instance.zipFile.entries(); - - /* Loop over Zip file entries */ - while(entries.hasMoreElements()){ - entry = entries.nextElement(); - - if(NOT entry.isDirectory()){ - name = entry.getName(); - - /* Create directory only if 'useFolderNames' is 'yes' */ - if(arguments.useFolderNames EQ "yes"){ - lenPath = Len(name) - Len(GetFileFromPath(name)); - - if(lenPath) path = extractPath & Left(name, lenPath); - else path = extractPath; - - if(NOT DirectoryExists(path)){ - instance.ioFile.init(path); - instance.ioFile.mkdirs(); - } - } - - /* Set file path */ - if(arguments.useFolderNames EQ "yes") filePath = arguments.extractPath & name; - else filePath = arguments.extractPath & GetFileFromPath(name); - - /* Extract files. Files would be extract when following conditions are fulfilled: - If the 'extractFiles' list is not defined, - or the 'extractFiles' list is defined and the entry filename is found in the list, - or the file already exists and 'overwriteFiles' is 'yes'. */ - if((NOT structKeyExists(arguments, "extractFiles") - OR (structKeyExists(arguments, "extractFiles") AND ListFindNoCase(arguments.extractFiles, GetFileFromPath(name), "|"))) - AND (NOT FileExists(filePath) OR (FileExists(filePath) AND arguments.overwriteFiles EQ "yes"))) - { - // Skip if entry contains special characters - try{ - instance.ioOutput.init(filePath); - instance.ioBufOutput.init(instance.ioOutput); - - inStream = instance.zipFile.getInputStream(entry); - l = inStream.read(buffer); - - while(l GTE 0){ - instance.ioBufOutput.write(buffer, 0, l); - l = inStream.read(buffer); - } - - inStream.close(); - instance.ioBufOutput.close(); - instance.ioOutput.close(); - } - - catch(Any Expr) - { skip = "yes"; } - } - } - } - - /* Close the Zip file */ - instance.zipFile.close(); - - /* Return true */ - return true; - } - - catch(Any expr){ - /* Close the Zip file */ - instance.zipFile.close(); - - /* Return false */ - return false; - } - - - - - - - - - - - - /* Default variables */ - var i = 0; - var entries = ""; - var entry = ""; - var cols = "entry,date,size,packed,ratio,crc"; - var query = QueryNew(cols); - var qEntry = ""; - var qDate = ""; - var qSize = ""; - var qPacked = ""; - var qCrc = ""; - var qRatio = ""; - - cols = ListToArray(cols); - - /* Open Zip file */ - instance.zipFile.init(arguments.zipFilePath); - - /* Zip file entries */ - entries = instance.zipFile.entries(); - - /* Fill query with data */ - while(entries.hasMoreElements()){ - entry = entries.nextElement(); - - if(NOT entry.isDirectory()){ - QueryAddRow(query, 1); - - qEntry = PathFormat(entry.getName()); - qDate = instance.objDate.init(entry.getTime()); - qSize = entry.getSize(); - qPacked = entry.getCompressedSize(); - qCrc = entry.getCrc(); - - if(qSize GT 0) qRatio = Round(Evaluate(100-((qPacked*100)/qSize))) & "%"; - else qRatio = "0%"; - - for(i=1; i LTE ArrayLen(cols); i=i+1) - QuerySetCell(query, cols[i], Trim(Evaluate("q#cols[i]#"))); - } - } - - /* Close the Zip File */ - instance.zipFile.close(); - - /* Return query */ - return query; - - - - - - - - - - - - /* Default variables */ - var l = 0; - var buffer = RepeatString(" ",1024).getBytes(); - var gzFileName = ""; - var outputFile = ""; - var lastChr = ""; - - - - /* Convert to the right path format */ - arguments.gzipFilePath = PathFormat(arguments.gzipFilePath); - arguments.filePath = PathFormat(arguments.filePath); - - /* Check if the 'extractPath' string is closed */ - lastChr = Right(arguments.gzipFilePath, 1); - - /* Set an slash at the end of string */ - if(lastChr NEQ instance.slash) - arguments.gzipFilePath = arguments.gzipFilePath & instance.slash; - - try{ - /* Set output gzip file name */ - gzFileName = getFileFromPath(arguments.filePath) & ".gz"; - outputFile = arguments.gzipFilePath & gzFileName; - - instance.ioInput.init(arguments.filePath); - instance.ioOutput.init(outputFile); - instance.gzOutput.init(instance.ioOutput); - - l = instance.ioInput.read(buffer); - - while(l GT 0){ - instance.gzOutput.write(buffer, 0, l); - l = instance.ioInput.read(buffer); - } - - /* Close the GZip file */ - instance.gzOutput.close(); - instance.ioOutput.close(); - instance.ioInput.close(); - - /* Return true */ - return true; - } - - catch(Any expr) - { return false; } - - - - - - - - - - - - - - /* Default variables */ - var l = 0; - var buffer = RepeatString(" ",1024).getBytes(); - var gzFileName = ""; - var outputFile = ""; - var lastChr = ""; - - /* Convert to the right path format */ - arguments.gzipFilePath = PathFormat(arguments.gzipFilePath); - arguments.extractPath = PathFormat(arguments.extractPath); - - /* Check if the 'extractPath' string is closed */ - lastChr = Right(arguments.extractPath, 1); - - /* Set an slash at the end of string */ - if(lastChr NEQ instance.slash) - arguments.extractPath = arguments.extractPath & instance.slash; - - try{ - /* Set output file name */ - gzFileName = getFileFromPath(arguments.gzipFilePath); - outputFile = arguments.extractPath & Left(gzFileName, Len(gzFileName)-3); - - /* Initialize gzip file */ - instance.ioOutput.init(outputFile); - instance.ioInput.init(arguments.gzipFilePath); - instance.gzInput.init(instance.ioInput); - - while(l GTE 0){ - instance.ioOutput.write(buffer, 0, l); - l = instance.gzInput.read(buffer); - } - - /* Close the GZip file */ - instance.gzInput.close(); - instance.ioInput.close(); - instance.ioOutput.close(); - - /* Return true */ - return true; - } - catch(Any expr) - { return false; } - - - - - - - - - - - - - - - - - - - - - - - - - - - /* Loop over directory query */ - for(i=1; i LTE dir.recordcount; i=i+1){ - path = PathFormat(arguments.directory & instance.slash & dir.name[i]); - - /* Add file to array */ - if(dir.type[i] eq "file" and dir.name[i] neq instance.filename) - ArrayAppend(array, path); - - /* Get files from sub directorys and add them to the array */ - else if(dir.type[i] EQ "dir" AND arguments.recurse EQ "yes"){ - subdir = FilesList(path, arguments.filter, arguments.recurse); - - for(n=1; n LTE ArrayLen(subdir); n=n+1) - ArrayAppend(array, subdir[n]); - } - } - - /* Return array */ - return array; - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/cfml/system/wirebox/system/ioc/AbstractIOCAdapter.cfc b/src/cfml/system/wirebox/system/ioc/AbstractIOCAdapter.cfc deleted file mode 100644 index 5e8483fd8..000000000 --- a/src/cfml/system/wirebox/system/ioc/AbstractIOCAdapter.cfc +++ /dev/null @@ -1,112 +0,0 @@ - - - - - - - - - - - instance = structnew(); - // A coldBox reference that might or not exist - instance.coldbox = ""; - // The placeholder for the factory created - instance.factory = ""; - // The definition file to be used by the factory created - instance.definitionFile = arguments.definitionFile; - // The properties passed to the factory to create - instance.properties = arguments.properties; - - // Link to coldbox context if passed - if( isObject(arguments.coldbox) ){ instance.coldbox = arguments.coldbox; } - - return this; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/cfml/system/wirebox/system/ioc/Builder.cfc b/src/cfml/system/wirebox/system/ioc/Builder.cfc index b5353af37..c66b7815d 100644 --- a/src/cfml/system/wirebox/system/ioc/Builder.cfc +++ b/src/cfml/system/wirebox/system/ioc/Builder.cfc @@ -1,20 +1,20 @@  - - + + @@ -26,7 +26,7 @@ TODO: update dsl consistency, so it is faster. utility = arguments.injector.getUtil(), customDSL = structnew() }; - + // Do we need to build the coldbox DSL namespace if( instance.injector.isColdBoxLinked() ){ instance.coldboxDSL = createObject("component","wirebox.system.ioc.dsl.ColdBoxDSL").init( arguments.injector ); @@ -37,49 +37,58 @@ TODO: update dsl consistency, so it is faster. } // Build LogBox DSL Namespace instance.logBoxDSL = createObject("component","wirebox.system.ioc.dsl.LogBoxDSL").init( arguments.injector ); - + return this; - + - + - var customDSL = instance.injector.getBinder().getCustomDSL(); - var key = ""; - + var customDSL = instance.injector.getBinder().getCustomDSL(); + // Register Custom DSL Builders - for(key in customDSL){ - instance.customDSL[key] = createObject("component",customDSL[key]).init( instance.injector ); - // Debugging - if( instance.log.canDebug() ){ - instance.log.debug("Registered custom DSL Builder: #customDSL[key]# with namespace: #key#"); - } - } + for( var key in customDSL ){ + registerDSL( namespace=key, path=customDSL[ key ] ); + } - - + + + + + + + + // register dsl + instance.customDSL[ arguments.namespace ] = createObject( "component", arguments.path ).init( instance.injector ); + // Debugging + if( instance.log.canDebug() ){ + instance.log.debug("Registered custom DSL Builder with namespace: #arguments.namespace#"); + } + + + var targetInjector = this.$wbScopeStorage.get(this.$wbScopeInfo.key, this.$wbScopeInfo.scope); var targetProvider = this.$wbProviders[ getFunctionCalledName() ]; - + // Verify if this is a mapping first? if( targetInjector.containsInstance( targetProvider ) ){ return targetInjector.getInstance(name=targetProvider, targetObject=this); } - + // else treat as full DSL return targetInjector.getInstance(dsl=targetProvider, targetObject=this); - + @@ -89,7 +98,7 @@ TODO: update dsl consistency, so it is faster. var oModel = createObject("component", thisMap.getPath() ); var constructorArgs = ""; var viMapping = ""; - + // Do we have virtual inheritance? if( arguments.mapping.isVirtualInheritance() ){ // retrieve the VI mapping. @@ -100,35 +109,35 @@ TODO: update dsl consistency, so it is faster. } } - + - + - + - + - - + - + @@ -139,10 +148,10 @@ TODO: update dsl consistency, so it is faster. var oModel = ""; var factoryName = thisMap.getPath(); var methodArgs = ""; - + // check if factory exists, else throw exception if( NOT instance.injector.containsInstance( factoryName ) ){ - instance.utility.throwIt(message="The factory mapping: #factoryName# is not registered with the injector",type="Builder.InvalidFactoryMappingException"); + throw(message="The factory mapping: #factoryName# is not registered with the injector",type="Builder.InvalidFactoryMappingException"); } // get Factory mapping oFactory = instance.injector.getInstance( factoryName ); @@ -153,13 +162,13 @@ TODO: update dsl consistency, so it is faster. structAppend(methodArgs,arguments.initArguments,true); } - + - + @@ -179,7 +188,7 @@ TODO: update dsl consistency, so it is faster. // do we have javacasting? if( structKeyExists(DIArgs[x],"javaCast") ){ ArrayAppend(args, "javaCast(DIArgs[#x#].javaCast, DIArgs[#x#].value)"); - } + } else{ ArrayAppend(args, "DIArgs[#x#].value"); } @@ -192,12 +201,12 @@ TODO: update dsl consistency, so it is faster. } return createObject("java",arguments.mapping.getPath()).init(); } - + // return with no init return createObject("java",arguments.mapping.getPath()); - + @@ -209,34 +218,34 @@ TODO: update dsl consistency, so it is faster. var DIArgs = arguments.argumentArray; var DIArgsLen = arrayLen(DIArgs); var args = structnew(); - + // Loop Over Arguments for(x=1;x lte DIArgsLen; x=x+1){ - + // Is value set in mapping? If so, add it and continue if( structKeyExists(DIArgs[x],"value") ){ args[ DIArgs[x].name ] = DIArgs[x].value; continue; } - + // Is it by DSL construction? If so, add it and continue, if not found it returns null, which is ok if( structKeyExists(DIArgs[x],"dsl") ){ args[ DIArgs[x].name ] = buildDSLDependency( definition=DIArgs[x], targetID=thisMap.getName(), targetObject=arguments.targetObject ); continue; } - + // If we get here then it is by ref id, so let's verify it exists and optional if( len(instance.injector.containsInstance( DIArgs[x].ref )) ){ args[ DIArgs[x].name ] = instance.injector.getInstance(name=DIArgs[x].ref); continue; } - + // Not found, so check if it is required if( DIArgs[x].required ){ // Log the error instance.log.error("Target: #thisMap.getName()# -> Argument reference not located: #DIArgs[x].name# for mapping: #arguments.mapping.getMemento().toString()#", DIArgs[x]); // not found but required, then throw exception - instance.utility.throwIt(message="Argument reference not located: #DIArgs[x].name#", + throw(message="Argument reference not located: #DIArgs[x].name#", detail="Injecting: #thisMap.getMemento().toString()#. The argument details are: #DIArgs[x].toString()#.", type="Injector.ArgumentNotFoundException"); } @@ -244,13 +253,13 @@ TODO: update dsl consistency, so it is faster. else if( instance.log.canDebug() ){ instance.log.debug("Target: #thisMap.getName()# -> Argument reference not located: #DIArgs[x].name# for mapping: #arguments.mapping.getMemento().toString()#", DIArgs[x]); } - + } - + return args; - + @@ -259,31 +268,31 @@ TODO: update dsl consistency, so it is faster. var argStruct = {}; var DIArgs = arguments.mapping.getDIConstructorArguments(); var DIArgsLen = arraylen(DIArgs); - + // Loop Over Arguments for wsdl args for(x=1;x lte DIArgsLen; x=x+1){ argStruct[ DIArgs[x].name ] = DIArgs[x].value; } - + // Do we ahve overrides if( NOT structIsEmpty(arguments.initArguments) ){ structAppend(argStruct, arguments.initArguments,true); } - + return createObject("webservice", arguments.mapping.getPath(), argStruct ); - + - + - + - + @@ -293,6 +302,7 @@ TODO: update dsl consistency, so it is faster. var definition = { + required=true, name = "", dsl = arguments.dsl }; @@ -308,20 +318,24 @@ TODO: update dsl consistency, so it is faster. var refLocal = {}; var DSLNamespace = listFirst(arguments.definition.dsl,":"); - var coldboxDSLRegex = "^(ioc|ocm|webservice|javaloader|coldbox|cachebox)$"; - - // Determine Type of Injection according to Internal Types first + + // Check if Custom DSL exists, if it does, execute it + if( structKeyExists( instance.customDSL, DSLNamespace ) ){ + return instance.customDSL[ DSLNamespace ].process(argumentCollection=arguments); + } + + // Determine Type of Injection according to type // Some namespaces requires the ColdBox context, if not found, an exception is thrown. switch( DSLNamespace ){ // ColdBox Context DSL - case "ioc" : case "ocm" : case "webservice" : case "javaloader" : case "coldbox" : { - refLocal.dependency = instance.coldboxDSL.process(argumentCollection=arguments); break; - } + case "ocm" : case "coldbox" : { + refLocal.dependency = instance.coldboxDSL.process(argumentCollection=arguments); break; + } // CacheBox Context DSL - case "cacheBox" : { + case "cacheBox" : { // check if linked if( !instance.injector.isCacheBoxLinked() AND !instance.injector.isColdBoxLinked() ){ - instance.utility.throwIt(message="The DSLNamespace: #DSLNamespace# cannot be used as it requires a ColdBox/CacheBox Context",type="Builder.IllegalDSLException"); + throw(message="The DSLNamespace: #DSLNamespace# cannot be used as it requires a ColdBox/CacheBox Context",type="Builder.IllegalDSLException"); } // retrieve it refLocal.dependency = instance.cacheBoxDSL.process(argumentCollection=arguments); break; @@ -334,42 +348,38 @@ TODO: update dsl consistency, so it is faster. case "provider" : { refLocal.dependency = getProviderDSL(argumentCollection=arguments); break; } // wirebox injection DSL always available case "wirebox" : { refLocal.dependency = getWireBoxDSL(argumentCollection=arguments); break;} - // wirebox entity services - case "entityService" : { refLocal.dependency = getEntityServiceDSL(argumentCollection=arguments); break;} // java class case "java" : { refLocal.dependency = getJavaDSL(argumentCollection=arguments); break; } - + // coldfusion type annotation + case "bytype" : { refLocal.dependency = getByTypeDSL(argumentCollection=arguments); break; } + // No internal DSL's found, then check custom DSL's default : { - // Check if Custom DSL exists, if it does, execute it - if( structKeyExists( instance.customDSL, DSLNamespace ) ){ - refLocal.dependency = instance.customDSL[ DSLNamespace ].process(argumentCollection=arguments); - } - - // If no custom DSL's found, let's try to use the name as the empty namespace + + // If no DSL's found, let's try to use the name as the empty namespace if( NOT find( ":", arguments.definition.dsl ) ){ arguments.definition.dsl = "id:#arguments.definition.dsl#"; refLocal.dependency = getModelDSL(argumentCollection=arguments); } } } - + // return only if found if( structKeyExists( refLocal, "dependency" ) ){ return refLocal.dependency; } - + // was dependency required? If so, then throw exception if( arguments.definition.required ){ // Logging if( instance.log.canError() ){ instance.log.error("Target: #arguments.targetID# -> DSL Definition: #arguments.definition.toString()# did not produce any resulting dependency"); } - + // Throw exception as DSL Dependency requested was not located - instance.utility.throwit(message="The DSL Definition #arguments.definition.toString()# did not produce any resulting dependency", + throw(message="The DSL Definition #arguments.definition.toString()# did not produce any resulting dependency", detail="The target requesting the dependency is: '#arguments.targetID#'", type="Builder.DSLDependencyNotFoundException"); } - // else return void, no dependency found that was required + // else return void, no dependency found that was required @@ -385,35 +395,18 @@ TODO: update dsl consistency, so it is faster. return createObject("java", javaClass); - - - - - - - var entityName = getToken(arguments.definition.dsl,2,":"); - - // Do we have an entity name? If we do create virtual entity service - if( len(entityName) ){ - return createObject("component","wirebox.system.orm.hibernate.VirtualEntityService").init( entityName ); - } - - // else Return Base ORM Service - return createObject("component","wirebox.system.orm.hibernate.BaseORMService").init(); - - - + var thisType = arguments.definition.dsl; var thisTypeLen = listLen(thisType,":"); var thisLocationType = ""; var thisLocationKey = ""; - + // DSL stages switch(thisTypeLen){ // WireBox injector @@ -497,7 +490,7 @@ TODO: update dsl consistency, so it is faster. var thisTypeLen = listLen(thisType,":"); var providerName = ""; var args = {}; - + // DSL stages switch( thisTypeLen ){ // provider default, get name of the provider from property @@ -511,12 +504,12 @@ TODO: update dsl consistency, so it is faster. } // Build provider arguments - args = { + args = { scopeRegistration = instance.injector.getScopeRegistration(), scopeStorage = instance.injector.getScopeStorage(), targetObject = arguments.targetObject }; - + // Check if the passed in provider is an ID directly if( instance.injector.containsInstance( providerName ) ){ args.name = providerName; @@ -525,12 +518,25 @@ TODO: update dsl consistency, so it is faster. else{ args.dsl = providerName; } - + // Build provider and return it. return createObject("component","wirebox.system.ioc.Provider").init( argumentCollection=args ); - + + + + + + + var injectType = arguments.definition.type; + + if( instance.injector.containsInstance( injectType ) ){ + return instance.injector.getInstance( injectType ); + } + + + @@ -538,39 +544,37 @@ TODO: update dsl consistency, so it is faster. var baseObject = ""; var familyPath = ""; - var key = ""; var constructorArgs = ""; var excludedProperties = "$super,$wbaopmixed,$mixed,$WBAOPTARGETMAPPING,$WBAOPTARGETS"; - + // Mix it up baby instance.utility.getMixerUtil().start( arguments.target ); - + // Create base family object baseObject = instance.injector.getInstance( arguments.mapping.getName() ); - + // Check if init already exists in target and base? - if( structKeyExists(arguments.target, "init") AND structKeyExists(baseObject,"init") ){ + if( structKeyExists( arguments.target, "init" ) AND structKeyExists( baseObject,"init" ) ){ arguments.target.$superInit = baseObject.init; - } - + } + // Mix in methods - for(key in baseObject){ + for( var key in baseObject ){ // If target has overriden method, then don't override it with mixin, simulated inheritance - if( NOT structKeyExists(arguments.target, key) AND NOT listFindNoCase(excludedProperties, key) ){ - arguments.target.injectMixin( key, baseObject[key] ); + if( NOT structKeyExists( arguments.target, key ) AND NOT listFindNoCase( excludedProperties, key ) ){ + arguments.target.injectMixin( key, baseObject[ key ] ); } } - // Mix in virtual super class arguments.target.$super = baseObject; // Verify if we need to init the virtualized object - if( structKeyExists(arguments.target, "$superInit") ){ + if( structKeyExists( arguments.target, "$superInit" ) ){ // get super constructor arguments. constructorArgs = buildArgumentCollection( arguments.mapping, arguments.mapping.getDIConstructorArguments(), baseObject ); // Init the virtualized inheritance - arguments.target.$superInit(argumentCollection=constructorArgs); + arguments.target.$superInit( argumentCollection=constructorArgs ); } - - \ No newline at end of file + + diff --git a/src/cfml/system/wirebox/system/ioc/ColdboxFactory.cfc b/src/cfml/system/wirebox/system/ioc/ColdboxFactory.cfc deleted file mode 100644 index d70b8745d..000000000 --- a/src/cfml/system/wirebox/system/ioc/ColdboxFactory.cfc +++ /dev/null @@ -1,174 +0,0 @@ - - - - - - - logger - - - true|false - - - -Modification History: -5/30/2007 - Created Template -----------------------------------------------------------------------> - - - - - - - variables.configBeanPath = "wirebox.system.core.collections.ConfigBean"; - variables.datasourceBeanPath = "wirebox.system.core.db.DatasourceBean"; - variables.mailsettingsBeanPath = "wirebox.system.core.mail.MailSettingsBean"; - variables.coldboxAppKey = "cbController"; - - - - - - - - - - - - - - - - - - - - - - - - - return CreateObject("component",configBeanPath).init( getColdbox().getConfigSettings() ); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - var datasources = getColdbox().getSetting("Datasources"); - //Check for datasources structure - if ( structIsEmpty(datasources) ){ - getUtil().throwit("There are no datasources defined for this application.","","ColdboxFactory.DatasourceStructureEmptyException"); - } - //Try to get the correct datasource. - if ( structKeyExists(datasources, arguments.alias) ){ - return CreateObject("component",datasourceBeanPath).init(datasources[arguments.alias]); - } - else{ - getUtil().throwit("The datasource: #arguments.alias# is not defined.","","ColdboxFactory.DatasourceNotFoundException"); - } - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/cfml/system/wirebox/system/ioc/IInjector.cfc b/src/cfml/system/wirebox/system/ioc/IInjector.cfc index 259cf3520..be2e92389 100644 --- a/src/cfml/system/wirebox/system/ioc/IInjector.cfc +++ b/src/cfml/system/wirebox/system/ioc/IInjector.cfc @@ -1,7 +1,7 @@  - + if( NOT instance.binder.mappingExists( arguments.name ) ){ // create a new mapping to be registered within the binder @@ -358,6 +369,15 @@ Description : + + + + + + instance.builder.registerDSL( argumentCollection=arguments ); + + + @@ -597,7 +617,7 @@ Description : else{ refLocal.dependency = getInstance( arguments.DIData[x].ref ); } - + // Check if dependency located, else log it and skip if( structKeyExists(refLocal,"dependency") ){ // scope or setter determination @@ -701,6 +721,11 @@ Description : + + + + + @@ -763,7 +788,7 @@ Description : return instance.scopeStorage.get(scopeInfo.key, scopeInfo.scope); } - instance.utility.throwit(message="The injector has not be registered in any scope",detail="The scope info is: #scopeInfo.toString()#",type="Injector.InvalidScopeRegistration"); + throw(message="The injector has not be registered in any scope",detail="The scope info is: #scopeInfo.toString()#",type="Injector.InvalidScopeRegistration"); @@ -824,7 +849,7 @@ Description : } catch(Any e){ instance.log.error("Error creating listener: #listeners[x].toString()#", e); - getUtil().throwit(message="Error creating listener: #listeners[x].toString()#", + throw(message="Error creating listener: #listeners[x].toString()#", detail="#e.message# #e.detail# #e.stackTrace#", type="Injector.ListenerCreationException"); } @@ -946,7 +971,7 @@ Description : instance.eventManager.appendInterceptionPoints( arrayToList(instance.eventStates) ); return; } - + // create event manager instance.eventManager = createObject("component","wirebox.system.core.events.EventPoolManager").init( instance.eventStates ); // Debugging @@ -974,7 +999,7 @@ Description : } // Check if data CFC or binder family - if( NOT instance.utility.isInstanceCheck(arguments.binder, "wirebox.system.ioc.config.Binder") ){ + if( NOT isInstanceOf( arguments.binder, "wirebox.system.ioc.config.Binder" ) ){ // simple data cfc, create native binder and decorate data CFC nativeBinder = createObject("component","wirebox.system.ioc.config.Binder").init(injector=this,config=arguments.binder,properties=arguments.properties); } diff --git a/src/cfml/system/wirebox/system/ioc/Provider.cfc b/src/cfml/system/wirebox/system/ioc/Provider.cfc index fa4df9594..07124f5f0 100644 --- a/src/cfml/system/wirebox/system/ioc/Provider.cfc +++ b/src/cfml/system/wirebox/system/ioc/Provider.cfc @@ -1,7 +1,7 @@  - - - - - - - - - - - super.init(argumentCollection=arguments); - - // ColdSpring Factory Path - instance.COLDSPRING2_FACTORY_PATH = "coldspring.beans.xml.XmlBeanFactory"; - - return this; - - - - - - - - - var properties = getProperties(); - - //Create the Coldspring Factory - instance.factory = createObject("component", instance.COLDSPRING2_FACTORY_PATH ).init( getDefinitionFile() , properties); - - - - - - - - return getFactory().getBean(arguments.beanName); - - - - - - - - return getFactory().containsBean(arguments.beanName); - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/cfml/system/wirebox/system/ioc/adapters/ColdSpringAdapter.cfc b/src/cfml/system/wirebox/system/ioc/adapters/ColdSpringAdapter.cfc deleted file mode 100644 index 04e2b89ce..000000000 --- a/src/cfml/system/wirebox/system/ioc/adapters/ColdSpringAdapter.cfc +++ /dev/null @@ -1,78 +0,0 @@ - - - - - - - - - - - - super.init(argumentCollection=arguments); - - // ColdSpring Factory Path - instance.COLDSPRING_FACTORY_PATH = "coldspring.beans.DefaultXmlBeanFactory"; - - return this; - - - - - - - - - var properties = getProperties(); - - //Create the Coldspring Factory - instance.factory = createObject("component", instance.COLDSPRING_FACTORY_PATH ).init(structnew(),properties); - - // Load Bean Definitions - instance.factory.loadBeans( getDefinitionFile() ); - - - - - - - - return getFactory().getBean(arguments.beanName); - - - - - - - - return getFactory().containsBean(arguments.beanName); - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/cfml/system/wirebox/system/ioc/adapters/LightWireAdapter.cfc b/src/cfml/system/wirebox/system/ioc/adapters/LightWireAdapter.cfc deleted file mode 100644 index 5f176bdb4..000000000 --- a/src/cfml/system/wirebox/system/ioc/adapters/LightWireAdapter.cfc +++ /dev/null @@ -1,118 +0,0 @@ - - - - - - - - - - - - super.init(argumentCollection=arguments); - - instance.utility = createObject("component","wirebox.system.core.util.Util"); - - // LightWire Factory Path - instance.LIGHTWIRE_FACTORY_PATH = "lightwire.LightWire"; - - return this; - - - - - - - - - var properties = getProperties(); - - //Create the lightwire Factory - instance.factory = createObject("component", instance.LIGHTWIRE_FACTORY_PATH ).init( createLightwireConfigBean() ); - - - - - - - - - return getFactory().getBean(arguments.beanName); - - - - - - - - return getFactory().containsBean(arguments.beanName); - - - - - - - - - - - - - - - - - - - - var lightwireBeanConfig = ""; - var isUsingXML = listLast(getDefinitionFile(),".") eq "xml" or listLast(getDefinitionFile(),".") eq "cfm"; - - // Create the lightwire Config Bean. - if( NOT isUsingXML ){ - // Create the declared config bean, but do not init it - lightwireBeanConfig = createObject("component", getDefinitionFile()); - } - else{ - // Create base config Bean - lightwireBeanConfig = CreateObject("component", "lightwire.BaseConfigObject").init(); - } - - // Are we using ColdBox Application Container? If so, then do mixins. - if( isObject(getColdBox()) ){ - lightWireBeanConfig.injectMixin = instance.utility.getMixerUtil().injectMixin; - lightWireBeanConfig.injectMixin( "getController", variables.getController ); - lightwireBeanConfig.controller = getColdBox(); - } - - // Do we need to configure - if( isUsingXML ){ - // Read in and parse the XML - lightwireBeanConfig.parseXMLConfigFile( getDefinitionFile(), getProperties()); - return lightwireBeanConfig; - } - else{ - return lightwireBeanConfig.init(); - } - - - - - - - - - \ No newline at end of file diff --git a/src/cfml/system/wirebox/system/ioc/adapters/WireBoxAdapter.cfc b/src/cfml/system/wirebox/system/ioc/adapters/WireBoxAdapter.cfc deleted file mode 100644 index 043809f76..000000000 --- a/src/cfml/system/wirebox/system/ioc/adapters/WireBoxAdapter.cfc +++ /dev/null @@ -1,74 +0,0 @@ - - - - - - - - - - - - super.init(argumentCollection=arguments); - - instance.utility = createObject("component","wirebox.system.core.util.Util"); - - // WireBox Factory Path - instance.WIREBOX_FACTORY_PATH = "wirebox.system.ioc.Injector"; - - return this; - - - - - - - - - //Create a WireBox injector - instance.factory = createObject("component", instance.WIREBOX_FACTORY_PATH ).init(binder=getDefinitionFile(),properties=getProperties(),coldbox=getColdbox()); - - - - - - - - return getFactory().getInstance(arguments.beanName); - - - - - - - - return getFactory().containsInstance(arguments.beanName); - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/cfml/system/wirebox/system/ioc/config/Binder.cfc b/src/cfml/system/wirebox/system/ioc/config/Binder.cfc index b5b8a96cb..8ff02b59f 100644 --- a/src/cfml/system/wirebox/system/ioc/config/Binder.cfc +++ b/src/cfml/system/wirebox/system/ioc/config/Binder.cfc @@ -1,7 +1,7 @@  + + + + + + - + - + @@ -304,10 +311,11 @@ Description : - + + // generate mapping entry for this dude. var name = ""; @@ -320,6 +328,12 @@ Description : // first entry name = arguments.alias[1]; + // check if mapping exists, if so, just use and return. + if( structKeyExists( instance.mappings, name) and !arguments.force ){ + currentMapping = instance.mappings[ name ]; + return this; + } + // generate the mapping for the first name passed instance.mappings[ name ] = createObject("component","wirebox.system.ioc.config.Mapping").init( name ); @@ -497,9 +511,9 @@ Description : currentMapping = instance.mappings[arguments.alias]; return this; } - this.utility.throwit(message="The mapping '#arguments.alias# has not been initialized yet.'", - detail="Please use the map('#arguments.alias#') first to start working with a mapping", - type="Binder.InvalidMappingStateException"); + throw(message="The mapping '#arguments.alias# has not been initialized yet.'", + detail="Please use the map('#arguments.alias#') first to start working with a mapping", + type="Binder.InvalidMappingStateException"); @@ -574,9 +588,9 @@ Description : // check if invalid scope if( NOT this.SCOPES.isValidScope(arguments.scope) AND NOT structKeyExists(instance.customScopes,arguments.scope) ){ - this.utility.throwit(message="Invalid WireBox Scope: '#arguments.scope#'", - detail="Please make sure you are using a valid scope, valid scopes are: #arrayToList(this.SCOPES.getValidScopes())# AND custom scopes: #structKeyList(instance.customScopes)#", - type="Binder.InvalidScopeMapping"); + throw( message="Invalid WireBox Scope: '#arguments.scope#'", + detail="Please make sure you are using a valid scope, valid scopes are: #arrayToList(this.SCOPES.getValidScopes())# AND custom scopes: #structKeyList(instance.customScopes)#", + type="Binder.InvalidScopeMapping" ); } currentMapping.setScope( arguments.scope ); return this; @@ -606,6 +620,15 @@ Description : + + + + + currentMapping.setInfluenceClosure( arguments.influenceClosure ); + return this; + + + @@ -815,7 +838,7 @@ Description : if( structKeyExists( wireBoxDSL, "logBoxConfig") ){ logBoxConfig(wireBoxDSL.logBoxConfig); } - + // Register Parent Injector if( structKeyExists( wireBoxDSL, "parentInjector") ){ parentInjector( wireBoxDSL.parentInjector ); diff --git a/src/cfml/system/wirebox/system/ioc/config/DefaultBinder.cfc b/src/cfml/system/wirebox/system/ioc/config/DefaultBinder.cfc index 0f099ac9e..bb2709110 100644 --- a/src/cfml/system/wirebox/system/ioc/config/DefaultBinder.cfc +++ b/src/cfml/system/wirebox/system/ioc/config/DefaultBinder.cfc @@ -1,7 +1,7 @@  + + + + + + + + + @@ -371,6 +383,7 @@ Description : + var def = getDIDefinition(); var x = 1; @@ -395,6 +408,7 @@ Description : + var def = getDIDefinition(); var x = 1; @@ -428,6 +442,7 @@ Description : + var def = getDIDefinition(); var x = 1; @@ -549,9 +564,14 @@ Description : + + + + + - + if( NOT instance.discovered ){ // announce inspection @@ -741,9 +761,9 @@ Description : case "regex" : { classMatcher = arguments.binder.match().regex( getToken(arguments.metadata.classMatcher,2,":") ); break; } default: { // throw, no matching matchers - arguments.binder.utility.throwIt(message="Invalid Class Matcher: #classes#", - type="Mapping.InvalidAOPClassMatcher", - detail="Valid matchers are 'any,annotatedWith:annotation,annotatedWith:annotation:value,mappings:XXX,instanceOf:XXX,regex:XXX'"); + throw(message="Invalid Class Matcher: #classes#", + type="Mapping.InvalidAOPClassMatcher", + detail="Valid matchers are 'any,annotatedWith:annotation,annotatedWith:annotation:value,mappings:XXX,instanceOf:XXX,regex:XXX'"); } } @@ -766,9 +786,9 @@ Description : case "regex" : { methodMatcher = arguments.binder.match().regex( getToken(arguments.metadata.methodMatcher,2,":") ); break; } default: { // throw, no matching matchers - arguments.binder.utility.throwIt(message="Invalid Method Matcher: #classes#", - type="Mapping.InvalidAOPMethodMatcher", - detail="Valid matchers are 'any,annotatedWith:annotation,annotatedWith:annotation:value,methods:XXX,instanceOf:XXX,regex:XXX'"); + throw(message="Invalid Method Matcher: #classes#", + type="Mapping.InvalidAOPMethodMatcher", + detail="Valid matchers are 'any,annotatedWith:annotation,annotatedWith:annotation:value,methods:XXX,instanceOf:XXX,regex:XXX'"); } } @@ -797,8 +817,12 @@ Description : if( structKeyExists(md.properties[x],"inject") ){ // prepare default params, we do this so we do not alter the md as it is cached by cf params = { - scope="variables", inject="model", name=md.properties[x].name, required=true + scope="variables", inject="model", name=md.properties[x].name, required=true, type="any" }; + // default property type + if( structKeyExists( md.properties[ x ], "type" ) ){ + params.type = md.properties[ x ].type; + } // default injection scope, if not found in object if( structKeyExists(md.properties[x],"scope") ){ params.scope = md.properties[x].scope; @@ -812,7 +836,7 @@ Description : params.required = md.properties[ x ].required; } // Add to property to mappings - addDIProperty( name=params.name, dsl=params.inject, scope=params.scope, required=params.required ); + addDIProperty( name=params.name, dsl=params.inject, scope=params.scope, required=params.required, type=params.type ); } } @@ -836,9 +860,12 @@ Description : // prepare params as we do not alter md as cf caches it params = { - required = false, inject="model",name=md.functions[x].parameters[y].name + required = false, inject="model", name=md.functions[x].parameters[y].name, type="any" }; - + // check type annotation + if( structKeyExists( md.functions[ x ].parameters[ y ], "type" ) ){ + params.type = md.functions[ x ].parameters[ y ].type; + } // Check required annotation if( structKeyExists(md.functions[x].parameters[y], "required") ){ params.required = md.functions[x].parameters[y].required; @@ -854,7 +881,8 @@ Description : // ADD Constructor argument addDIConstructorArgument(name=params.name, dsl=params.inject, - required=params.required); + required=params.required, + type=params.type); } } diff --git a/src/cfml/system/wirebox/system/ioc/dsl/CacheBoxDSL.cfc b/src/cfml/system/wirebox/system/ioc/dsl/CacheBoxDSL.cfc index c553c8df9..87472a370 100644 --- a/src/cfml/system/wirebox/system/ioc/dsl/CacheBoxDSL.cfc +++ b/src/cfml/system/wirebox/system/ioc/dsl/CacheBoxDSL.cfc @@ -1,7 +1,7 @@  - - - - - var oWebservices = instance.coldbox.getPlugin("Webservices"); - var thisType = arguments.definition.dsl; - var thisTypeLen = listLen(thisType,":"); - - switch(thisTypeLen){ - // webservice, take name from property as default. - case 1: { return oWebservices.getWSobj( arguments.definition.name ); break; } - // webservice:alias - case 2: { return oWebservices.getWSobj( getToken(thisType,2,":") ); break; } - } - - - - - - - - - var className = listLast(arguments.definition.dsl,":"); - - // Get Dependency, if not found, exception is thrown - return instance.coldbox.getPlugin("JavaLoader").create( className ); - - - @@ -99,7 +66,7 @@ Description : // Support shortcut for specifying name in the definition instead of the DSl for supporting namespaces if( thisTypeLen eq 2 - and listFindNoCase("setting,fwSetting,plugin,myplugin,datasource,interceptor",listLast(thisType,":")) + and listFindNoCase("setting,fwSetting,datasource,interceptor",listLast(thisType,":")) and len(thisName)){ // Add the additional alias to the DSL thisType = thisType & ":" & thisName; @@ -115,18 +82,15 @@ Description : thisLocationKey = getToken(thisType,2,":"); switch( thisLocationKey ){ case "flash" : { return instance.coldbox.getRequestService().getFlashScope(); } - case "fwconfigbean" : { return createObject("component","wirebox.system.core.collections.ConfigBean").init( instance.coldbox.getColdboxSettings() ); } - case "configbean" : { return createObject("component","wirebox.system.core.collections.ConfigBean").init( instance.coldbox.getConfigSettings() ); } - case "mailsettingsbean" : { return createObject("component","wirebox.system.core.mail.MailSettingsBean").init(argumentCollection=instance.coldbox.getSetting("mailSettings")); } case "loaderService" : { return instance.coldbox.getLoaderService(); } case "requestService" : { return instance.coldbox.getrequestService(); } - case "debuggerService" : { return instance.coldbox.getDebuggerService();} - case "pluginService" : { return instance.coldbox.getPluginService(); } case "handlerService" : { return instance.coldbox.gethandlerService(); } case "interceptorService" : { return instance.coldbox.getinterceptorService(); } - case "cacheManager" : { return instance.coldbox.getColdboxOCM(); } case "moduleService" : { return instance.coldbox.getModuleService(); } - case "validationManager" : { return instance.coldbox.getValidationManager(); } + case "renderer" : { return instance.coldbox.getRenderer(); } + case "dataMarshaller" : { return instance.coldbox.getDataMarshaller(); } + case "configSettings" : { return instance.coldbox.getConfigSettings(); } + case "fwSettings" : { return instance.coldbox.getColdboxSettings(); } } // end of services break; @@ -147,8 +111,8 @@ Description : instance.log.debug("The module requested: #listlast(thisLocationKey,"@")# does not exist in the loaded modules. Loaded modules are #structKeyList(moduleSettings)#"); } } - // normal custom plugin - return instance.coldbox.getSetting(thisLocationKey); + // just get setting + return instance.coldbox.getSetting( thisLocationKey ); } case "modulesettings" : { moduleSettings = instance.coldbox.getSetting("modules"); @@ -169,15 +133,6 @@ Description : } } case "fwSetting" : { return instance.coldbox.getSetting(thisLocationKey,true); } - case "plugin" : { return instance.coldbox.getPlugin(thisLocationKey);} - case "myplugin" : { - // module plugin - if( find("@",thisLocationKey) ){ - return instance.coldbox.getPlugin(plugin=listFirst(thisLocationKey,"@"),customPlugin=true,module=listLast(thisLocationKey,"@")); - } - // normal custom plugin - return instance.coldbox.getPlugin(plugin=thisLocationKey,customPlugin=true); - } case "datasource" : { return getDatasource(thisLocationKey); } case "interceptor" : { return instance.coldbox.getInterceptorService().getInterceptor(thisLocationKey,true); } }//end of services @@ -192,59 +147,12 @@ Description : - - - - - - var thisTypeLen = listLen(arguments.definition.dsl,":"); - var beanName = ""; - var oIOC = instance.coldbox.getPlugin("IOC"); - - // DSL stages - switch(thisTypeLen){ - // ioc only, so get name from definition - case 1: { beanName = arguments.definition.name; break;} - // ioc:beanName, so get it from here - case 2: { beanName = getToken(arguments.definition.dsl,2,":"); break;} - } - - // Check for Bean existence first - if( oIOC.containsBean(beanName) ){ - return oIOC.getBean(beanName); - } - else if( instance.log.canDebug() ){ - instance.log.debug("getIOCDSL() cannot find IOC Bean: #beanName# using definition: #arguments.definition.toString()#"); - } - - - - var thisTypeLen = listLen(arguments.definition.dsl,":"); - var cacheKey = ""; - var cache = instance.cacheBox.getCache('default'); - var refLocal = {}; - - // DSL stages - switch(thisTypeLen){ - // ocm only - case 1: { cacheKey = arguments.definition.name; break;} - // ocm:objectKey - case 2: { cacheKey = getToken(arguments.definition.dsl,2,":"); break;} - } - - // Verify that dependency exists in the Cache container - refLocal.target = cache.get( cacheKey ); - if( structKeyExists(refLocal, "target") ){ - return refLocal.target; - } - else if( instance.log.canDebug() ){ - instance.log.debug("getOCMDSL() cannot find cache Key: #cacheKey# using definition: #arguments.definition.toString()#"); - } + throw( "This DSL has been deprecated in favor of the 'cachebox' Namespace." ); diff --git a/src/cfml/system/wirebox/system/ioc/dsl/IDSLBuilder.cfc b/src/cfml/system/wirebox/system/ioc/dsl/IDSLBuilder.cfc index ffe8a21e5..ed0358f67 100644 --- a/src/cfml/system/wirebox/system/ioc/dsl/IDSLBuilder.cfc +++ b/src/cfml/system/wirebox/system/ioc/dsl/IDSLBuilder.cfc @@ -1,7 +1,7 @@  - + // double lock it if( NOT instance.scopeStorage.exists(cacheKey, CFScope) ){ diff --git a/src/cfml/system/wirebox/system/ioc/scopes/CacheBox.cfc b/src/cfml/system/wirebox/system/ioc/scopes/CacheBox.cfc index c82e2ff3f..c44efca84 100644 --- a/src/cfml/system/wirebox/system/ioc/scopes/CacheBox.cfc +++ b/src/cfml/system/wirebox/system/ioc/scopes/CacheBox.cfc @@ -1,7 +1,7 @@  - + // Double get just in case of race conditions refLocal.target = cacheProvider.get( cacheKey ); diff --git a/src/cfml/system/wirebox/system/ioc/scopes/IScope.cfc b/src/cfml/system/wirebox/system/ioc/scopes/IScope.cfc index 2265e82ce..64daa3f75 100644 --- a/src/cfml/system/wirebox/system/ioc/scopes/IScope.cfc +++ b/src/cfml/system/wirebox/system/ioc/scopes/IScope.cfc @@ -1,7 +1,7 @@  - + // double lock it if( NOT structKeyExists(instance.singletons, cacheKey) ){ diff --git a/src/cfml/system/wirebox/system/logging/AbstractAppender.cfc b/src/cfml/system/wirebox/system/logging/AbstractAppender.cfc index 0f13ad861..a0f9bed1d 100644 --- a/src/cfml/system/wirebox/system/logging/AbstractAppender.cfc +++ b/src/cfml/system/wirebox/system/logging/AbstractAppender.cfc @@ -1,7 +1,7 @@  @@ -46,23 +46,23 @@ Description : // Appender's Name instance.name = REreplacenocase(arguments.name, "[^0-9a-z]","","ALL"); - - // Set internal properties + + // Set internal properties instance.properties = arguments.properties; - + //Custom Layout? if( len(trim(arguments.layout)) ){ instance.customLayout = createObject("component",arguments.layout).init(this); } - + // Levels instance.levelMin = arguments.levelMin; instance.levelMax = arguments.levelMax; - + return this; - + @@ -72,7 +72,7 @@ Description : - + @@ -86,11 +86,11 @@ Description : instance.levelMin = arguments.levelMin; } else{ - $throw("Invalid Log Level","The log level #arguments.levelMin# is invalid or greater than the levelMax (#getLevelMax()#). Valid log levels are from 0 to 5","AbstractAppender.InvalidLogLevelException"); + throw("Invalid Log Level","The log level #arguments.levelMin# is invalid or greater than the levelMax (#getLevelMax()#). Valid log levels are from 0 to 5","AbstractAppender.InvalidLogLevelException"); } - + @@ -104,11 +104,11 @@ Description : instance.levelMax = arguments.levelMax; } else{ - $throw("Invalid Log Level","The log level #arguments.levelMax# is invalid or less than the levelMin (#getLevelMin()#). Valid log levels are from 0 to 5","AbstractAppender.InvalidLogLevelException"); + throw("Invalid Log Level","The log level #arguments.levelMax# is invalid or less than the levelMin (#getLevelMin()#). Valid log levels are from 0 to 5","AbstractAppender.InvalidLogLevelException"); } - + @@ -117,33 +117,33 @@ Description : - + - + - + - + - + - + @@ -152,15 +152,15 @@ Description : - + - + - + @@ -170,48 +170,48 @@ Description : - + - + - + - + - + - + - + - + - + if( structKeyExists(instance,"util") ){ return instance.util; } instance.util = createObject("component","wirebox.system.core.util.Util"); return instance.util; - + @@ -219,33 +219,4 @@ Description : - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/cfml/system/wirebox/system/logging/Layout.cfc b/src/cfml/system/wirebox/system/logging/Layout.cfc index 2f858bf9f..3a1448f76 100644 --- a/src/cfml/system/wirebox/system/logging/Layout.cfc +++ b/src/cfml/system/wirebox/system/logging/Layout.cfc @@ -1,7 +1,7 @@  @@ -21,25 +21,25 @@ Description : // The log levels enum as a public property this.logLevels = createObject("component","wirebox.system.logging.LogLevels"); - + // private instance scope instance = structnew(); // LogBox Unique ID - instance.logboxID = createObject('java','java.lang.System').identityHashCode(this); + instance.logboxID = createObject('java','java.lang.System').identityHashCode(this); // Appenders instance.appenderRegistry = structnew(); // Loggers instance.loggerRegistry = structnew(); // Category Appenders - instance.categoryAppenders = ""; + instance.categoryAppenders = ""; // Version - instance.version = "1.8.0.00056"; + instance.version = "2.1.0+00002"; // Configuration object instance.config = ""; // ColdBox Application Link - instance.coldbox = ""; + instance.coldbox = ""; - + @@ -47,15 +47,15 @@ Description : // Check if linking ColdBox if( isObject(arguments.coldbox) ){ instance.coldbox = arguments.coldbox; } - + // Configure LogBox configure(arguments.config); - + // Return LogBox return this; - + @@ -66,26 +66,26 @@ Description : var rootConfig = ""; var args = structnew(); - + // Store config object instance.config = arguments.config; // Validate configuration instance.config.validate(); - + // Reset Registries instance.appenderRegistry = structnew(); instance.loggerRegistry = structnew(); - + //Get appender definitions appenders = instance.config.getAllAppenders(); - + // Register All Appenders configured for( key in appenders ){ registerAppender(argumentCollection=appenders[key]); } - + // Get Root def rootConfig = instance.config.getRoot(); // Create Root Logger @@ -94,19 +94,19 @@ Description : args.levelMax = rootConfig.levelMax; args.appenders = getAppendersMap(rootConfig.appenders); oRoot = createObject("component","wirebox.system.logging.Logger").init(argumentCollection=args); - + //Save in Registry instance.loggerRegistry = structnew(); instance.loggerRegistry["ROOT"] = oRoot; - + - + @@ -127,13 +127,13 @@ Description : var categoryConfig = ""; var oLogger = ""; var root = instance.loggerRegistry["ROOT"]; - + // is category object? if( isObject(arguments.category) ){ arguments.category = getMetadata(arguments.category).name; } - + //trim cat, just in case arguments.category = trim(arguments.category); - + //Is logger by category name created already? if( structKeyExists(instance.loggerRegistry,arguments.category) ){ return instance.loggerRegistry[arguments.category]; @@ -155,14 +155,14 @@ Description : // Setup the category levels according to parent found. args.levelMin = root.getLevelMin(); args.levelMax = root.getLevelMax(); - } + } if( NOT structKeyExists(instance.loggerRegistry,arguments.category) ){ - // Create logger + // Create logger oLogger = createObject("component","wirebox.system.logging.Logger").init(argumentCollection=args); // Inject Root Logger oLogger.setRootLogger(root); @@ -171,15 +171,15 @@ Description : } - + - + - + @@ -193,11 +193,11 @@ Description : - + - + @@ -220,54 +220,53 @@ Description : - + // Get parent category name shortened by one. var parentCategory = ""; - + // category len check if( len(arguments.category) ){ parentCategory = listDeleteAt(arguments.category, listLen(arguments.category,"."), "."); } - + // Check if parent Category is empty if( len(parentCategory) EQ 0 ){ // Just return the root logger, nothing found. return instance.loggerRegistry["ROOT"]; - } + } // Does it exist already in the instantiated loggers? if( structKeyExists(instance.loggerRegistry,parentCategory) ){ return instance.loggerRegistry[parentCategory]; } // Do we need to create it, lazy loading? if( instance.config.categoryExists(parentCategory) ){ - return getLogger(parentCategory); + return getLogger(parentCategory); } // Else, it was not located, recurse - return locateCategoryParentLogger(parentCategory); + return locateCategoryParentLogger(parentCategory); - + - var x =1; var appendersMap = structnew(); - + // Go over appender's list and configure it - for(x=1; x lte listlen(arguments.appenders); x=x+1){ - thisAppender = listGetAt(arguments.appenders,x); - appendersMap[thisAppender] = instance.appenderRegistry[thisAppender]; + arguments.appenders = listToArray( arguments.appenders ); + for( var thisAppender in arguments.appenders ){ + appendersMap[ thisAppender ] = instance.appenderRegistry[ thisAppender ]; } - + return appendersMap; - + diff --git a/src/cfml/system/wirebox/system/logging/LogEvent.cfc b/src/cfml/system/wirebox/system/logging/LogEvent.cfc index 97c10d046..6cd223318 100644 --- a/src/cfml/system/wirebox/system/logging/LogEvent.cfc +++ b/src/cfml/system/wirebox/system/logging/LogEvent.cfc @@ -1,7 +1,7 @@  - - // All Available Logging Levels for LogBox this.OFF = -1; this.FATAL = 0; @@ -66,6 +63,4 @@ Description : function isLevelValid(level){ return ( arguments.level gte this.MINLEVEL AND arguments.level lte this.MAXLEVEL ); } - - - \ No newline at end of file +} \ No newline at end of file diff --git a/src/cfml/system/wirebox/system/logging/Logger.cfc b/src/cfml/system/wirebox/system/logging/Logger.cfc index dcdf421c2..0dc07b27d 100644 --- a/src/cfml/system/wirebox/system/logging/Logger.cfc +++ b/src/cfml/system/wirebox/system/logging/Logger.cfc @@ -1,7 +1,7 @@  @@ -37,19 +39,19 @@ Description : - + // Save Properties - instance.category = arguments.category; - instance.appenders = arguments.appenders; - + instance.category = arguments.category; + instance.appenders = arguments.appenders; + // Set logging levels setLevelMin( arguments.levelMin ); setLevelMax( arguments.levelMax ); - + return this; - + @@ -67,32 +69,32 @@ Description : - + - + - + if( structKeyExists(instance.appenders,arguments.name) ){ return instance.appenders[arguments.name]; } else{ - $throw(message="Appender #arguments.name# does not exist.", + throw(message="Appender #arguments.name# does not exist.", detail="The appenders registered are #structKeyList(getAppenders())#", type="Logger.AppenderNotFound"); } - + @@ -108,43 +110,43 @@ Description : var name= ""; //Verify Appender's name if( NOT len(arguments.newAppender.getName()) ){ - $throw(message="Appender does not have a name, please instantiate the appender with a unique name.",type="Logger.InvalidAppenderNameException"); + throw(message="Appender does not have a name, please instantiate the appender with a unique name.",type="Logger.InvalidAppenderNameException"); } // Get name - name = arguments.newAppender.getName(); + name = arguments.newAppender.getName(); - + - if( NOT appenderExists(name) ){ + if( NOT appenderExists(name) ){ // Store Appender instance.appenders[name] = arguments.newAppender; - + // run registration event if not Initialized if( NOT arguments.newAppender.isInitialized() ){ arguments.newAppender.onRegistration(); arguments.newAppender.setInitialized(true); - } + } } - + - + - + if( appenderExists(arguments.name) ){ // Get Appender - appender = instance.appenders[arguments.name]; + appender = instance.appenders[arguments.name]; // Run un-registration event appender.onUnRegistration(); // Now Delete it @@ -155,16 +157,16 @@ Description : - + - + var appenderKeys = structKeyList(getAppenders()); var x=1; - + for( x=1; x lte listLen(appenderKeys); x=x+1){ removeAppender(listGetAt(appenderKeys,x)); } @@ -172,7 +174,7 @@ Description : - + @@ -186,11 +188,11 @@ Description : instance.levelMin = arguments.levelMin; } else{ - $throw("Invalid Log Level","The log level #arguments.levelMin# is invalid or greater than the levelMax (#getLevelMax()#). Valid log levels are from 0 to 5","Logger.InvalidLogLevelException"); + throw("Invalid Log Level","The log level #arguments.levelMin# is invalid or greater than the levelMax (#getLevelMax()#). Valid log levels are from 0 to 5","Logger.InvalidLogLevelException"); } - + @@ -204,11 +206,11 @@ Description : instance.levelMax = arguments.levelMax; } else{ - $throw("Invalid Log Level","The log level #arguments.levelMax# is invalid or less than the levelMin (#getLevelMin()#). Valid log levels are from 0 to 5","Logger.InvalidLogLevelException"); + throw("Invalid Log Level","The log level #arguments.levelMax# is invalid or less than the levelMin (#getLevelMin()#). Valid log levels are from 0 to 5","Logger.InvalidLogLevelException"); } - + @@ -231,7 +233,7 @@ Description : logMessage(argumentCollection=arguments); - + @@ -243,7 +245,7 @@ Description : logMessage(argumentCollection=arguments); - + @@ -255,7 +257,7 @@ Description : logMessage(argumentCollection=arguments); - + @@ -267,7 +269,7 @@ Description : logMessage(argumentCollection=arguments); - + @@ -279,7 +281,7 @@ Description : logMessage(argumentCollection=arguments); - + @@ -288,91 +290,101 @@ Description : - var key = ""; var thisAppender = ""; - var appenders = ""; - var logEvent = ""; var target = this; - + // Verify severity, if invalid, default to INFO if( NOT this.logLevels.isLevelValid(arguments.severity) ){ arguments.severity = this.logLevels.INFO; } - + // If message empty, just exit arguments.message = trim(arguments.message); if( NOT len(arguments.message) ){ return; } - + //Is Logging Enabled? if( getLevelMin() eq this.logLevels.OFF ){ return; } - + // Can we log on target - if( canLog(arguments.severity) ){ + if( canLog( arguments.severity ) ){ // Create Logging Event arguments.category = target.getCategory(); - logEvent = createobject("component","wirebox.system.logging.LogEvent").init(argumentCollection=arguments); - + var logEvent = new wirebox.system.logging.LogEvent( argumentCollection=arguments ); + // Do we have appenders locally? or go to root Logger if( NOT hasAppenders() ){ target = getRootLogger(); - } + } // Get appenders - appenders = target.getAppenders(); + var appenders = target.getAppenders(); // Delegate Calls to appenders - for(key in appenders){ + for( var key in appenders ){ // Get Appender - thisAppender = appenders[key]; + thisAppender = appenders[ key ]; // Log the message in the appender if the appender allows it - if( thisAppender.canLog(arguments.severity) ){ - thisAppender.logMessage(logEvent); + if( thisAppender.canLog( arguments.severity ) ){ + + // check to see if the async property was passed during definition + if( thisAppender.propertyExists( 'async' ) && thisAppender.getProperty( 'async' ) ) { + // prepare threading variables. + var threadName = "logMessage_#replace( createUUID(), "-", "", "all" )#"; + // Are we in a thread already? + if( instance.util.inThread() ) { + thisAppender.logMessage( logEvent ); + } else { + // Thread this puppy + thread action="run" name="#threadName#" logEvent="#logEvent#" thisAppender="#thisAppender#"{ + attributes.thisAppender.logMessage( attributes.logEvent ); + } + } + } else { + thisAppender.logMessage( logEvent ); + } } } - } - + } + - + - return (arguments.level GTE getLevelMin() AND arguments.level LTE getLevelMax() ); + // If numeric, do a comparison immediately. + if( isNumeric( arguments.level ) ){ + return ( arguments.level GTE getLevelMin() AND arguments.level LTE getLevelMax() ); + } + // Else it is a string + var targetLevel = this.LogLevels.lookupAsInt( arguments.level ); + return ( canLog( targetLevel ) ); - + - + - + - + - + - + - - - - - - - - - - + \ No newline at end of file diff --git a/src/cfml/system/wirebox/system/logging/appenders/AsyncDBAppender.cfc b/src/cfml/system/wirebox/system/logging/appenders/AsyncDBAppender.cfc deleted file mode 100644 index 4c2d58deb..000000000 --- a/src/cfml/system/wirebox/system/logging/appenders/AsyncDBAppender.cfc +++ /dev/null @@ -1,83 +0,0 @@ - - - - - - - - - - - - - - // Init supertype - super.init(argumentCollection=arguments); - // strong reference to super scope if not cf9 and below choke on high load and cfthread - variables.$super = super; - return this; - - - - - - - - - - - var uuid = createobject("java", "java.util.UUID").randomUUID(); - var threadName = "#getname()#_logMessage_#replace(uuid,"-","","all")#"; - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/cfml/system/wirebox/system/logging/appenders/AsyncFileAppender.cfc b/src/cfml/system/wirebox/system/logging/appenders/AsyncFileAppender.cfc deleted file mode 100644 index 3014781b7..000000000 --- a/src/cfml/system/wirebox/system/logging/appenders/AsyncFileAppender.cfc +++ /dev/null @@ -1,95 +0,0 @@ - - - - - - - - - - - - - - - - super.init(argumentCollection=arguments); - - return this; - - - - - - - - - - var uuid = createobject("java", "java.util.UUID").randomUUID(); - var ThreadName = "#getname()#_logMessage_#replace(uuid,"-","","all")#"; - var loge = arguments.logEvent; - var timestamp = loge.getTimestamp(); - var message = loge.getMessage(); - var extra = ""; - var entry = ""; - - // Does file still exist? - if( NOT fileExists(getLogFullpath()) ){ - ensureDefaultLogDirectory(); - initLogLocation(); - } - - // Custom Layout? - if( hasCustomLayout() ){ - entry = getCustomLayout().format(loge); - } - else{ - // Cleanup main message - message = replace(message,'"','""',"all"); - message = replace(message,"#chr(13)##chr(10)#",' ',"all"); - message = replace(message,chr(13),' ',"all"); - if( len(loge.getExtraInfoAsString()) ){ - message &= " ExtraInfo:" & loge.getExtraInfoAsString(); - } - - // Prepare Entry - entry = '"#severityToString(logEvent.getSeverity())#","#getname()#","#dateformat(timestamp,"MM/DD/YYYY")#","#timeformat(timestamp,"HH:MM:SS")#","#loge.getCategory()#","#message#"'; - } - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/cfml/system/wirebox/system/logging/appenders/AsyncRollingFileAppender.cfc b/src/cfml/system/wirebox/system/logging/appenders/AsyncRollingFileAppender.cfc deleted file mode 100644 index 77e80e635..000000000 --- a/src/cfml/system/wirebox/system/logging/appenders/AsyncRollingFileAppender.cfc +++ /dev/null @@ -1,79 +0,0 @@ - - - - - - - - - - - - - - - - super.init(argumentCollection=arguments); - - if( NOT propertyExists("fileMaxSize") OR NOT isNumeric(getProperty("fileMaxSize")) ){ - setProperty("fileMaxSize","2000"); - } - if( NOT propertyExists("fileMaxArchives") OR NOT isNumeric(getProperty("fileMaxArchives")) ){ - setProperty("fileMaxArchives","2"); - } - - instance.fileRotator = createObject("component","wirebox.system.logging.util.FileRotator").init(); - - // strong reference to super scope if not cf9 and below choke on high load and cfthread - variables.$super = super; - - return this; - - - - - - - - - - // Log the message in the super. - variables.$super.logMessage(arguments.logEvent); - - // Rotate - try{ - instance.fileRotator.checkRotation(this); - } - catch(Any e){ - $log("ERROR","Could not zip and rotate log files in #getName()#. #e.message# #e.detail#"); - } - - - - - - - \ No newline at end of file diff --git a/src/cfml/system/wirebox/system/logging/appenders/CFAppender.cfc b/src/cfml/system/wirebox/system/logging/appenders/CFAppender.cfc index a4e7201f3..ea08d5ffc 100644 --- a/src/cfml/system/wirebox/system/logging/appenders/CFAppender.cfc +++ b/src/cfml/system/wirebox/system/logging/appenders/CFAppender.cfc @@ -1,7 +1,7 @@  - - - - - - - - - - - - - // Init supertype - super.init(argumentCollection=arguments); - - return this; - - - - - - - - - - var loge = arguments.logEvent; - var entry = ""; - var traceSeverity = "information"; - var severityStyle = ""; - var severity = severityToString(loge.getseverity()); - - // Severity Styles - switch(severity){ - case "FATAL" : { severityStyle = "fw_redText"; break;} - case "ERROR" : { severityStyle = "fw_orangeText"; break;} - case "WARN" : { severityStyle = "fw_greenText"; break;} - case "INFO" : { severityStyle = "fw_blackText"; break;} - case "DEBUG" : { severityStyle = "fw_blueText"; break;} - } - - if ( hasCustomLayout() ){ - entry = getCustomLayout().format(loge); - } - else{ - entry = "#severity# #timeFormat(loge.getTimeStamp(),"hh:MM:SS.l tt")# #loge.getCategory()#
    #loge.getMessage()#"; - } - - //send to coldBox debugger - getColdBox().getDebuggerService().pushTracer(entry,loge.getExtraInfo()); -
    -
    - - - - - -
    \ No newline at end of file diff --git a/src/cfml/system/wirebox/system/logging/appenders/ConsoleAppender.cfc b/src/cfml/system/wirebox/system/logging/appenders/ConsoleAppender.cfc index a0452ca3e..224b4957a 100644 --- a/src/cfml/system/wirebox/system/logging/appenders/ConsoleAppender.cfc +++ b/src/cfml/system/wirebox/system/logging/appenders/ConsoleAppender.cfc @@ -1,62 +1,52 @@ - - - - - - - - - - - - - - // Init supertype - super.init(argumentCollection=arguments); - - instance.out = createObject("java","java.lang.System").out; - - return this; - - - - - - - - - - var loge = arguments.logEvent; - var entry = ""; - - if( hasCustomLayout() ){ - entry = getCustomLayout().format(loge); - } - else{ - entry = "#severityToString(loge.getseverity())# #loge.getCategory()# #loge.getmessage()# ExtraInfo: #loge.getextraInfoAsString()#"; - } - - // Log message - instance.out.println(entry); - - - - - - - \ No newline at end of file +} \ No newline at end of file diff --git a/src/cfml/system/wirebox/system/logging/appenders/DBAppender.cfc b/src/cfml/system/wirebox/system/logging/appenders/DBAppender.cfc index 7ab825bd7..3d5cad1f3 100644 --- a/src/cfml/system/wirebox/system/logging/appenders/DBAppender.cfc +++ b/src/cfml/system/wirebox/system/logging/appenders/DBAppender.cfc @@ -1,7 +1,7 @@  - var logBoxDSL = ""; - // Test and load via XML - if( len(trim(arguments.XMLConfig)) ){ - parseAndLoad(xmlParse(arguments.XMLConfig)); - } - // Test and load via Data CFC Path if( structKeyExists(arguments, "CFCConfigPath") ){ arguments.CFCConfig = createObject("component",arguments.CFCConfigPath); @@ -45,7 +40,7 @@ Description : // Test and load via Data CFC if( structKeyExists(arguments,"CFCConfig") and isObject(arguments.CFCConfig) ){ // Decorate our data CFC - arguments.CFCConfig.getPropertyMixin = instance.utility.getMixerUtil().getPropertyMixin; + arguments.CFCConfig.getPropertyMixin = variables.utility.getMixerUtil().getPropertyMixin; // Execute the configuration arguments.CFCConfig.configure(); // Get Data @@ -68,7 +63,7 @@ Description : // Are appenders defined? if( NOT structKeyExists( logBoxDSL, "appenders" ) ){ - instance.utility.throwit("No appenders defined","Please define at least one appender","#getMetadata(this).name#.NoAppendersFound"); + throw("No appenders defined","Please define at least one appender","#getMetadata(this).name#.NoAppendersFound"); } // Register Appenders for( key in logBoxDSL.appenders ){ @@ -78,7 +73,7 @@ Description : // Register Root Logger if( NOT structKeyExists( logBoxDSL, "root" ) ){ - instance.utility.throwit("No Root Logger Defined","Please define the root logger","#getMetadata(this).name#.NoRootLoggerException"); + throw("No Root Logger Defined","Please define the root logger","#getMetadata(this).name#.NoRootLoggerException"); } root(argumentCollection=logBoxDSL.root); @@ -92,22 +87,22 @@ Description : // Register Level Categories if( structKeyExists( logBoxDSL, "debug" ) ){ - DEBUG(argumentCollection=instance.utility.arrayToStruct(logBoxDSL.debug) ); + DEBUG(argumentCollection=variables.utility.arrayToStruct(logBoxDSL.debug) ); } if( structKeyExists( logBoxDSL, "info" ) ){ - INFO(argumentCollection=instance.utility.arrayToStruct(logBoxDSL.info) ); + INFO(argumentCollection=variables.utility.arrayToStruct(logBoxDSL.info) ); } if( structKeyExists( logBoxDSL, "warn" ) ){ - WARN(argumentCollection=instance.utility.arrayToStruct(logBoxDSL.warn) ); + WARN(argumentCollection=variables.utility.arrayToStruct(logBoxDSL.warn) ); } if( structKeyExists( logBoxDSL, "error" ) ){ - ERROR(argumentCollection=instance.utility.arrayToStruct(logBoxDSL.error) ); + ERROR(argumentCollection=variables.utility.arrayToStruct(logBoxDSL.error) ); } if( structKeyExists( logBoxDSL, "fatal" ) ){ - FATAL(argumentCollection=instance.utility.arrayToStruct(logBoxDSL.fatal) ); + FATAL(argumentCollection=variables.utility.arrayToStruct(logBoxDSL.fatal) ); } if( structKeyExists( logBoxDSL, "off" ) ){ - OFF(argumentCollection=instance.utility.arrayToStruct(logBoxDSL.off) ); + OFF(argumentCollection=variables.utility.arrayToStruct(logBoxDSL.off) ); } @@ -152,11 +147,11 @@ Description : // Are appenders defined if( structIsEmpty(instance.appenders) ){ - instance.utility.throwit(message="Invalid Configuration. No appenders defined.",type="#getMetadata(this).name#.NoAppendersFound"); + throw(message="Invalid Configuration. No appenders defined.",type="#getMetadata(this).name#.NoAppendersFound"); } // Check root logger definition if( structIsEmpty(instance.rootLogger) ){ - instance.utility.throwit(message="Invalid Configuration. No root logger defined.",type="#getMetadata(this).name#.RootLoggerNotFound"); + throw(message="Invalid Configuration. No root logger defined.",type="#getMetadata(this).name#.RootLoggerNotFound"); } // All root appenders? @@ -166,7 +161,7 @@ Description : // Check root's appenders for(x=1; x lte listlen(instance.rootLogger.appenders); x=x+1){ if( NOT structKeyExists(instance.appenders, listGetAt(instance.rootLogger.appenders,x)) ){ - instance.utility.throwit(message="Invalid appender in Root Logger", + throw(message="Invalid appender in Root Logger", detail="The appender #listGetAt(instance.rootLogger.appenders,x)# has not been defined yet. Please define it first.", type="#getMetadata(this).name#.AppenderNotFound"); } @@ -182,7 +177,7 @@ Description : for(x=1; x lte listlen(instance.categories[key].appenders); x=x+1){ if( NOT structKeyExists(instance.appenders, listGetAt(instance.categories[key].appenders,x)) ){ - instance.utility.throwit(message="Invalid appender in Category: #key#", + throw(message="Invalid appender in Category: #key#", detail="The appender #listGetAt(instance.categories[key].appenders,x)# has not been defined yet. Please define it first.", type="#getMetadata(this).name#.AppenderNotFound"); } @@ -228,7 +223,7 @@ Description : //Verify appender list if( NOT listLen(arguments.appenders) ){ - instance.utility.throwit("Invalid Appenders","Please send in at least one appender for the root logger","#getMetadata(this).name#.InvalidAppenders"); + throw("Invalid Appenders","Please send in at least one appender for the root logger","#getMetadata(this).name#.InvalidAppenders"); } // Add definition @@ -353,144 +348,6 @@ Description : - - - - - // Get All Appenders - var xml = arguments.xmlDoc; - var appendersXML = xmlSearch(xml,"//Appender"); - var rootXML = xmlSearch(xml,"//Root"); - var categoriesXML = xmlSearch(xml,"//Category"); - var args = structnew(); - var x =1; - var y =1; - - //Register all appenders - for(x=1; x lte arrayLen(appendersXML); x=x+1){ - args = structnew(); - args.properties = structnew(); - thisAppender = appendersXML[x]; - // Error - if( NOT structKeyExists(thisAppender.XMLAttributes,"name") OR NOT - structKeyExists(thisAppender.XMLAttributes,"class") ){ - instance.utility.throwit(message="An appender must have a name and class attribute",type="#getMetadata(this).name#.InvalidAppenderDefinition"); - } - // Construct appender Properties - args.name = trim(thisAppender.XMLAttributes.name); - args.class = trim(thisAppender.XMLAttributes.class); - - //Appender layout? - if( structKeyExists(thisAppender.XMLAttributes,"layout") ){ - args.layout = trim(thisAppender.XMLAttributes.layout); - } - //Appender Levels? - if( structKeyExists(thisAppender.XMLAttributes,"levelMin") ){ - args.levelMin = trim(thisAppender.XMLAttributes.levelMin); - // Numeric Check - if( NOT isNumeric(args.levelMin) ){ - args.levelMin = this.logLevels.lookupAsInt(args.levelMin); - } - } - if( structKeyExists(thisAppender.XMLAttributes,"levelMax") ){ - args.levelMax = trim(thisAppender.XMLAttributes.levelMax); - // Numeric Check - if( NOT isNumeric(args.levelMax) ){ - args.levelMax = this.logLevels.lookupAsInt(args.levelMax); - } - } - - // Check Properties Out - for(y=1; y lte arrayLen(thisAppender.xmlChildren); y=y+1 ){ - args.properties[trim(thisAppender.xmlChildren[y].xmlAttributes.name)] = trim(thisAppender.xmlChildren[y].xmlText); - } - // Register appender - appender(argumentCollection=args); - } - - //Register Root Logger - if( NOT arrayLen(rootXML) ){ - instance.utility.throwit(message="The root element cannot be found and it is mandatory",type="#getMetadata(this).name#.RootLoggerNotFound"); - } - args = structnew(); - if( structKeyExists(rootXML[1].xmlAttributes,"levelMin") ){ - args.levelMin = trim(rootXML[1].xmlAttributes.levelMin); - // Numeric Check - if( NOT isNumeric(args.levelMin) ){ - args.levelMin = this.logLevels.lookupAsInt(args.levelMin); - } - } - if( structKeyExists(rootXML[1].xmlAttributes,"levelMax") ){ - args.levelMax = trim(rootXML[1].xmlAttributes.levelMax); - // Numeric Check - if( NOT isNumeric(args.levelMax) ){ - args.levelMax = this.logLevels.lookupAsInt(args.levelMax); - } - } - - //Root Appenders - if( structKeyExists(rootXML[1].xmlAttributes,"appenders") ){ - args.appenders = trim(rootXML[1].xmlAttributes.appenders); - } - else{ - args.appenders = ""; - for( x=1; x lte arrayLen(rootXML[1].xmlChildren); x=x+1){ - if( rootXML[1].xmlChildren[x].XMLName eq "Appender-ref" ){ - args.appenders = listAppend(args.appenders, trim(rootXML[1].xmlChildren[x].XMLAttributes.ref) ); - } - } - } - root(argumentCollection=args); - - //Categories - for( x=1; x lte arrayLen(categoriesXML); x=x+1){ - args = structnew(); - - // Category Name - if( NOT structKeyExists(categoriesXML[x].XMLAttributes,"name") ){ - instance.utility.throwit(message="A category definition must have a name attribute",type="#getMetadata(this).name#.InvalidCategoryDefinition"); - } - args.name = trim(categoriesXML[x].XMLAttributes.name); - - // Level Min - if( structKeyExists(categoriesXML[x].XMLAttributes,"levelMin") ){ - args.levelMin = trim(categoriesXML[x].XMLAttributes.levelMin); - if( NOT isNumeric(args.levelMin) ){ - args.levelMin = this.logLevels.lookupAsInt(args.levelMin); - } - } - - // Level Max - if( structKeyExists(categoriesXML[x].XMLAttributes,"levelMax") ){ - args.levelMax = trim(categoriesXML[x].XMLAttributes.levelMax); - if( NOT isNumeric(args.levelMax) ){ - args.levelMax = this.logLevels.lookupAsInt(args.levelMax); - } - } - - //Category Appenders - if( structKeyExists(categoriesXML[x].XMLAttributes,"appenders") ){ - args.appenders = trim(categoriesXML[x].XMLAttributes.appenders); - } - else{ - args.appenders = ""; - // Find xml appender references - for( y=1; y lte arrayLen(categoriesXML[x].xmlChildren); y=y+1){ - if( categoriesXML[x].xmlChildren[y].XMLName eq "Appender-ref" ){ - args.appenders = listAppend(args.appenders, trim(categoriesXML[x].xmlChildren[y].XMLAttributes.ref) ); - } - } - // check if we have appenders else default to * - if(NOT len(args.appenders) ){ - args.appenders = "*"; - } - } - // Register category - category(argumentCollection=args); - } - - - diff --git a/src/cfml/system/wirebox/system/logging/config/LogBoxConfig.xsd b/src/cfml/system/wirebox/system/logging/config/LogBoxConfig.xsd deleted file mode 100644 index f8743d09f..000000000 --- a/src/cfml/system/wirebox/system/logging/config/LogBoxConfig.xsd +++ /dev/null @@ -1,242 +0,0 @@ - - - - This is how you configure the ColdBox Logging Library: LogBox - - - - - - An Appender declaration. - - - - - A property of the appender, can be simple or complex via ColdBox complex properties - - - - - The name of the property - - - - - - - - - The name of the registered appender. - - - - - The instantiation class of the appender. - - - - - A custom layout class to use with this appender. - - - - - The minimum logging level for this root logger. - - - - - - - - - - - - - - - - - - - - - - The maximum logging level for this root logger. - - - - - - - - - - - - - - - - - - - - - - - - The root logger definition. - - - - - An appender reference for the root logger - - - - - The appender reference name - - - - - - - - - The minimum logging level for this root logger. - - - - - - - - - - - - - - - - - - - - - - The maximum logging level for this root logger. - - - - - - - - - - - - - - - - - - - - - - *=all appender or optional configuration of appenders, else use Appender-ref - - - - - - - A category definition. - - - - - An appender reference for thi category - - - - - The appender reference name - - - - - - - - - The name of the category to configure. - - - - - The minimum logging level for this root logger. - - - - - - - - - - - - - - - - - - - - - - The maximum logging level for this root logger. - - - - - - - - - - - - - - - - - - - - - - *=all appender or optional configuration of appenders, else use Appender-ref - - - - - - - - \ No newline at end of file diff --git a/src/cfml/system/wirebox/system/logging/config/samples/Sample.LogBox.cfc b/src/cfml/system/wirebox/system/logging/config/samples/Sample.LogBox.cfc index fa6b7ade1..ff9f30cf6 100644 --- a/src/cfml/system/wirebox/system/logging/config/samples/Sample.LogBox.cfc +++ b/src/cfml/system/wirebox/system/logging/config/samples/Sample.LogBox.cfc @@ -1,5 +1,11 @@ - - +/******************************************************************************** +* Copyright Since 2005 ColdBox Framework by Luis Majano and Ortus Solutions, Corp +* www.ortussolutions.com +******************************************************************************** +* The default LogBox configuration object +**/ +component{ + /** * Configure LogBox, that's it! */ @@ -8,7 +14,7 @@ // Define Appenders appenders = { coldboxTracer = { - class="wirebox.system.logging.appenders.ColdboxTracerAppender", + class="wirebox.system.logging.appenders.ConsoleAppender", layout="coldbox.testing.cases.logging.MockLayout", properties = { name = "awesome" @@ -31,5 +37,5 @@ OFF = [ "hello.model", "yes.wow.wow" ] }; } - - + +} diff --git a/src/cfml/system/wirebox/system/logging/config/samples/Sample.LogBox.xml b/src/cfml/system/wirebox/system/logging/config/samples/Sample.LogBox.xml deleted file mode 100644 index 16e9a32bb..000000000 --- a/src/cfml/system/wirebox/system/logging/config/samples/Sample.LogBox.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - /coldbox/testing/logging/tmp - true - 3 - 2 - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/cfml/system/wirebox/system/logging/license.txt b/src/cfml/system/wirebox/system/logging/license.txt index 82b9b8bed..3de5291cb 100644 --- a/src/cfml/system/wirebox/system/logging/license.txt +++ b/src/cfml/system/wirebox/system/logging/license.txt @@ -1,6 +1,6 @@ ******************************************************************************** Copyright Since 2005 ColdBox Framework by Luis Majano and Ortus Solutions, Corp -www.coldbox.org | www.luismajano.com | www.ortussolutions.com +www.ortussolutions.com ******************************************************************************** ColdBox is open source. However, if you use this product please know that it is bound to the following Licence. If you use ColdBox, please make mention of it in your code or web site or add a Powered By Coldbox icon. diff --git a/src/cfml/system/wirebox/system/logging/readme.md b/src/cfml/system/wirebox/system/logging/readme.md new file mode 100644 index 000000000..c49c67a4a --- /dev/null +++ b/src/cfml/system/wirebox/system/logging/readme.md @@ -0,0 +1 @@ +``` _ ____ | | | _ \ | | ___ __ _| |_) | _____ __ | | / _ \ / _` | _ < / _ \ \/ / | |___| (_) | (_| | |_) | (_) > < |______\___/ \__, |____/ \___/_/\_\ v2.0.0.00002 __/ | |___/ ``` Copyright Since 2005 ColdBox Platform by Luis Majano and Ortus Solutions, Corp www.coldbox.org | www.ortussolutions.com ---- Because of God's 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: By whom also we have access by faith into this grace wherein we stand, and rejoice in hope of the glory of God. And not only so, but we glory in tribulations also: knowing that tribulation worketh patience; And patience, experience; and experience, hope: And hope maketh not ashamed; because the love of God is shed abroad in our hearts by the Holy Ghost which is given unto us. ." Romans 5:5 ---- # Welcome to LogBox LogBox is an enterprise ColdFusion (CFML) logging library designed to give you flexibility, simplicity and power when logging or tracing is needed in your applications. ## License Apache License, Version 2.0. >The ColdBox Websites, logo and content have a separate license and they are a separate entity. ## Versioning LogBox is maintained under the Semantic Versioning guidelines as much as possible. Releases will be numbered with the following format: ``` .. ``` And constructed with the following guidelines: * Breaking backward compatibility bumps the major (and resets the minor and patch) * New additions without breaking backward compatibility bumps the minor (and resets the patch) * Bug fixes and misc changes bumps the patch ## Important Links Source Code - https://github.com/coldbox/coldbox-platform Continuous Integration - http://jenkins.staging.ortussolutions.com/job/OS-ColdBoxPlatform%20BE/ Bug Tracking/Agile Boards - https://ortussolutions.atlassian.net/browse/LOGBOX Documentation - http://logbox.ortusbooks.com - http://wiki.coldbox.org/wiki/LogBox.cfm Blog - http://blog.coldbox.org Official Site - http://www.coldbox.org ## System Requirements - Lucee 4.5+ - Railo 4+ - ColdFusion 9.02+ ## Quick Installation Please go to our [documentation](http://logbox.ortusbooks.com) for expanded instructions. **CommandBox (Recommended)** We recommend you use [CommandBox](http://www.ortussolutions.com/products/commandbox), our CFML CLI and package manager, to install LogBox. **Stable Release** `box install logbox` **Bleeding Edge Release** `box install logbox-be` **Simple Install** Unzip the download into a folder called `logbox` in your webroot or place outside of the webroot and create a per-application mapping `/logbox` that points to it. **Bleeding Edge Downloads** You can always leverage our bleeding edge artifacts server to download LogBox: http://integration.staging.ortussolutions.com/artifacts/ortussolutions/logbox/ --- ###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/src/cfml/system/wirebox/system/logging/readme.txt b/src/cfml/system/wirebox/system/logging/readme.txt deleted file mode 100644 index b1f938912..000000000 --- a/src/cfml/system/wirebox/system/logging/readme.txt +++ /dev/null @@ -1 +0,0 @@ -******************************************************************************** Copyright Since 2005 ColdBox Framework by Luis Majano and Ortus Solutions, Corp www.coldbox.org | www.luismajano.com | www.ortussolutions.com ******************************************************************************** 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: By whom also we have access by faith into this grace wherein we stand, and rejoice in hope of the glory of God. And not only so, but we glory in tribulations also: knowing that tribulation worketh patience; And patience, experience; and experience, hope: And hope maketh not ashamed; because the love of God is shed abroad in our hearts by the Holy Ghost which is given unto us. ." Romans 5:5 ******************************************************************************** COLDBOX LICENSE ******************************************************************************** ColdBox is open source and bound to the Apache License, Version 2.0. If you use ColdBox, please try to make mention of it in your code or web site or add a Powered By Coldbox icon. Please donate, this project lives thanks to your donations. Please Read The Official License Agreement: http://www.coldbox.org/about/license The ColdBox Dashboard has a separate license and it is a separate entity. The ColdBox Websites, logo and content have a separate license and they are a separate entity. ******************************************************************************** OPEN SOURCE INITIATIVE APPROVED ******************************************************************************** This software is Open Source Initiative approved Open Source Software. Open Source Initiative Approved is a trademark of the Open Source Initiative. ******************************************************************************** COLDBOX IMPORTANT LINKS ******************************************************************************** Tracker Site (Bug Tracking, Issues) - https://ortussolutions.atlassian.net/browse/LOGBOX Documentation - http://wiki.coldbox.org Eclipse Update Site - http://www.coldbox.org/distribution/eclipse Blog - http://blog.coldboxframework.com Official Site - http://www.coldbox.org Official Bug Email - bugs@coldboxframework.com Official Info Email - info@coldboxframework.com ******************************************************************************** LOGBOX INSTALLATION ******************************************************************************** You can visit the LogBox documentation page to view all of its features and capabilities. To install logbox, just follow the normal coldbox installation procedures: LogBox Documentation http://wiki.coldbox.org/wiki/LogBox.cfm ColdBox Documentation http://wiki.coldbox.org ******************************************************************************** SYSTEM REQUIREMENTS ******************************************************************************** - Railo 2.0 and above - ColdFusion MX 7.X and above - BlueDragon 7.X and above * Some appenders require cf8 capabilities. ******************************************************************************** CHANGELOG ******************************************************************************** == Version 1.6 == https://coldbox.assembla.com/spaces/coldbox/milestones/273527-logbox-1-6 * coldbox-1128 Do convenience methods for log checks: canDebug(), canInfo(), etc. * coldbox-1129 Better documentation on logging classes and levels * coldbox-1139 Enhance the logEvent class to have a better serialization schema for extraInfo, it can use convention $toString() and json * coldbox-1147 LogBox category parsing needs a length check when the category sent is blank * coldbox-1154 performance tuning == Version 1.5 == https://coldbox.assembla.com/spaces/coldbox/milestones/246233-logbox-1-5 * 1108 db appender failure when declaring a columnMap, instance.columns not defined New * 1059 implicit logging levels are not changing on max level only but both, misconceptions Fixed * 1062 added concatenation possibilities to all programamtic configuration methods, so you can concatenate them jquery style == Version 1.4 == http://coldbox.assembla.com/spaces/coldbox/milestones/222897-logbox-1-4 * 1006 Fixes to DSL when doing appender affinity, not converting log levels to numeric Fixed * 1007 logLevels isLevelValid not assuring a valid level wrong boolean operation Fixed * 1008 appender() not doing level checks Fixed * 1009 refactoring the log levels argument types to consolidate them at the three input methods thanks to brad wood Fixed * 1010 Appender registration an init() not registering the log levels correctly Fixed * 1011 refactor logger and appender to verify logging levels sent via init() Fixed * 1032 Update the ensurance of datasources and let CF throw exception instead * 1054 Creation of XML schema for LogBox Fixed == Version 1.3 == http://coldbox.assembla.com/spaces/coldbox/milestones/187467-logbox-1-3 * Varscoping issue for DBAppender * Varscoping issue for Logger object * fix for category inheritance issues on locateCategoryParentLogger thanks to Sean Corfield * fixes when declaring appenders and * appenders on XML declarations * Add the ability to configure levels of logging on Appenders as a last line of granularity (some nice candy) * Appender registration an init() not registering the log levels correctly == Version 1.2 == http://coldbox.assembla.com/spaces/coldbox/milestones/153095-logbox-1-2 * Added some new methods: resetAppenders(), resetCategories and resetRoot() to reset some configurations. * Fixes on appender declarations and layouts * Addition of the LogBox DSL to coldbox configuration files * Ability to configure LogBox via a simple CFC with a simple configure() and a logBox variable == Version 1.1 == http://coldbox.assembla.com/spaces/coldbox/milestones/127903-LogBox-1-1 * Ability to declare categories with no appenders defined, by default it will use all appenders defined. * Standalone refactoring now creates the logbox namespace for operations instead of the coldbox namespace by default. * Ability to define * for category appender definitions == Version 1.0 (November 2009) == * Added performance updates for uuid creations * Added fixes for file removals * Added ability to add category appenders as * to add all of them at once == Version 1.0 RC 2 (October 2009) == * Fix for adding categories via XML * DBAppender new property textDBType to choose the text db type instead of the default 'text' == Version 1.0 Beta (August, 2009) == * Initial release of LogBox ---- AS ALWAYS, VISIT THE WIKI FOR THE LATEST DOCUMENTATION == THE DAILY BREAD == "I am the way, and the truth, and the life; no one comes to the Father, but by me (JESUS)" John 14:1-12 \ No newline at end of file diff --git a/src/cfml/system/wirebox/system/logging/util/FileRotator.cfc b/src/cfml/system/wirebox/system/logging/util/FileRotator.cfc index 87f78b355..c72df1d07 100644 --- a/src/cfml/system/wirebox/system/logging/util/FileRotator.cfc +++ b/src/cfml/system/wirebox/system/logging/util/FileRotator.cfc @@ -1,7 +1,7 @@  - - + - + @@ -28,20 +28,19 @@ Description : - - + - + - - + @@ -51,19 +50,24 @@ Description : - + - +
    - + - +
    - + @@ -82,5 +86,5 @@ Description : return (objFile.length()/1073741824); - + \ No newline at end of file diff --git a/src/cfml/system/wirebox/system/orm/hibernate/ActiveEntity.cfc b/src/cfml/system/wirebox/system/orm/hibernate/ActiveEntity.cfc deleted file mode 100644 index 752992906..000000000 --- a/src/cfml/system/wirebox/system/orm/hibernate/ActiveEntity.cfc +++ /dev/null @@ -1,306 +0,0 @@ -/** -******************************************************************************** -Copyright Since 2005 ColdBox Framework by Luis Majano and Ortus Solutions, Corp -www.coldbox.org | www.luismajano.com | www.ortussolutions.com -******************************************************************************** -Description : - -This Active Entity object allows you to enhance your ORM entities with virtual service methods -and make it follow more of an Active Record pattern, but not really :) - -It just allows you to operate on entity and related entity objects much much more easily. - -If you have enabled WireBox entity injection, then you will get an added validation features: - -boolean function isValid(fields="*",constraints="",locale=""){} -wirebox.system.validation.result.IValidationResult function getValidationResults(){} - -These methods are only active if WireBox entity injection is available. - - -*/ -component extends="wirebox.system.orm.hibernate.VirtualEntityService" accessors="true"{ - - /** - * WireBox entity injector, only injected if ORM entity injection is available. - */ - property name="wirebox" inject="wirebox" persistent="false"; - - /** - * Active Entity Constructor, if you override it, make sure you call super.init() - * @queryCacheRegion.hint The query cache region to use if not we will use one for you - * @useQueryCaching.hint Enable query caching for this entity or not, defaults to false - * @eventHandling.hint Enable event handling for new() and save() operations, defaults to true - * @useTransactions.hint Enable transactions for all major operations, defaults to true - * @defaultAsQuery.hint What should be the default return type query or arrays for list opertions, defaults to true - */ - function init(string queryCacheRegion, boolean useQueryCaching, boolean eventHandling, boolean useTransactions, boolean defaultAsQuery){ - var md = getMetadata( this ); - - // find entity name on md? - if( structKeyExists(md,"entityName") ){ - arguments.entityName = md.entityName; - } - // else default to entity CFC name - else{ - arguments.entityName = listLast( md.name, "." ); - } - // query cache region just in case - if( !structKeyExists(arguments,"queryCacheRegion") ){ - arguments.queryCacheRegion = "#arguments.entityName#.activeEntityCache"; - } - // datasource - arguments.datasource = new wirebox.system.orm.hibernate.util.ORMUtilFactory().getORMUtil().getEntityDatasource( this ); - - // init the super class with our own arguments - super.init( argumentCollection=arguments ); - - return this; - } - - /** - * Save an entity using hibernate transactions or not. You can optionally flush the session also - * @entity.hint You can optionally pass in an entity, else this active entity is saved - * @forceInsert.hint Force insert on the save - * @flush.hint Flush the session or not, default is false - * @transactional.hint Use transactions or not, it defaults to true - */ - any function save(any entity, boolean forceInsert=false, boolean flush=false, boolean transactional=getUseTransactions()){ - if( !structKeyExists(arguments,"entity") ){ - arguments.entity = this; - } - - return super.save( argumentCollection=arguments ); - } - - /** - * Delete an entity. The entity argument can be a single entity - * or an array of entities. You can optionally flush the session also after committing - * Transactions are used if useTransactions bit is set or the transactional argument is passed - * @entity.hint You can optionally pass in an entity, else this active entity is saved - * @flush.hint Flush the session or not, default is false - * @transactional.hint Use transactions or not, it defaults to true - */ - any function delete(any entity, boolean flush=false,boolean transactional=getUseTransactions()){ - if( !structKeyExists(arguments,"entity") ){ - arguments.entity = this; - } - return super.delete( argumentCollection=arguments ); - } - - /** - * Refresh the state of the entity - * @entity.hint The argument can be one persistence entity or an array of entities - */ - any function refresh(any entity){ - var objects = arrayNew(1); - - if( structKeyExists(arguments,"entity") ){ - if( isArray(arguments.entity) ){ - objects = arguments.entity; - } - else{ - arrayAppend(objects, arguments.entity); - } - } - - arrayAppend(objects, this); - - return super.refresh(objects); - } - - /** - * Merge an entity or array of entities back into the session - * @entity.hint The argument can be one persistence entity or an array of entities - */ - any function merge(any entity){ - var objects = arrayNew(1); - - if( structKeyExists(arguments,"entity") ){ - if( isArray(arguments.entity) ){ - objects = arguments.entity; - } - else{ - arrayAppend(objects, arguments.entity); - } - } - - arrayAppend(objects, this); - - return super.merge(objects); - } - - /** - * Evict entity objects from session, if no arguments, then the entity evicts itself - * @entity.hint The argument can be one persistence entity or an array of entities - */ - any function evict(any entity){ - var objects = arrayNew(1); - - if( structKeyExists(arguments,"entity") ){ - if( isArray(arguments.entity) ){ - objects = arguments.entity; - } - else{ - arrayAppend(objects, arguments.entity); - } - } - - arrayAppend(objects, this); - - return super.evictEntity(objects); - } - - /** - * Simple map to property population for entities - * @memento.hint The map/struct to populate the entity with - * @scope.hint Use scope injection instead of setter injection, no need of setters, just tell us what scope to inject to - * @trustedSetter.hint Do not check if the setter exists, just call it, great for usage with onMissingMethod() and virtual properties - * @include.hint A list of keys to include in the population ONLY - * @exclude.hint A list of keys to exclude from the population - */ - any function populate(any target=this, - required struct memento, - string scope="", - boolean trustedSetter=false, - string include="", - string exclude="", - boolean ignoreEmpty=false, - string nullEmptyInclude="", - string nullEmptyExclude="", - boolean composeRelationships=true){ - return beanPopulator.populateFromStruct( argumentCollection=arguments ); - } - - /** - * Simple map to property population for entities with structure key prefixes - * @memento.hint The map/struct to populate the entity with - * @scope.hint Use scope injection instead of setter injection, no need of setters, just tell us what scope to inject to - * @trustedSetter.hint Do not check if the setter exists, just call it, great for usage with onMissingMethod() and virtual properties - * @include.hint A list of keys to include in the population ONLY - * @exclude.hint A list of keys to exclude from the population - * @prefix.hint The prefix used to filter, Example: 'user' would apply to the following formfield: 'user_id' and 'user_name' but not 'address_id' - */ - any function populateWithPrefix(any target=this, - required struct memento, - string scope="", - boolean trustedSetter=false, - string include="", - string exclude="", - boolean ignoreEmpty=false, - string nullEmptyInclude="", - string nullEmptyExclude="", - boolean composeRelationships=true, - required string prefix){ - return beanPopulator.populateFromStructWithPrefix( argumentCollection=arguments ); - } - - /** - * Populate from JSON, for argument definitions look at the populate method - * @JSONString.hint The JSON packet to use for population - * @scope.hint Use scope injection instead of setter injection, no need of setters, just tell us what scope to inject to - * @trustedSetter.hint Do not check if the setter exists, just call it, great for usage with onMissingMethod() and virtual properties - * @include.hint A list of keys to include in the population ONLY - * @exclude.hint A list of keys to exclude from the population - */ - any function populateFromJSON(any target=this, - required string JSONString, - string scope="", - boolean trustedSetter=false, - string include="", - string exclude="", - boolean ignoreEmpty=false, - string nullEmptyInclude="", - string nullEmptyExclude="", - boolean composeRelationships=true){ - return beanPopulator.populateFromJSON( argumentCollection=arguments ); - } - - /** - * Populate from XML, for argument definitions look at the populate method.
    - * @root.hint The XML root element to start from - * @xml.hint The XML string or packet or XML object to populate from - * @scope.hint Use scope injection instead of setter injection, no need of setters, just tell us what scope to inject to - * @trustedSetter.hint Do not check if the setter exists, just call it, great for usage with onMissingMethod() and virtual properties - * @include.hint A list of keys to include in the population ONLY - * @exclude.hint A list of keys to exclude from the population - */ - any function populateFromXML(any target=this, - required string xml, - string root="", - string scope="", - boolean trustedSetter=false, - string include="", - string exclude="", - boolean ignoreEmpty=false, - string nullEmptyInclude="", - string nullEmptyExclude="", - boolean composeRelationships=true){ - return beanPopulator.populateFromXML( argumentCollection=arguments ); - } - - /** - * Populate from Query, for argument definitions look at the populate method.
    - * @qry.hint The query to use for population - * @rowNumber.hint The row number to use for population - * @scope.hint Use scope injection instead of setter injection, no need of setters, just tell us what scope to inject to - * @trustedSetter.hint Do not check if the setter exists, just call it, great for usage with onMissingMethod() and virtual properties - * @include.hint A list of keys to include in the population ONLY - * @exclude.hint A list of keys to exclude from the population - */ - any function populateFromQuery(any target=this, - required any qry, - numeric rowNumber=1, - string scope="", - boolean trustedSetter=false, - string include="", - string exclude="", - boolean ignoreEmpty=false, - string nullEmptyInclude="", - string nullEmptyExclude="", - boolean composeRelationships=true){ - return beanPopulator.populateFromQuery( argumentCollection=arguments ); - } - - /** - * Validate the ActiveEntity with the coded constraints -> this.constraints, or passed in shared or implicit constraints - * The entity must have been populated with data before the validation - * @fields.hint One or more fields to validate on, by default it validates all fields in the constraints. This can be a simple list or an array. - * @constraints.hint An optional shared constraints name or an actual structure of constraints to validate on. - * @locale.hint An optional locale to use for i18n messages - * @excludeFields.hint An optional list of fields to exclude from the validation. - */ - boolean function isValid(string fields="*", any constraints="", string locale="", string excludeFields=""){ - // validate wirebox - if( !structKeyExists(variables,"wirebox") OR !isObject(variables.wirebox) ){ - throw(message="WireBox reference does not exist in this entity",detail="WireBox entity injection must be enabled in order to use the validation features",type="ActiveEntity.ORMEntityInjectionMissing"); - } - - // Get validation manager - var validationManager = wirebox.getInstance("WireBoxValidationManager"); - // validate constraints - var thisConstraints = ""; - if( structKeyExists(this,"constraints") ){ thisConstraints = this.constraints; } - // argument override - if( !isSimpleValue(arguments.constraints) OR len(arguments.constraints) ){ - thisConstraints = arguments.constraints; - } - - // validate and save results in private scope - validationResults = validationManager.validate(target=this, fields=arguments.fields, constraints=thisConstraints, locale=arguments.locale, excludeFields=arguments.excludeFields); - - // return it - return ( !validationResults.hasErrors() ); - } - - /** - * Get the validation results object. This will be an empty validation object if isValid() has not being called yet. - */ - wirebox.system.validation.result.IValidationResult function getValidationResults(){ - if( structKeyExists(variables,"validationResults") ){ - return validationResults; - } - return new wirebox.system.validation.result.ValidationResult(); - } - -} \ No newline at end of file diff --git a/src/cfml/system/wirebox/system/orm/hibernate/BaseBuilder.cfc b/src/cfml/system/wirebox/system/orm/hibernate/BaseBuilder.cfc deleted file mode 100644 index d0d4f52b9..000000000 --- a/src/cfml/system/wirebox/system/orm/hibernate/BaseBuilder.cfc +++ /dev/null @@ -1,568 +0,0 @@ -/** -******************************************************************************** -Copyright Since 2005 ColdBox Framework by Luis Majano and Ortus Solutions, Corp -www.coldbox.org | www.luismajano.com | www.ortussolutions.com -******************************************************************************** - -Description: BaseBuilder is a common funnel through which both CriteriaBuilder and DetachedCriteriaBuilder can be run - It exposes properties and methods that both builders share in common, for a singular mechanism for building - criteria queries and subqueries - -We also setup several public properties: - -this.PROJECTIONS - Maps to the Hibernate projections class: org.hibernate.criterion.Projections -this.RESTRICTIONS - Maps to our ColdBox restrictions class: wirebox.system.orm.hibernate.criterion.Restrictions - -Join Types -this.FULL_JOIN - Specifies joining to an entity based on a full join. -this.INNER_JOIN - Specifies joining to an entity based on an inner join. -this.LEFT_JOIN - Specifies joining to an entity based on a left outer join. - -Result Transformers -this.ALIAS_TO_ENTITY_MAP - Each row of results is a Map from alias to entity instance -this.DISTINCT_ROOT_ENTITY - Each row of results is a distinct instance of the root entity -this.PROJECTION - This result transformer is selected implicitly by calling setProjection() -this.ROOT_ENTITY - Each row of results is an instance of the root entity - -*/ -import wirebox.system.orm.hibernate.*; -import org.hibernate.*; -component accessors="true"{ - - /** - * The native criteria object - */ - property name="nativeCriteria" type="any"; - /** - * The entity name this criteria builder is binded to - */ - property name="entityName" type="string"; - /** - * The bit that determines if we are tracking SQL - */ - property name="SQLLoggerActive" type="boolean" default="false"; - /** - * The system event manager - */ - property name="eventManager" type="any"; - -/************************************** Constructor *********************************************/ - - // Constructor - BaseBuilder function init( - required string entityName, - required any criteria, - required any restrictions, - required any ORMService - ){ - - // java projections linkage - this.projections = CreateObject("java","org.hibernate.criterion.Projections"); - // restrictions linkage - this.restrictions = arguments.restrictions; - - // hibernate criteria query setup - will be either CriteriaBuilder or DetachedCriteriaBuilder - variables.nativeCriteria = arguments.criteria; - // set entity name - variables.entityName = arguments.entityName; - // Link to orm service - variables.ORMService = arguments.ORMService; - // Link to system event handler - variables.eventManager = arguments.ORMService.getORMEventHandler().getEventManager(); - // set sql logger usage - variables.SQLLoggerActive = false; - // add SQL Helper - variables.SQLHelper = new wirebox.system.orm.hibernate.sql.SQLHelper( this ); - - // Setup pseudo-static join types and transformer types: - this.ALIAS_TO_ENTITY_MAP = nativeCriteria.ALIAS_TO_ENTITY_MAP; - this.DISTINCT_ROOT_ENTITY = nativeCriteria.DISTINCT_ROOT_ENTITY; - this.FULL_JOIN = nativeCriteria.FULL_JOIN; - this.INNER_JOIN = nativeCriteria.INNER_JOIN; - this.LEFT_JOIN = nativeCriteria.LEFT_JOIN; - this.PROJECTION = nativeCriteria.PROJECTION; - this.ROOT_ALIAS = nativeCriteria.ROOT_ALIAS; - this.ROOT_ENTITY = nativeCriteria.ROOT_ENTITY; - - return this; - } - -/************************************** PUBLIC *********************************************/ - - // setter override - any function setNativeCriteria( required any criteria ){ - variables.nativeCriteria = arguments.criteria; - return this; - } - - // setter override - any function setEntityName( required any entityName ){ - variables.entityName = arguments.entityName; - return this; - } - - /** - * Add an ordering to the result set, you can add as many as you like - * @property The name of the property to order on - * @sortOrder The order type: asc or desc, defaults to asc - * @ignoreCase Wether to ignore case or not, defaults to false - */ - any function order( required string property, string sortDir="asc", boolean ignoreCase=false ){ - var order = CreateObject( "java", "org.hibernate.criterion.Order" ); - var orderBy = ""; - // direction - switch(UCase(arguments.sortDir)) { - case "DESC": - orderBy = order.desc(arguments.property); - break; - default: - orderBy = order.asc(arguments.property); - break; - } - // ignore case - if(arguments.ignoreCase){ - orderBy.ignoreCase(); - } - nativeCriteria.addOrder( orderBy ); - - // process interception - if( ORMService.getEventHandling() ){ - variables.eventManager.processState( "onCriteriaBuilderAddition", { - "type" = "Order", - "criteriaBuilder" = this - }); - } - return this; - } - - /** - * Join an association, assigning an alias to the joined association. - * @associationName The name of the association property - * @alias The alias to use for this association property on restrictions - * @jointType The hibernate join type to use, by default it uses an inner join. Available as properties: criteria.FULL_JOIN, criteria.INNER_JOIN, criteria.LEFT_JOIN - */ - any function createAlias( required string associationName, required string alias, numeric joinType ){ - // No Join type - if( NOT structKeyExists(arguments,"joinType") ){ - // create alias - nativeCriteria.createAlias( arguments.associationName, arguments.alias ); - - // announce - if( ORMService.getEventHandling() ){ - variables.eventManager.processState( "onCriteriaBuilderAddition", { - "type" = "Alias", - "criteriaBuilder" = this - }); - } - - return this; - } - // With Join Type - nativeCriteria.createAlias( arguments.associationName, arguments.alias, arguments.joinType ); - - // announce - if( ORMService.getEventHandling() ){ - variables.eventManager.processState( "onCriteriaBuilderAddition", { - "type" = "Alias w/Join Type", - "criteriaBuilder" = this - }); - } - - return this; - } - - /** - * Create a new Criteria, "rooted" at the associated entity and using an Inner Join - * @associationName The name of the association property to root the restrictions with - * @jointType The hibernate join type to use, by default it uses an inner join. Available as properties: criteria.FULL_JOIN, criteria.INNER_JOIN, criteria.LEFT_JOIN - */ - any function createCriteria(required string associationName,numeric joinType){ - // No Join type - if( NOT structKeyExists(arguments,"joinType") ){ - nativeCriteria = nativeCriteria.createCriteria( arguments.associationName ); - // log sql if enabled - if( canLogSql() ) { - logSQL( "New Criteria" ); - } - return this; - } - - // With Join Type - nativeCriteria = nativeCriteria.createCriteria( arguments.associationName, arguments.joinType ); - - // announce - if( ORMService.getEventHandling() ){ - variables.eventManager.processState( "onCriteriaBuilderAddition", { - "type" = "New Criteria w/Join Type", - "criteriaBuilder" = this - }); - } - - return this; - } - - /** - * Add a restriction to constrain the results to be retrieved - * @criterion A single or array of criterions to add - */ - any function add(required any criterion){ - if( NOT isArray(arguments.criterion) ){ - arguments.criterion = [ arguments.criterion ]; - } - for(var i=1; i LTE ArrayLen(arguments.criterion); i++) { - nativeCriteria.add( arguments.criterion[i] ); - } - return this; - } - - /** - * Sets a valid hibernate result transformer: org.hibernate.transform.ResultTransform to use on the results - * @resultTransformer a custom result transform or you can use the included ones: criteria.ALIAS_TO_ENTITY_MAP, criteria.DISTINCT_ROOT_ENTITY, criteria.PROJECTION, criteria.ROOT_ENTITY. - */ - any function resultTransformer(any resultTransformer){ - nativeCriteria.setResultTransformer( arguments.resultTransformer ); - return this; - } - - /** - * Setup a single or a projection list via native projections class: criteria.projections - */ - any function setProjection(any projection){ - // set projection - nativeCriteria.setProjection( arguments.projection ); - - // announce - if( ORMService.getEventHandling() ){ - variables.eventManager.processState( "onCriteriaBuilderAddition", { - "type" = "Projection", - "criteriaBuilder" = this - }); - } - - return this; - } - - /** - * Setup projections for this criteria query, you can pass one or as many projection arguments as you like. - * The majority of the arguments take in the property name to do the projection on, which will also use that as the alias for the column - * or you can pass an alias after the property name separated by a : Ex: projections(avg="balance:avgBalance") - * The alias on the projected value can be referred to in restrictions or orderings. - * Please also note that the resulting array locations are done in alphabetical order of the arguments. - * @avg The name of the property to avg or a list or array of property names - * @count The name of the property to count or a list or array of property names - * @countDistinct The name of the property to count distinct or a list or array of property names - * @distinct The name of the property to do a distinct on, this can be a single property name a list or an array of property names - * @groupProperty The name of the property to group by or a list or array of property names - * @id The projected identifier value - * @max The name of the property to max or a list or array of property names - * @min The name of the property to min or a list or array of property names - * @property The name of the property to do a projected value on or a list or array of property names - * @rowCount Do a row count on the criteria - * @sum The name of the property to sum or a list or array of property names - * @sqlProjection Do a projection based on arbitrary SQL string - * @sqlGroupProjection Do a projection based on arbitrary SQL string, with grouping - * @detachedSQLProjection Do a projection based on a DetachedCriteria builder config - */ - any function withProjections( - string avg, - string count, - string countDistinct, - any distinct, - string groupProperty, - boolean id, - string max, - string min, - string property, - boolean rowCount, - string sum, - any sqlProjection, - any sqlGroupProjection, - any detachedSQLProjection - ){ - // create our projection list - var projectionList = this.PROJECTIONS.projectionList(); - var excludes = "id,rowCount,distinct,sqlProjection,sqlGroupProjection,detachedSQLProjection"; - - // iterate and add dynamically if the incoming argument exists, man, so much easier if we had closures. - for(var pType in arguments){ - if( structKeyExists(arguments,pType) AND NOT listFindNoCase(excludes, pType) ){ - addProjection(arguments[pType], lcase(pType), projectionList); - } - } - - // id - if( structKeyExists(arguments,"id") ){ - projectionList.add( this.PROJECTIONS.id() ); - } - - // rowCount - if( structKeyExists(arguments,"rowCount") ){ - projectionList.add( this.PROJECTIONS.rowCount() ); - } - - // distinct - if( structKeyExists(arguments,"distinct") ){ - addProjection(arguments.distinct,"property",projectionList); - projectionList = this.PROJECTIONS.distinct(projectionList); - } - - // detachedSQLProjection - if( structKeyExists( arguments, "detachedSQLProjection" ) ) { - // allow single or arrary of detachedSQLProjection - var projectionCollection = !isArray( arguments.detachedSQLProjection ) ? [ arguments.detachedSQLProjection ] : arguments.detachedSQLProjection; - // loop over array of detachedSQLProjections - for( projection in projectionCollection ) { - projectionList.add( projection.createDetachedSQLProjection() ); - } - } - - // sqlProjection - if( structKeyExists( arguments, "sqlProjection" ) ) { - // allow for either an array of sqlProjections, or a stand-alone config for one - var sqlargs = !isArray( arguments.sqlProjection ) ? [ arguments.sqlProjection ] : arguments.sqlProjection; - // loop over sqlProjections - for( var projection in sqlargs ) { - var projectionArgs = prepareSQLProjection( projection ); - projectionList.add( this.PROJECTIONS.sqlProjection( projectionArgs.sql, projectionArgs.alias, projectionArgs.types ) ); - } - - } - - // sqlGroupProjection - if( structKeyExists( arguments, "sqlGroupProjection" ) ) { - // allow for either an array of sqlGroupProjections, or a stand-alone config for one - var sqlargs = !isArray( arguments.sqlGroupProjection ) ? [ arguments.sqlGroupProjection ] : arguments.sqlGroupProjection; - // loop over sqlGroupProjections - for( var projection in sqlargs ) { - var projectionArgs = prepareSQLProjection( projection ); - projectionList.add( this.PROJECTIONS.sqlGroupProjection( projectionArgs.sql, projectionArgs.group, projectionArgs.alias, projectionArgs.types ) ); - } - } - // add all the projections - nativeCriteria.setProjection( projectionList ); - - // announce - if( ORMService.getEventHandling() ){ - variables.eventManager.processState( "onCriteriaBuilderAddition", { - "type" = "Projection", - "criteriaBuilder" = this - }); - } - - return this; - } - - /** - * Coverts an ID, list of ID's, or array of ID's values to the proper java type - * The method returns a coverted array of ID's - */ - any function convertIDValueToJavaType(required id){ - arguments.entityName = variables.entityName; - return new BaseORMService().convertIDValueToJavaType(argumentCollection=arguments); - } - - /** - * Coverts a value to the correct javaType for the property passed in - * The method returns the value in the proper Java Type - */ - any function convertValueToJavaType(required propertyName, required value){ - arguments.entityName = variables.entityName; - return new BaseORMService().convertValueToJavaType(argumentCollection=arguments); - } - - /** - * Returns the SQL string that will be prepared for the criteria object at the time of request - * @executable {Boolean} Whether or not to do query param replacements on returned SQL string - * return string - */ - public string function getSQL( required boolean returnExecutableSql=false, required boolean formatSql=true ) { - return SQLHelper.getSQL( argumentCollection=arguments ); - } - - /** - * Gets the positional SQL parameter values from the criteria query - * return array - */ - public array function getPositionalSQLParameterValues() { - return SQLHelper.getPositionalSQLParameterValues(); - } - - /** - * Gets positional SQL parameter types from the criteria query - * @simple {Boolean} Whether to return a simply array or full objects - * return any - */ - public any function getPositionalSQLParameterTypes( required boolean simple=true ) { - return SQLHelper.getPositionalSQLParameterTypes( argumentCollection=arguments ); - } - - /** - * Returns a formatted array of parameter value and types - * return array - */ - public array function getPositionalSQLParameters() { - return SQLHelper.getPositionalSQLParameters(); - } - - /** - * Retrieves the SQL Log - * return Array - */ - public array function getSQLLog() { - return SQLHelper.getLog(); - } - - /** - * Triggers CriteriaBuilder to start internally logging the state of SQL at each iterative build - * @returnExecutableSql {Boolean} Whether or not to return sql with query params replaced with positional values - * @formatSql {Boolean} Whether or not to run sql through formatter and wrap the sql in
     tags for more readable output
    -	 * return CriteriaBuilder
    -	 */
    -	public any function startSqlLog( required Any returnExecutableSql=false, required Any formatSql=false ) {
    -		SQLHelper.setReturnExecutableSql( arguments.returnExecutableSql );
    -		SQLHelper.setFormatSql( arguments.formatSql );
    -		sqlLoggerActive = true;
    -		return this;
    -	}
    -
    -	/**
    -	 * Stops CriteriaBuilder from continuing to internally log the state of SQL
    -	 * return CriteriaBuilder
    -	 */
    -	public any function stopSqlLog() {
    -		sqlLoggerActive = false;
    -		return this;
    -	}
    -
    -	/**
    -	 * Allows for one-off sql logging at any point in the process of building up CriteriaBuilder; will log the SQL state at the time of the call
    -	 * @label {String} The label to use for the sql log record
    -	 * return void
    -	 */
    -	public void function logSQL( required String label ) {
    -		SQLHelper.log( argumentCollection=arguments );
    -	}
    -
    -	/**
    -	 * Returns whether or not CriteriaBuilder is currently configured to log SQL
    -	 * return Boolean
    -	 */
    -	public boolean function canLogSql() {
    -		return sqlLoggerActive;
    -	}
    -	/************************************** PRIVATE *********************************************/
    -	
    -	/**
    -	 * Checks whether or not a projection is currently applied to the CriteriaBuilder
    -	 * return Boolean
    -	 */
    -	private boolean function hasProjection() {
    -		var projectionExists = false;
    -		if( !isNull( nativeCriteria.getProjection() ) ) {
    -			projectionExists = nativeCriteria.getProjection().getLength() ? true : false;
    -		}
    -		return projectionExists;
    -	}
    -
    -	// Simplified additions of projections
    -	private function addProjection(any propertyName,any projectionType,any projectionList){
    -		// inflate to array
    -		if( isSimpleValue(arguments.propertyName) ){ arguments.propertyName = listToArray(arguments.propertyName); }
    -		// iterate array and add projections
    -		for(var thisP in arguments.propertyName){
    -			// add projection
    -			arguments.projectionList.add( evaluate("this.PROJECTIONS.#arguments.projectionType#( listFirst(thisP,':') )"), listLast(thisP,":") );
    -			
    -			// announce
    -			if( ORMService.getEventHandling() ){
    -				variables.eventManager.processState( "onCriteriaBuilderAddition", {
    -					"type" = "Projection",
    -					"criteriaBuilder" = this
    -				});
    -			}
    -
    -		}
    -	}
    -	
    -	/**
    -	 * Helper method to prepare sqlProjection for addition to CriteriaBuilder
    -	 * @rawProjection {Struct} The raw projection configuration
    -	 * return Struct
    -	 */
    -	private struct function prepareSQLProjection( rawProjection ) {
    -		// get metadata for current root entity
    -		var metaData = ORMService.getORM().getSessionFactory( ORMService.getORM().getEntityDatasource( this.getentityName() ) )
    -						  .getClassMetaData( this.getentityName() );
    -		// establish projection struct
    -		var projection = {};
    -		// create empty array for propertyTypes
    -		var projection.types = [];
    -		// retrieve correct type for each specified property so list() doesn't bork
    -		for( var prop in listToArray( arguments.rawProjection.property ) ) {
    -			arrayAppend( projection.types, metaData.getPropertyType( prop ) );
    -		}
    -		var partialSQL = "";
    -		projection.sql = "";
    -		// if multiple subqueries have been specified, smartly separate them out into a sql string that will work
    -		for( var x=1; x<=listLen( arguments.rawProjection.sql ); x++ ) {
    -			partialSQL = listGetAt( arguments.rawProjection.sql, x );
    -			partialSQL = reFindNoCase( "^select", partialSQL ) ? "(#partialSQL#)" : partialSQL;
    -			partialSQL = partialSQL & " as #listGetAt( arguments.rawProjection.alias, x )#";
    -			projection.sql = listAppend( projection.sql, partialSQL );
    -		}
    -		// get all aliases
    -		projection.alias = listToArray( arguments.rawProjection.alias );
    -		// if there is a grouping spcified, add it to structure
    -		if( structKeyExists( arguments.rawProjection, "group" ) ) {
    -			projection.group = arguments.rawProjection.group;
    -		}
    -		return projection;
    -	}
    -	
    -	// Normalize Sort orders
    -	private void function normalizeOrder(required string sortOrder,required boolean ignoreCase){
    -		
    -		var sortLen = listLen(arguments.sortOrder);
    -		
    -		for(var x=1; x lte sortLen; x++){
    -			var thisSort = listGetAt(arguments.sortOrder,x);
    -			var sortField = Trim(ListFirst(thisSort," "));
    -			var sortDir = "ASC";
    -			if(ListLen(thisSort," ") GTE 2){
    -				sortDir = ListGetAt(thisSort,2," ");
    -			}
    -			// add it to our ordering
    -			order(sortField,sortDir,arguments.ignoreCase);
    -		}
    -	} 
    -	
    -	// creates either a new criteria query, or a new restriction, and returns the result
    -	private any function createRestriction( required string missingMethodName, required struct missingMethodArguments ){
    -		// check for with{association} dynamic finder: 
    -		if( left(arguments.missingMethodName,4) eq "with" ){
    -			var args = { 
    -				associationName = right( arguments.missingMethodName, len(arguments.missingMethodName)-4)
    -			};
    -			// join type
    -			if( structKeyExists(arguments.missingMethodArguments,"1") ){
    -				args.joinType = arguments.missingMethodArguments[1];
    -			}
    -			if( structKeyExists(arguments.missingMethodArguments,"joinType") ){
    -				args.joinType = arguments.missingMethodArguments.joinType;
    -			}
    -			// create the dynamic criteria
    -			return createCriteria(argumentCollection=args);
    -		}
    -		//arguments.missingMethodArguments.nativeCriteria = getNativeCriteria();
    -		// funnel missing methods to restrictions and append to criterias
    -		var r = evaluate("this.restrictions.#arguments.missingMethodName#(argumentCollection=arguments.missingMethodArguments)");
    -		return r;
    -	}
    -}
    diff --git a/src/cfml/system/wirebox/system/orm/hibernate/BaseORMService.cfc b/src/cfml/system/wirebox/system/orm/hibernate/BaseORMService.cfc
    deleted file mode 100644
    index 6c054ec13..000000000
    --- a/src/cfml/system/wirebox/system/orm/hibernate/BaseORMService.cfc
    +++ /dev/null
    @@ -1,1493 +0,0 @@
    -/**
    -********************************************************************************
    -Copyright Since 2005 ColdBox Framework by Luis Majano and Ortus Solutions, Corp
    -www.coldbox.org | www.luismajano.com | www.ortussolutions.com
    -********************************************************************************
    -Author      :	Luis Majano
    -Description :
    -
    -This is a helper ORM service that will help you abstract some complexities
    -when dealing with CF's ORM via Hibernate.  You can use this service in its
    -concrete form or you can inherit from it and extend it.
    -
    -TODO:
    -- Add dynamic findBy methods
    -- Add dynamic countBy methods
    -- Add dynamic getBy methods
    -- Dynamic entity methods for the following methods:
    -   - new{entityName}()
    -   - exists{entityName}()
    -   - get{entityName}()
    -   - getAll{entityName}()
    -   - count{entityName}()
    -- Add find methods by criteria with projections
    ------------------------------------------------------------------------>
    -*/
    -import wirebox.system.orm.hibernate.util.*;
    -
    -component accessors="true"{
    -
    -	/**
    -	* The queryCacheRegion name property for all query caching produced in this service
    -	*/
    -	property name="queryCacheRegion" type="string" default="ORMService.defaultCache";
    -
    -	/**
    -	* The bit that tells the service to enable query caching, disabled by default
    -	*/
    -	property name="useQueryCaching" type="boolean" default="false";
    -
    -	/**
    -	* The bit that enables event handling via the ORM Event handler such as interceptions when new entities get created, etc, enabled by default.
    -	*/
    -	property name="eventHandling" type="boolean" default="true";
    -
    -	/**
    -	* The system ORM event handler to transmitt ORM events to
    -	*/
    -	property name="ORMEventHandler";
    -
    -	/**
    -	* The system ORM utility object
    -	*/
    -	property name="ORM";
    -	
    -	/**
    -	* The bit that enables automatic hibernate transactions on all save, saveAll, update, delete methods
    -	*/
    -	property name="useTransactions" type="boolean" default="true";
    -
    -	/**
    -	* The bit that determines the default return value for list(), createCriteriaQuery() and executeQuery() as query or array
    -	*/
    -	property name="defaultAsQuery" type="boolean" default="true";
    -	
    -	/**
    -	* All calculated and parsed dynamic finders' and counters' HQL will be stored here for easier execution
    -	*/
    -	property name="HQLDynamicCache" type="struct";  
    -	
    -	// STATIC DYNAMIC FINDER VARIABLES
    -	ALL_CONDITIONALS 		= "LessThanEquals,LessThan,GreaterThanEquals,GreaterThan,Like,NotEqual,isNull,isNotNull,NotBetween,Between,NotInList,inList";
    -	ALL_CONDITIONALS_REGEX	= replace( ALL_CONDITIONALS, ",", "|", "all" );
    -	CONDITIONALS_SQL_MAP 	= { 
    -		"LessThanEquals" = "<=",
    -		"LessThan" = "<",
    -		"GreaterThanEquals" = ">=",
    -		"GreaterThan" = ">",
    -		"Like" = "like",
    -		"NotEqual" = "<>",
    -		"isNull" = "is null",
    -		"isNotNull" = "is not null",
    -		"NotBetween" = "not between",
    -		"between" = "between",
    -		"NotInList" = "not in",
    -		"InList" = "in" };
    -
    -	/************************************** CONSTRUCTOR *********************************************/
    -
    -	BaseORMService function init( 
    -		string queryCacheRegion="ORMService.defaultCache",
    -		boolean useQueryCaching=false,
    -		boolean eventHandling=true,
    -		boolean useTransactions=true,
    -		boolean defaultAsQuery=true
    -	){
    -		
    -		// setup local properties
    -		variables.queryCacheRegion 	= arguments.queryCacheRegion;
    -		variables.useQueryCaching 	= arguments.useQueryCaching;
    -		variables.eventHandling 	= arguments.eventHandling;
    -		variables.useTransactions 	= arguments.useTransactions;
    -		variables.defaultAsQuery 	= arguments.defaultAsQuery;
    -		variables.HQLDynamicCache	= {};
    -
    -		// Create the ORM Utility component
    -		variables.ORM = new wirebox.system.orm.hibernate.util.ORMUtilFactory().getORMUtil();
    -		
    -		// Create the service ORM Event Handler
    -		if( directoryExists( expandPath("/wirebox") ) OR structKeyExists( application, "cblite" ) ){
    -			variables.ORMEventHandler = new wirebox.system.orm.hibernate.WBEventHandler();
    -		}
    -		else{
    -			variables.ORMEventHandler = new wirebox.system.orm.hibernate.EventHandler();
    -		}
    -
    -		// Create our bean populator utility object
    -		variables.beanPopulator = new wirebox.system.core.dynamic.BeanPopulator();
    -		// Restrictions orm.hibernate.criterion.Restrictions
    -		variables.restrictions  = new wirebox.system.orm.hibernate.criterion.Restrictions();
    -
    -		return this;
    -	}
    -
    -	/************************************** PUBLIC *********************************************/
    -
    -	/**
    -	* Create a virtual abstract service for a specfic entity.
    -	*/
    -	any function createService(required string entityName,
    -							   boolean useQueryCaching=getUseQueryCaching(),
    -							   string queryCacheRegion=getQueryCacheRegion(),
    -							   boolean eventHandling=getEventHandling()) {
    -
    -		return new wirebox.system.orm.hibernate.VirtualEntityService( argumentCollection=arguments );
    -	}
    -
    -	/**
    -	* List all of the instances of the passed in entity class name. You can pass in several optional arguments like
    -	* a struct of filtering criteria, a sortOrder string, offset, max, ignorecase, and timeout.
    -	* Caching for the list is based on the useQueryCaching class property and the cachename property is based on
    -	* the queryCacheRegion class property.
    -	*/
    -	any function list(required string entityName,
    -					  struct criteria=structnew(),
    -					  string sortOrder="",
    -					  numeric offset=0,
    -					  numeric max=0,
    -					  numeric timeout=0,
    -					  boolean ignoreCase=false,
    -					  boolean asQuery=getDefaultAsQuery()){
    -		var options = {};
    -
    -		// Setup listing options
    -		if( arguments.offset neq 0 ){
    -			options.offset = arguments.offset;
    -		}
    -		if( arguments.max neq 0 ){
    -			options.maxresults = arguments.max;
    -		}
    -		if( arguments.timeout neq 0 ){
    -			options.timeout = arguments.timeout;
    -		}
    -
    -		// Caching?
    -		if( getUseQueryCaching() ){
    -			options.cacheName  = getQueryCacheRegion();
    -			options.cacheable  = true;
    -		}
    -
    -		// Sort Order Case
    -		if( len(trim(arguments.sortOrder)) ){
    -			options.ignoreCase = arguments.ignoreCase;
    -		}
    -
    -		// Get listing
    -		var results = entityLoad(arguments.entityName, arguments.criteria, arguments.sortOrder, options);
    -
    -		// Is it Null?
    -		if( isNull(results) ){ results = []; }
    -
    -		// Objects or Query?
    -		if( arguments.asQuery ){
    -			results = entityToQuery(results);
    -		}
    -
    -		return results;
    -	}
    -
    -	/**
    -	* Allows the execution of HQL queries using several nice arguments and returns either an array of entities or a query as specified by the asQuery argument.
    -	* The params filtering can be using named or positional.
    -	*/
    -	any function executeQuery(required string query,
    -							   any params=structnew(),
    -							   numeric offset=0,
    -					  		   numeric max=0,
    -					  		   numeric timeout=0,
    -						       boolean ignorecase=false,
    -						       boolean asQuery=getDefaultAsQuery(),
    -						       boolean unique=false,
    -						       string datasource=""){
    -		var options = {};
    -
    -		// Setup listing options
    -		if( arguments.offset neq 0 ){
    -			options.offset = arguments.offset;
    -		}
    -		if( arguments.max neq 0 ){
    -			options.maxresults = arguments.max;
    -		}
    -		if( arguments.timeout neq 0 ){
    -			options.timeout = arguments.timeout;
    -		}
    -		if( Len(arguments.datasource) ){
    -			options.datasource = arguments.datasource;
    -		}
    -		options.ignorecase = arguments.ignorecase;
    -		// Caching?
    -		if( getUseQueryCaching() ){
    -			options.cacheName  = getQueryCacheRegion();
    -			options.cacheable  = true;
    -		}
    -
    -		// Get listing
    -		var results = ORMExecuteQuery( arguments.query, arguments.params, arguments.unique, options );
    -
    -		// Null Checks
    -		if( isNull(results) ){
    -			if( arguments.asQuery ){ return queryNew(""); }
    -			if (arguments.unique) {
    -				return;
    -			} else {
    -				return [];
    -			}
    -		}
    -
    -		// Objects or Query?
    -		if( arguments.asQuery ){
    -			results = entityToQuery(results);
    -		}
    -
    -		return results;
    -	}
    -
    -	/**
    -	* Finds and returns the first result for the given query or null if no entity was found.
    -	* You can either use the query and params combination or send in an example entity to find.
    -	* @example.hint DEPRECATED. Use findByExample() instead, deprecated by 3.5
    -	*/
    -	any function findIt(string query,any params=structnew(), any example){
    -		var options = {maxresults=1};
    -
    -		// Caching?
    -		if( getUseQueryCaching() ){
    -			options.cacheName  = getQueryCacheRegion();
    -			options.cacheable  = true;
    -		}
    -
    -		// Get entry by example
    -		if( structKeyExists( arguments, "example") ){
    -			return findByExample( arguments.example, true );
    -		}
    -
    -		// Normal Find
    -		return ORMExecuteQuery( arguments.query, arguments.params, true, options);
    -	}
    -
    -	/**
    -	* Find all/single entities by example
    -	*/
    -	any function findByExample(any example,boolean unique=false){
    -		return entityLoadByExample(arguments.example,arguments.unique);
    -	}
    -
    -	/**
    -	* Find all the entities for the specified query and params or example
    -	* @example.hint	DEPRECATED use findByExample() this will be dropped in 3.5
    -	*/
    -	array function findAll(string query,
    -						    any params=structnew(),
    -						    numeric offset=0,
    -					        numeric max=0,
    -					        numeric timeout=0,
    -					        boolean ignoreCase=false,
    -						    any example){
    -
    -		// Get entry by example
    -		if( structKeyExists( arguments, "example") ){
    -			return findByExample( arguments.example );
    -		}
    -
    -		// Normal Execute Query
    -		arguments.asQuery=false;
    -		return executeQuery( argumentCollection=arguments );
    -	}
    -
    -	/**
    -	* Find one entity (or null if not found) according to a criteria structure
    -	*/
    -	any function findWhere(required string entityName, required struct criteria){
    -		// Caching?
    -		if( getUseQueryCaching() ){
    -			//if we are caching, we will use find all and return an array since entityLoad does not support both unique and caching
    -			var arEntity = findAllWhere( argumentCollection=arguments );
    -			//if we found an entity, return it
    -			if (arrayLen(arEntity)) {
    -				return arEntity[1];
    -			//else return NULL, just like entityLoad with unique would
    -			} else {
    -				return javaCast("null",0);
    -			}
    -		} else {
    -			return entityLoad( arguments.entityName, arguments.criteria, true );
    -		}
    -	}
    -
    -	/**
    -	* Find all entities according to criteria structure
    -	*/
    -	array function findAllWhere(required string entityName, required struct criteria, string sortOrder=""){
    -		var options = {};
    -		// Caching?
    -		if( getUseQueryCaching() ){
    -			options.cacheName  = getQueryCacheRegion();
    -			options.cacheable  = true;
    -		}
    -		return entityLoad( arguments.entityName, arguments.criteria, arguments.sortOrder, options);
    -	}
    -
    -	/**
    -    * Get a new entity object by entity name and you can pass in the properties structre also to bind the entity with properties
    -    * @entityName.hint The entity to create
    -    * @properties.hint The structure of data to populate the entity with. By default we will inspect for many-to-one, one-to-many and many-to-many relationships and compose them for you.
    -    * @composeRelationships.hint Automatically attempt to compose relationships from the incoming properties memento
    -    * @nullEmptyInclude.hint A list of keys to NULL when empty
    -    * @nullEmptyExclude.hint A list of keys to NOT NULL when empty
    -    * @ignoreEmpty.hint Ignore empty values on populations, great for ORM population
    -    * @include.hint A list of keys to include in the population from the incoming properties memento
    -    * @exclude.hint A list of keys to exclude in the population from the incoming properties memento
    -    */
    -	any function new(required string entityName, struct properties=structnew(), boolean composeRelationships=true, nullEmptyInclude="", nullEmptyExclude="", boolean ignoreEmpty=false, include="", exclude=""){
    -		var entity   = entityNew( arguments.entityName );
    -
    -		// Properties exists?
    -		if( NOT structIsEmpty(arguments.properties) ){
    -			populate(target=entity, memento=arguments.properties, composeRelationships=arguments.composeRelationships,
    -					 nullEmptyInclude=arguments.nullEmptyInclude, nullEmptyExclude=arguments.nullEmptyExclude, ignoreEmpty=arguments.ignoreEmpty,
    -					 include=arguments.include, exclude=arguments.exclude );
    -		}
    -
    -		// Event Handling? If enabled, call the postNew() interception
    -		if( getEventHandling() ){
    -			ORMEventHandler.postNew( entity, arguments.entityName );
    -		}
    -
    -		return entity;
    -	}
    -
    -	/**
    -    * Simple map to property population for entities
    -	* @memento.hint	The map/struct to populate the entity with
    -	* @scope.hint Use scope injection instead of setter injection, no need of setters, just tell us what scope to inject to
    -	* @trustedSetter.hint Do not check if the setter exists, just call it, great for usage with onMissingMethod() and virtual properties
    -	* @include.hint A list of keys to include in the population ONLY
    -	* @exclude.hint A list of keys to exclude from the population
    -    */
    -	any function populate(required any target,
    -						   required struct memento,
    -						   string scope="",
    -					 	   boolean trustedSetter=false,
    -						   string include="",
    -						   string exclude="",
    -						   boolean ignoreEmpty=false,
    -						   string nullEmptyInclude="",
    -						   string nullEmptyExclude="",
    -						   boolean composeRelationships=true){
    -
    -		return beanPopulator.populateFromStruct( argumentCollection=arguments );
    -	}
    -	
    -	/**
    -    * Simple map to property population for entities with structure key prefixes
    -	* @memento.hint	The map/struct to populate the entity with
    -	* @scope.hint Use scope injection instead of setter injection, no need of setters, just tell us what scope to inject to
    -	* @trustedSetter.hint Do not check if the setter exists, just call it, great for usage with onMissingMethod() and virtual properties
    -	* @include.hint A list of keys to include in the population ONLY
    -	* @exclude.hint A list of keys to exclude from the population
    -	* @prefix.hint The prefix used to filter, Example: 'user' would apply to the following formfield: 'user_id' and 'user_name' but not 'address_id' 
    -    */
    -	any function populateWithPrefix(required any target,
    -						  required struct memento,
    -						  string scope="",
    -					 	  boolean trustedSetter=false,
    -						  string include="",
    -						  string exclude="",
    -						  boolean ignoreEmpty=false,
    -						  string nullEmptyInclude="",
    -						  string nullEmptyExclude="",
    -						  boolean composeRelationships=true,
    -						  required string prefix){
    -		return beanPopulator.populateFromStructWithPrefix( argumentCollection=arguments );
    -	}
    -
    -	/**
    -	* Populate from JSON, for argument definitions look at the populate method
    -	* @JSONString.hint	The JSON packet to use for population
    -	* @scope.hint Use scope injection instead of setter injection, no need of setters, just tell us what scope to inject to
    -	* @trustedSetter.hint Do not check if the setter exists, just call it, great for usage with onMissingMethod() and virtual properties
    -	* @include.hint A list of keys to include in the population ONLY
    -	* @exclude.hint A list of keys to exclude from the population
    -	*/
    -	any function populateFromJSON(required any target,
    -								   required string JSONString,
    -								   string scope="",
    -								   boolean trustedSetter=false,
    -								   string include="",
    -								   string exclude="",
    -						   		   boolean ignoreEmpty=false,
    -						   		   string nullEmptyInclude="",
    -						   		   string nullEmptyExclude="",
    -						   		   boolean composeRelationships=true){
    -
    -		return beanPopulator.populateFromJSON( argumentCollection=arguments );
    -	}
    -
    -	/**
    -	* Populate from XML, for argument definitions look at the populate method
    -	* @root.hint The XML root element to start from
    -	* @xml.hint	The XML string or packet or XML object to populate from
    -	* @scope.hint Use scope injection instead of setter injection, no need of setters, just tell us what scope to inject to
    -	* @trustedSetter.hint Do not check if the setter exists, just call it, great for usage with onMissingMethod() and virtual properties
    -	* @include.hint A list of keys to include in the population ONLY
    -	* @exclude.hint A list of keys to exclude from the population
    -	*/
    -	any function populateFromXML(required any target,
    -								  required string xml,
    -								  string root="",
    -								  string scope="",
    -								  boolean trustedSetter=false,
    -								  string include="",
    -								  string exclude="",
    -						   		  boolean ignoreEmpty=false,
    -						   		  string nullEmptyInclude="",
    -						   		  string nullEmptyExclude="",
    -						   		  boolean composeRelationships=true){
    -
    -		return beanPopulator.populateFromXML( argumentCollection=arguments );
    -	}
    -
    -	/**
    -	* Populate from Query, for argument definitions look at the populate method
    -	* @qry.hint The query to use for population
    -	* @rowNumber.hint	The row number to use for population
    -	* @scope.hint Use scope injection instead of setter injection, no need of setters, just tell us what scope to inject to
    -	* @trustedSetter.hint Do not check if the setter exists, just call it, great for usage with onMissingMethod() and virtual properties
    -	* @include.hint A list of keys to include in the population ONLY
    -	* @exclude.hint A list of keys to exclude from the population
    -	*/
    -	any function populateFromQuery(required any target,
    -								    required any qry,
    -								    numeric rowNumber=1,
    -								    string scope="",
    -								    boolean trustedSetter=false,
    -								    string include="",
    -								    string exclude="",
    -						   			boolean ignoreEmpty=false,
    -						   			string nullEmptyInclude="",
    -						   		  	string nullEmptyExclude="",
    -						   		  	boolean composeRelationships=true){
    -
    -		return beanPopulator.populateFromQuery( argumentCollection=arguments );
    -	}
    -
    -
    -	/**
    -    * Refresh the state of an entity or array of entities from the database
    -    */
    -	any function refresh(required any entity){
    -		var objects = arrayNew(1);
    -
    -		if( not isArray(arguments.entity) ){
    -			arrayAppend(objects, arguments.entity);
    -		}
    -		else{
    -			objects = arguments.entity;
    -		}
    -
    -		for( var x=1; x lte arrayLen(objects); x++){
    -			orm.getSession(orm.getEntityDatasource(objects[x])).refresh( objects[x] );
    -		}
    -		return this;
    -	}
    -
    -	/**
    -    * Checks if the given entityName and id exists in the database, this method does not load the entity into session
    -	*/
    -	boolean function exists(required entityName, required any id) {
    -		var  options = {};
    -		options.datasource = orm.getEntityDatasource(arguments.entityName);
    -
    -		// Do it DLM style
    -		var count = ORMExecuteQuery("select count(id) from #arguments.entityName# where id = ?",[arguments.id],true,options);
    -		return (count gt 0);
    -	}
    -
    -	/**
    -	* Get an entity using a primary key, if the id is not found this method returns null, if the id=0 or blank it returns a new entity.
    -	* @entityName the name of the entity to retrieve
    -	* @id An optional primary key to use to retrieve the entity, if the id is 0 or empty
    -    */
    -	any function get(required string entityName,required any id,boolean returnNew=true) {
    -
    -		// check if id exists so entityLoad does not throw error
    -		if( (isSimpleValue(arguments.id) and len(arguments.id)) OR NOT isSimpleValue(arguments.id) ){
    -			var entity = entityLoadByPK(arguments.entityName, arguments.id);
    -			// Check if not null, then return it
    -			if( NOT isNull(entity) ){
    -				return entity;
    -			}
    -		}
    -
    -		// Check for return new?
    -		if( arguments.returnNew ){
    -
    -			// Check if ID=0 or empty to do convenience new entity
    -			if( isSimpleValue(arguments.id) and ( arguments.id eq 0  OR len(arguments.id) eq 0 ) ){
    -				return new(entityName=arguments.entityName);
    -			}
    -
    -		}
    -	}
    -
    -	/**
    -	* Retrieve all the instances from the passed in entity name using the id argument if specified
    -	* The id can be a list of IDs or an array of IDs or none to retrieve all.
    -    */
    -	array function getAll(required string entityName,any id,string sortOrder="") {
    -		var results = [];
    -
    -		// Return all entity values
    -		if( NOT structKeyExists(arguments,"id") ){
    -			return entityLoad(arguments.entityName,{},arguments.sortOrder);
    -		}
    -
    -		// type safe conversions
    -		arguments.id = convertIDValueToJavaType(entityName=arguments.entityName, id=arguments.id);
    -		var q = "FROM #arguments.entityName# where id in (:idlist)";
    -		// ordering?
    -		if( len(arguments.sortOrder) ){
    -			q &= " ORDER BY #arguments.sortOrder#";
    -		}
    -		// Execute native hibernate query
    -		var query = orm.getSession(orm.getEntityDatasource(arguments.entityName)).createQuery(q);
    -		// parameter binding
    -		query.setParameterList("idlist",arguments.id);
    -		// Caching?
    -		if( getUseQueryCaching() ){
    -			query.setCacheRegion(getQueryCacheRegion());
    -			query.setCacheable(true);
    -		}
    -		return query.list();
    -	}
    -
    -	/**
    -    * Delete an entity. The entity argument can be a single entity
    -	* or an array of entities. You can optionally flush the session also after committing
    -	* Transactions are used if useTransactions bit is set or the transactional argument is passed
    -    */
    -	any function delete(required any entity,boolean flush=false,boolean transactional=getUseTransactions()){
    -		// using transaction closure, well, semy closures :(
    -		if( arguments.transactional ){
    -			return $transactioned(variables.$delete, arguments);
    -		}
    -		$delete( argumentCollection=arguments );
    -		return this;
    -	}
    -	private any function $delete(required any entity,boolean flush=false){
    -		var objects = arrayNew(1);
    -		var objLen  = 0;
    -
    -		if( not isArray(arguments.entity) ){
    -			arrayAppend(objects, arguments.entity);
    -		}
    -		else{
    -			objects = arguments.entity;
    -		}
    -
    -		objLen = arrayLen(objects);
    -		for(var x=1; x lte objLen; x++){
    -			// Delete?
    -			entityDelete( objects[x] );
    -			// Flush?
    -			if( arguments.flush ){ orm.flush( orm.getEntityDatasource( objects[x] ) ); }
    -		}
    -
    -		return this;
    -	}
    -
    -	/**
    -	* Delete all entries for an entity DLM style and transaction safe. It also returns all the count of deletions
    -	* Transactions are used if useTransactions bit is set or the transactional argument is passed
    -	*/
    -	numeric function deleteAll(required string entityName,boolean flush=false,boolean transactional=getUseTransactions()){
    -		// using transaction closure, well, semy closures :(
    -		if( arguments.transactional ){
    -			return $transactioned(variables.$deleteAll, arguments);
    -		}
    -		return $deleteAll( argumentCollection=arguments );
    -	}
    -	private numeric function $deleteAll(required string entityName,boolean flush=false){
    -		var options = {};
    -		options.datasource = orm.getEntityDatasource(arguments.entityName);
    -
    -		var count   = 0;
    -		count = ORMExecuteQuery("delete from #arguments.entityName#",false,options);
    -
    -		// Auto Flush
    -		if( arguments.flush ){ orm.flush(options.datasource); }
    -
    -		return count;
    -	}
    -
    -	/**
    -	* Delete using an entity name and an incoming id, you can also flush the session if needed. The id parameter can be a single id or an array of IDs to delete
    -	* The method returns the count of deleted entities.
    -	* Transactions are used if useTransactions bit is set or the transactional argument is passed
    -	*/
    -	numeric function deleteByID(required string entityName, required any id, boolean flush=false, boolean transactional=getUseTransactions()){
    -		// using transaction closure, well, semy closures :(
    -		if( arguments.transactional ){
    -			return $transactioned(variables.$deleteByID, arguments);
    -		}
    -		return $deleteByID( argumentCollection=arguments );
    -	}
    -	private numeric function $deleteByID(required string entityName, required any id, boolean flush=false){
    -		var count   = 0;
    -
    -		// type safe conversions
    -		arguments.id = convertIDValueToJavaType(entityName=arguments.entityName, id=arguments.id);
    -
    -		// delete using lowercase id convention from hibernate for identifier
    -		var datasource = orm.getEntityDatasource(arguments.entityName);
    -		var query = orm.getSession(datasource).createQuery("delete FROM #arguments.entityName# where id in (:idlist)");
    -		query.setParameterList("idlist",arguments.id);
    -		count = query.executeUpdate();
    -
    -		// Auto Flush
    -		if( arguments.flush ){ orm.flush(datasource); }
    -
    -		return count;
    -	}
    -
    -	/**
    -	* Delete by using an HQL query and iterating via the results, it is not performing a delete query but
    -	* it actually is a select query that should retrieve objects to remove
    -	* Transactions are used if useTransactions bit is set or the transactional argument is passed
    -	*/
    -	any function deleteByQuery(required string query, any params, numeric max=0, numeric offset=0, boolean flush=false, boolean transactional=getUseTransactions(), string datasource="" ){
    -		// using transaction closure, well, semy closures :(
    -		if( arguments.transactional ){
    -			return $transactioned(variables.$deleteByQuery, arguments);
    -		}
    -		$deleteByQuery( argumentCollection=arguments );
    -		return this;
    -	}
    -	private any function $deleteByQuery(required string query, any params, numeric max=0, numeric offset=0, boolean flush=false, string datasource=""){
    -		var objects = arrayNew(1);
    -		var options = {};
    -
    -		// Setup query options
    -		if( arguments.offset neq 0 ){
    -			options.offset = arguments.offset;
    -		}
    -		if( arguments.max neq 0 ){
    -			options.maxresults = arguments.max;
    -		}
    -		if( Len(arguments.datasource) ){
    -			options.datasource = arguments.datasource;
    -		}
    -		// Query
    -		if( structKeyExists(arguments, "params") ){
    -			objects = ORMExecuteQuery(arguments.query, arguments.params, false, options);
    -		}
    -		else{
    -			objects = ORMExecuteQuery(arguments.query, false, options);
    -		}
    -
    -		delete(entity=objects,flush=arguments.flush,transactional=arguments.transactional);
    -		return this;
    -	}
    -
    -	/**
    -	* Deletes entities by using name value pairs as arguments to this function.  One mandatory argument is to pass the 'entityName'.
    -	* The rest of the arguments are used in the where class using AND notation and parameterized.
    -	* Ex: deleteWhere(entityName="User",age="4",isActive=true);
    -	* Transactions are used if useTransactions bit is set or the transactional argument is passed
    -	*/
    -	numeric function deleteWhere(required string entityName,boolean transactional=getUseTransactions()){
    -		// using transaction closure, well, semy closures :(
    -		if( arguments.transactional ){
    -			structDelete(arguments,"transactional");
    -			return $transactioned(variables.$deleteWhere, arguments);
    -		}
    -		structDelete(arguments,"transactional");
    -		return $deleteWhere( argumentCollection=arguments );
    -	}
    -	private numeric function $deleteWhere(required string entityName){
    -		var buffer   = createObject("java","java.lang.StringBuffer").init('');
    -		var key      = "";
    -		var operator = "AND";
    -		var params	  = {};
    -		var idx	  	  = 1;
    -		var count	  = 0;
    -		var options   = {};
    -
    -		options.datasource = orm.getEntityDatasource(arguments.entityName);
    -
    -		buffer.append('delete from #arguments.entityName#');
    -
    -		// Do we have arguments?
    -		if( structCount(arguments) gt 1){
    -			buffer.append(" WHERE");
    -		}
    -		else{
    -			throw(message="No where arguments sent, aborting deletion",
    -			  detail="We will not do a full delete via this method, you need to pass in named value arguments.",
    -			  type="BaseORMService.NoWhereArgumentsFound");
    -		}
    -
    -		// Go over Params
    -		for(key in arguments){
    -			// Build where parameterized
    -			if( key neq "entityName" ){
    -				params[key] = arguments[key];
    -				buffer.append(" #key# = :#key#");
    -				idx++;
    -				// Check AND?
    -				if( idx neq structCount(arguments) ){
    -					buffer.append(" AND");
    -				}
    -			}
    -		}
    -
    -		//start DLM deleteion
    -		try{
    -			count = ORMExecuteQuery( buffer.toString(), params, true, options);
    -		}
    -		catch("java.lang.NullPointerException" e){
    -			throw(message="A null pointer exception occurred when running the query",
    -			  detail="The most likely reason is that the keys in the passed in structure need to be case sensitive. Passed Keys=#structKeyList(params)#",
    -			  type="BaseORMService.MaybeInvalidParamCaseException");
    -		}
    -		catch(any e){
    -			rethrow;
    -		}
    -		return count;
    -	}
    -
    -	/**
    -    * Saves an array of passed entities in specified order
    -	* @entities An array of entities to save
    -	* Transactions are used if useTransactions bit is set or the transactional argument is passed
    -    */
    -	any function saveAll(required entities, forceInsert=false, flush=false,boolean transactional=getUseTransactions()){
    -		// using transaction closure, well, semy closures :(
    -		if( arguments.transactional ){
    -			return $transactioned(variables.$saveAll, arguments);
    -		}
    -		return $saveAll( argumentCollection=arguments );
    -	}
    -	private any function $saveAll(required entities, forceInsert=false, flush=false){
    -		var count 			=  arrayLen(arguments.entities);
    -		var eventHandling 	=  getEventHandling();
    -
    -		// iterate and save
    -		for(var x=1; x lte count; x++){
    -			// Event Handling? If enabled, call the preSave() interception
    -			if( eventHandling ){
    -				ORMEventHandler.preSave( arguments.entities[x] );
    -			}
    -			// Save it
    -			entitySave(arguments.entities[x], arguments.forceInsert);
    -			// Event Handling? If enabled, call the postSave() interception
    -			if( eventHandling ){
    -				ORMEventHandler.postSave( arguments.entities[x] );
    -			}
    -			// Auto Flush
    -			if( arguments.flush ){ orm.flush( orm.getEntityDatasource( arguments.entities[x] ) ); }
    -		}
    -
    -		return true;
    -	}
    -
    -	/**
    -    * Save an entity using hibernate transactions or not. You can optionally flush the session also
    -    */
    -	any function save(required any entity, boolean forceInsert=false, boolean flush=false, boolean transactional=getUseTransactions()){
    -		// using transaction closure, well, semy closures :(
    -		if( arguments.transactional ){
    -			return $transactioned(variables.$save, arguments);
    -		}
    -		return $save( argumentCollection=arguments );
    -	}
    -	any function $save(required any entity, boolean forceInsert=false, boolean flush=false){
    -		// Event handling flag
    -		var eventHandling = getEventHandling();
    -
    -		// Event Handling? If enabled, call the preSave() interception
    -		if( eventHandling ){
    -			ORMEventHandler.preSave( arguments.entity );
    -		}
    -
    -		// save
    -		entitySave(arguments.entity, arguments.forceInsert);
    -
    -		// Auto Flush
    -		if( arguments.flush ){ orm.flush(orm.getEntityDatasource(arguments.entity)); }
    -
    -		// Event Handling? If enabled, call the postSave() interception
    -		if( eventHandling ){
    -			ORMEventHandler.postSave( arguments.entity );
    -		}
    -
    -		return true;
    -	}
    -
    -	/**
    -	* Return the count of records in the DB for the given entity name. You can also pass an optional where statement
    -	* that can filter the count. Ex: count('User','age > 40 AND name="joe"'). You can even use params with this method:
    -	* Ex: count('User','age > ? AND name = ?',[40,"joe"])
    -	*/
    -	numeric function count(required string entityName,string where="", any params=structNew()){
    -		var buffer   = createObject("java","java.lang.StringBuffer").init('');
    -		var key      = "";
    -		var operator = "AND";
    -		var options = {};
    -
    -		options.datasource = orm.getEntityDatasource(arguments.entityName);
    -
    -		// Caching?
    -		if( getUseQueryCaching() ){
    -			options.cacheName  = getQueryCacheRegion();
    -			options.cacheable  = true;
    -		}
    -		buffer.append('select count(*) from #arguments.entityName#');
    -
    -		// build params
    -		if( len(trim(arguments.where)) ){
    -			buffer.append(" WHERE #arguments.where#");
    -		}
    -
    -		// execute query as unique for the count
    -		try{
    -			return ORMExecuteQuery( buffer.toString(), arguments.params, true, options);
    -		}
    -		catch("java.lang.NullPointerException" e){
    -			throw(message="A null pointer exception occurred when running the query",
    -				  detail="The most likely reason is that the keys in the passed in structure need to be case sensitive. Passed Keys=#structKeyList(arguments.params)#",
    -				  type="ORMService.MaybeInvalidParamCaseException");
    -		}
    -
    -	}
    -
    -	/**
    -	* Returns the count by passing name value pairs as arguments to this function.  One mandatory argument is to pass the 'entityName'.
    -	* The rest of the arguments are used in the where class using AND notation and parameterized.
    -	* Ex: countWhere(entityName="User",age="20");
    -	*/
    -	numeric function countWhere(required string entityName){
    -		var buffer   = createObject("java","java.lang.StringBuffer").init('');
    -		var key      = "";
    -		var operator = "AND";
    -		var params	  = {};
    -		var idx	  = 1;
    -		var options = {};
    -
    -		options.datasource = orm.getEntityDatasource(arguments.entityName);
    -
    -		buffer.append('select count(*) from #arguments.entityName#');
    -
    -		// Do we have params?
    -		if( structCount(arguments) gt 1){
    -			buffer.append(" WHERE");
    -		}
    -		// Go over Params
    -		for(key in arguments){
    -			// Build where parameterized
    -			if( key neq "entityName" ){
    -				params[key] = arguments[key];
    -				buffer.append(" #key# = :#key#");
    -				idx++;
    -				// Check AND?
    -				if( idx neq structCount(arguments) ){
    -					buffer.append(" AND");
    -				}
    -			}
    -		}
    -		// Caching?
    -		if( getUseQueryCaching() ){
    -			options.cacheName  = getQueryCacheRegion();
    -			options.cacheable  = true;
    -		}
    -
    -		// execute query as unique for the count
    -		try{
    -			return ORMExecuteQuery( buffer.toString(), params, true, options);
    -		}
    -		catch("java.lang.NullPointerException" e){
    -			throw(message="A null pointer exception occurred when running the count",
    -				  detail="The most likely reason is that the keys in the passed in structure need to be case sensitive. Passed Keys=#structKeyList(params)#",
    -				  type="ORMService.MaybeInvalidParamCaseException");
    -		}
    -	}
    -
    -	/**
    -    * Evict an entity from session, the id can be a string or structure for the primary key
    -	* You can also pass in a collection name to evict from the collection
    -    */
    -	any function evict(required string entityName,string collectionName, any id){
    -
    -		//Collection?
    -		if( structKeyExists(arguments,"collectionName") ){
    -			if( structKeyExists(arguments,"id") )
    -				ORMEvictCollection(arguments.entityName,arguments.collectionName, arguments.id);
    -			else
    -				ORMEvictCollection(arguments.entityName,arguments.collectionName);
    -		}
    -		// Single Entity
    -		else{
    -			if( structKeyExists(arguments,"id") )
    -				evictEntity( this.get(entityName=arguments.entityName,id=arguments.id) );
    -			else
    -				evictEntity( this.new(entityName=arguments.entityName) );
    -		}
    -
    -		return this;
    -	}
    -
    -	/**
    -    * Evict entity objects from session.
    -	* @entities The argument can be one persistence entity or an array of entities
    -    */
    -	any function evictEntity(required any entities){
    -		var objects = arrayNew(1);
    -
    -		if( not isArray(arguments.entities) ){
    -			arrayAppend(objects, arguments.entities);
    -		}
    -		else{
    -			objects = arguments.entities;
    -		}
    -
    -		for( var x=1; x lte arrayLen(objects); x++){
    -			orm.getSession(orm.getEntityDatasource(objects[x])).evict( objects[x] );
    -		}
    -
    -		return this;
    -	}
    -
    -	/**
    -    * Evict all queries in the default cache or the cache region passed
    -    */
    -	any function evictQueries(string cacheName, string datasource){
    -		orm.evictQueries( argumentCollection=arguments );
    -		return this;
    -	}
    -
    -	/**
    -    * Merge an entity or array of entities back into the session
    -    */
    -	any function merge(required any entity){
    -		var objects = [];
    -
    -		if( not isArray( arguments.entity ) ){
    -			arrayAppend( objects, arguments.entity );
    -		}
    -		else{
    -			objects = arguments.entity;
    -		}
    -
    -		for( var x=1; x lte arrayLen( objects ); x++){
    -			entityMerge( objects[ x ] );
    -		}
    -
    -		return this;
    -	}
    -
    -	/**
    -	* Clear the session removes all the entities that are loaded or created in the session.
    -	* This clears the first level cache and removes the objects that are not yet saved to the database.
    -	*/
    -	any function clear(string datasource=orm.getDefaultDatasource()){
    -		orm.clearSession(arguments.datasource);
    -		return this;
    -	}
    -
    -	/**
    -	* Checks if the session contains dirty objects that are awaiting persistence
    -	*/
    -	boolean function isSessionDirty(string datasource=orm.getDefaultDatasource()){
    -		return orm.getSession(arguments.datasource).isDirty();
    -	}
    -
    -	/**
    -	* Checks if the current session contains the passed in entity
    -	*/
    -	boolean function sessionContains(required any entity){
    -		var ormSession = orm.getSession(orm.getEntityDatasource(arguments.entity));
    -		// weird CFML thing
    -		return ormSession.contains(arguments.entity);
    -	}
    -
    -	/**
    -	* Information about the first-level (session) cache for the current session
    -	*/
    -	struct function getSessionStatistics(string datasource=orm.getDefaultDatasource()){
    -		var stats   = orm.getSession(arguments.datasource).getStatistics();
    -		var results = {
    -			collectionCount = stats.getCollectionCount(),
    -			collectionKeys  = stats.getCollectionKeys().toString(),
    -			entityCount	    = stats.getEntityCount(),
    -			entityKeys		= stats.getEntityKeys().toString()
    -		};
    -
    -		return results;
    -	}
    -
    -	/**
    -	* A nice onMissingMethod template to create awesome dynamic methods.
    -	*/
    -	any function onMissingMethod(string missingMethodName, struct missingMethodArguments){
    -		var method = arguments.missingMethodName;
    -		var args   = arguments.missingMethodArguments;
    -		
    -		// Dynamic Find Unique Finders
    -		if( left( method, 6 ) eq "findBy" and len( method ) GT 6 ){
    -			return findDynamically(missingMethodName=right( method, len( method ) - 6 ), missingMethodArguments=args, unique=true);
    -		}
    -		// Dynamic find All Finders
    -		if( left( method, 9 ) eq "findAllBy"  and len( method ) GT 9 ){
    -			return findDynamically(missingMethodName=right( method, len( method ) - 9 ), missingMethodArguments=args, unique=false);
    -		}
    -		// Dynamic countBy Finders
    -		if( left( method, 7 ) eq "countBy"  and len( method ) GT 7 ){
    -			return findDynamically(missingMethodName=right( method, len( method ) - 7 ), missingMethodArguments=args, unique=true, isCounting=true);
    -		}
    -		
    -		// Throw exception, method not found.
    -		throw(message="Invalid method call: #method#", detail="The dynamic/static method you called does not exist", type="BaseORMService.MissingMethodException");
    -	}
    -	
    -	/**
    -	* Compile HQL from a dynamic method call
    -	*/
    -	private any function compileHQLFromDynamicMethod(string missingMethodName, struct missingMethodArguments, boolean unique=true, boolean isCounting=false, struct params, entityName){
    -		var method 			= arguments.missingMethodName;
    -		var args   			= arguments.missingMethodArguments;
    -		
    -		// Get all real property names
    -		var realPropertyNames = getPropertyNames( arguments.entityName );
    -		// Match our method gramars ini the method string
    -		var methodGrammars = REMatchNoCase( "((?!(and|or|$))\w)+(#ALL_CONDITIONALS_REGEX#)?(and|or|$)", method );
    -		
    -		// Throw exception if no method grammars found
    -		if( !arrayLen( methodGrammars ) ){
    -			throw(message="Invalid dynamic method grammar expression. Please check your syntax. You could be missing property names or conditionals", 
    -				  detail="Expression: #method#", 
    -				  type="BaseORMService.InvalidMethodGrammar");
    -		}
    -		
    -		// Iterate over method grammars to build HQL Expressions
    -		var HQLExpressions = [];
    -		for( var thisGrammar in methodGrammars ){
    -			// create expression syntax
    -			var expression = { property = "", conditional = "eq", operator = "and", sql = "=" };
    -
    -			// Check for Or expression, AND is default expression
    -			if( right( thisGrammar, 2 ) eq "or" ){
    -				expression.operator = "or";
    -			}
    -			// Remove operator now that we have it
    -			thisGrammar = REReplacenoCase( thisGrammar, "(and|or)$", "" );
    -			
    -			// Get property by removing conditionals from the expression
    -			expression.property = REReplacenoCase( thisGrammar, "(#ALL_CONDITIONALS_REGEX#)$", "" );
    -			// Verify if property exists in valid properties
    -			// TODO: Add relationships later 
    -			var realPropertyIndex = arrayFindNoCase( realPropertyNames, expression.property );
    -			if( realPropertyIndex EQ 0 ){
    -				throw(message="The property you requested #expression.property# is not a valid property in the #arguments.entityName# entity",
    -					  detail="Valid properties are #arrayToList( realPropertyNames )#",
    -					  type="BaseORMService.InvalidEntityProperty");
    -			}
    -			// now save the actual property name to the passed in property to avoid case issues with Hibernate
    -			expression.property = realPropertyNames[ realPropertyIndex ];
    -			// Remove property now from method expression
    -			thisGrammar = REReplacenoCase( thisGrammar, "#expression.property#", "" );
    -			
    -			// Get Conditional Operator now if it exists, else it defaults to EQ
    -			if( len( thisGrammar ) ){
    -				// Match the conditional statement
    -				var conditional = REMatchNoCase( "(#ALL_CONDITIONALS_REGEX#)$", thisGrammar );
    -				// Did we match?
    -				if( arrayLen( conditional ) ){
    -					expression.conditional = conditional[ 1 ];
    -					expression.sql = CONDITIONALS_SQL_MAP[ expression.conditional ];
    -				}
    -				else{
    -					throw(message="Invalid conditional statement in method expression: #thisGrammar#",
    -						  detail="Valid Conditionals: #ALL_CONDITIONALS#",
    -						  type="BaseORMService.InvalidConditionalExpression");
    -				}
    -			}
    -			
    -			// Add to expressions
    -			arrayAppend( HQLExpressions, expression );
    -		}
    -		// end compile grammars
    -		
    -		// Build the HQL
    -		var where = "";
    -		// Begin building the hql statement with or without counts
    -		var hql = "";
    -		if( arguments.isCounting ){
    -			hql &= "select count(id) ";
    -		}
    -		hql &= "from " & arguments.entityName;	
    -		
    -		var paramIndex = 1;
    -		for( var thisExpression in HQLExpressions ){
    -			if( len( where ) ){
    -				where = "#where# #thisExpression.operator# ";
    -			}
    -			switch( trim( thisExpression.conditional ) ){
    -				case "isNull" : case "isNotNull" : { 
    -					where = "#where# #thisExpression.property# #thisExpression.sql#";
    -					break; 
    -				}
    -				case "between" : case "notBetween" : {
    -					where = "#where# #thisExpression.property# #thisExpression.sql# :param#paramIndex++# and :param#paramIndex++#";
    -					break;
    -				}
    -				case "inList" : case "notInList" : {
    -					where = "#where# #thisExpression.property# #thisExpression.sql# (:param#paramIndex++#)";
    -					// Verify if the param is an array collection
    -					if( isSimpleValue( params["param#paramIndex-1#"] ) ){
    -						params["param#paramIndex-1#"] = listToArray( params["param#paramIndex-1#"] );
    -					}
    -					break;
    -				}
    -				default:{
    -					where = "#where# #thisExpression.property# #thisExpression.sql# :param#paramIndex++#";	
    -					break;	
    -				}
    -			}
    -		}	
    -		
    -		// Finalize the HQL
    -		return hql & " where #where#";
    -	}
    -	
    -	/**
    -	* A method for finding entity's dynamically, for example:
    -	* findByLastNameAndFirstName('User', 'Tester', 'Test');
    -	* findByLastNameOrFirstName('User', 'Tester', 'Test')
    -	* findAllByLastNameIsNotNull('User');
    -	* The first argument must be the 'entityName' or a named agument called 'entityname'
    -	* Any argument which is a structure will be used as options for the query: { ignorecase, maxresults, offset, cacheable, cachename, timeout }
    -	*/
    -	any function findDynamically(string missingMethodName, struct missingMethodArguments, boolean unique=true, boolean isCounting=false){
    -		var method 			= arguments.missingMethodName;
    -		var args   			= arguments.missingMethodArguments;
    -		var dynamicCacheKey = hash( arguments.toString() );
    -		var hql				= "";
    -		
    -		// setup the params to bind from the arguments, and also distinguish the incoming query options
    -		var params 	= {};
    -		var options = {};
    -		// Verify entityName, if does not exist, use the first argument.
    -		if( !structKeyExists(args, "entityName" ) ){
    -			arguments.entityName = args[ 1 ];
    -			// Remove it like a mighty ninja
    -			structDelete( args, "1" );
    -		}
    -		else{
    -			arguments.entityName = args.entityName;
    -			// Remove it like a mighty ninja
    -			structDelete( args, "entityName" );
    -		}
    -		// Process arguments to binding parameters, we use named as they bind better in HQL, go figure
    -		for(var i=1; i LTE ArrayLen( args ); i++){
    -			// Check if the argument is a structure, if it is, then these are the query options
    -			if( isStruct( args[ i ] ) ){
    -				options = args[ i ];
    -			}
    -			// Normal params
    -			else{
    -				params[ "param#i#" ] = args[ i ];
    -			}
    -		}
    -		// Check if we have already the signature for this request
    -		if( structKeyExists( HQLDynamicCache, dynamicCacheKey ) ){
    -			hql = HQLDynamicCache[ dynamicCacheKey ];
    -		}
    -		else{
    -			arguments.params = params;
    -			hql = compileHQLFromDynamicMethod( argumentCollection=arguments );
    -			// store compiled HQL
    -			HQLDynamicCache[ dynamicCacheKey ] = hql;
    -		}
    -		
    -		//results struct used for testing
    -		var results = structNew();
    -		results.method = method;
    -		results.params = params;
    -		results.options = options;
    -		results.unique = arguments.unique;
    -		results.isCounting = arguments.isCounting;
    -		results.hql = hql;
    -		
    -		//writeDump( ORMExecuteQuery( hql, params, arguments.unique, options) );
    -		//writeDump(results);abort;
    -		
    -		// execute query as unique for the count
    -		try{
    -			return ORMExecuteQuery( hql, params, arguments.unique, options);
    -		}
    -		catch(Any e){
    -			if( findNoCase("org.hibernate.NonUniqueResultException", e.detail) ){
    -		 		throw(message=e.message & e.detail,
    -					  detail="If you do not want unique results then use 'FindAllBy' instead of 'FindBy'",
    -				  	  type="ORMService.NonUniqueResultException");
    -			}
    -			throw(message=e.message & e.detail, type="BaseORMService.HQLQueryException", detail="Dynamic compiled query: #results.toString()#");
    -		}
    -		
    -	}
    -	
    -
    -	/**
    -	* Returns the key (id field) of a given entity, either simple or composite keys.
    -	* If the key is a simple pk then it will return a string, if it is a composite key then it returns an array
    -	*/
    -	any function getKey(required string entityName){
    -		var hibernateMD =  orm.getSessionFactory(orm.getEntityDatasource(arguments.entityName)).getClassMetaData(arguments.entityName);
    -
    -		// Is this a simple key?
    -		if( hibernateMD.hasIdentifierProperty() ){
    -			return hibernateMD.getIdentifierPropertyName();
    -		}
    -
    -		// Composite Keys?
    -		if( hibernateMD.getIdentifierType().isComponentType() ){
    -			// Do conversion to CF Array instead of java array, just in case
    -			return listToArray(arrayToList(hibernateMD.getIdentifierType().getPropertyNames()));
    -		}
    -
    -		return "";
    -	}
    -
    -	/**
    -	* Returns the Property Names of the entity via hibernate metadata
    -	*/
    -	array function getPropertyNames(required string entityName){
    -		return orm.getSessionFactory( orm.getEntityDatasource(arguments.entityName) ).getClassMetaData( arguments.entityName ).getPropertyNames();
    -	}
    -
    -	/**
    -	* Returns the table name that the current entity string belongs to via hibernate metadata
    -	*/
    -	string function getTableName(required string entityName){
    -		return orm.getSessionFactory( orm.getEntityDatasource(arguments.entityName) ).getClassMetadata( arguments.entityName ).getTableName();
    -	}
    -
    -	/**
    - 	* Returns the entity name from a given entity object via session lookup or if new object via metadata lookup
    -	*/
    -	function getEntityGivenName(required entity) {
    -		if( sessionContains( arguments.entity ) ){
    - 			return orm.getSession( orm.getEntityDatasource(arguments.entity) ).getEntityName( entity );
    - 		}
    -
    - 		// else long approach
    - 		var md = getMetadata( arguments.entity );
    - 		if( structKeyExists(md, "entityname") ){ return md.entityname; }
    - 		return listLast( md.name, ".");
    - 	}
    -
    -	/**
    -	* Coverts an ID, list of ID's, or array of ID's values to the proper java type
    -	* The method returns a coverted array of ID's
    -	*/
    -	any function convertIDValueToJavaType(required entityName, required id){
    -		var hibernateMD = orm.getSessionFactory(orm.getEntityDatasource(arguments.entityName)).getClassMetaData(arguments.entityName);
    -
    -		if(isDefined("hibernateMD") and not hibernateMD.getIdentifierType().isComponentType() ){
    -			//id conversion to array
    -			if( isSimpleValue(arguments.id) ){
    -				arguments.id = listToArray(arguments.id);
    -			}
    -
    -			// Convert to hibernate native types
    -			for (var i=1; i lte arrayLen(arguments.id); i=i+1){
    -				arguments.id[i] = hibernateMD.getIdentifierType().fromStringValue(arguments.id[i]);
    -			}
    -		}
    -
    -		return arguments.id;
    -	}
    -	
    -	/**
    -	* Coverts a value to the correct javaType for the property passed in
    -	* The method returns the value in the proper Java Type
    -	*/
    -	any function convertValueToJavaType(required entityName, required propertyName, required value){
    -		var hibernateMD = orm.getSessionFactory(orm.getEntityDatasource(arguments.entityName)).getClassMetaData(arguments.entityName);
    -
    -		return hibernateMD.getPropertyType(arguments.propertyName).fromStringValue(arguments.value);
    -	}
    -
    -	/**
    -	* Get our hibernate org.hibernate.criterion.Restrictions proxy object
    -	*/
    -	public any function getRestrictions(){
    -		return restrictions;
    -	}
    -
    -	/**
    -	* Do a hibernate criteria based query with projections. You must pass an array of criterion objects by using the Hibernate Restrictions object that can be retrieved from this service using ''getRestrictions()''.  The Criteria interface allows to create and execute object-oriented queries. It is powerful alternative to the HQL but has own limitations. Criteria Query is used mostly in case of multi criteria search screens, where HQL is not very effective.
    -	*/
    -	public any function criteriaQuery(required entityName,
    -									  array criteria=ArrayNew(1),
    -					  		 		  string sortOrder="",
    -					  		 		  numeric offset=0,
    -					  				  numeric max=0,
    -					  		 		  numeric timeout=0,
    -					  		 		  boolean ignoreCase=false,
    -					  		 		  boolean asQuery=getDefaultAsQuery()){
    -		// create Criteria query object
    -		var qry = createCriteriaQuery(arguments.entityName, arguments.criteria);
    -
    -		// Setup listing options
    -		if( arguments.offset NEQ 0 ){
    -			qry.setFirstResult(arguments.offset);
    -		}
    -		if(arguments.max GT 0){
    -			qry.setMaxResults(arguments.max);
    -		}
    -		if( arguments.timeout NEQ 0 ){
    -			qry.setTimeout(arguments.timeout);
    -		}
    -
    -		// Caching
    -		if( getUseQueryCaching() ){
    -			qry.setCacheRegion(getQueryCacheRegion());
    -			qry.setCacheable(true);
    -		}
    -
    -		// Sort Order Case
    -		if( Len(Trim(arguments.sortOrder)) ){
    -			var sortTypes = listToArray(arguments.sortOrder);
    -			for(var sortType in sortTypes) {
    -				var sortField = Trim(ListFirst(sortType," "));
    -				var sortDir = "ASC";
    -				var Order = CreateObject("java","org.hibernate.criterion.Order");
    -
    -				if(ListLen(sortType," ") GTE 2){
    -					sortDir = ListGetAt(sortType,2," ");
    -				}
    -
    -				switch(UCase(sortDir)) {
    -					case "DESC":
    -						var orderBy = Order.desc(sortField);
    -						break;
    -					default:
    -						var orderBy = Order.asc(sortField);
    -						break;
    -				}
    -				// ignore case
    -				if(arguments.ignoreCase){
    -					orderBy.ignoreCase();
    -				}
    -				// add order to query
    -				qry.addOrder(orderBy);
    -			}
    -		}
    -
    -		// Get listing
    -		var results = qry.list();
    -
    -		// Is it Null? If yes, return empty array
    -		if( isNull(results) ){ results = []; }
    -
    -		// Objects or Query?
    -		if( arguments.asQuery ){
    -			results = EntityToQuery(results);
    -		}
    -
    -		return results;
    -	}
    -
    -	/**
    -	* Get the record count using hibernate projections and criterion for specific queries
    -	*/
    -	numeric function criteriaCount(required entityName, array criteria=ArrayNew(1)){
    -		// create a new criteria query object
    -		var qry = createCriteriaQuery(arguments.entityName, arguments.criteria);
    -		var projections = CreateObject("java","org.hibernate.criterion.Projections");
    -
    -		qry.setProjection( projections.rowCount() );
    -
    -		return qry.uniqueResult();
    -	}
    -
    -	/**
    -	* Get a brand new criteria builder object
    -	* @entityName The name of the entity to bind this criteria query to
    -	* @useQueryCaching Activate query caching for the list operations
    -	* @queryCacheRegion The query cache region to use, which defaults to criterias.{entityName}
    -	* @defaultAsQuery To return results as queries or array of objects or reports, default is array as results might not match entities precisely
    -	*/
    -	any function newCriteria(
    -		required string entityName,
    -		boolean useQueryCaching=false,
    -		string queryCacheRegion=""
    -	){
    -		
    -		// mix in yourself as a dependency
    -		arguments.ORMService = this;
    -		// create new criteria builder
    -		return new CriteriaBuilder( argumentCollection=arguments );
    -	}
    -
    -	/**
    -	* Create a new hibernate criteria object according to entityname and criterion array objects
    -	*/
    -	private any function createCriteriaQuery(required entityName, array criteria=ArrayNew(1)){
    -		var qry = orm.getSession(orm.getEntityDatasource(arguments.entityName)).createCriteria( arguments.entityName );
    -
    -		for(var i=1; i LTE ArrayLen(arguments.criteria); i++) {
    -			if( isSimpleValue( arguments.criteria[i] ) ){
    -				// create criteria out of simple values for associations with alias
    -				qry.createCriteria( arguments.criteria[i], arguments.criteria[i] );
    -			}
    -			else{
    -				// add criterion
    -				qry.add( arguments.criteria[i] );
    -			}
    -		}
    -
    -		return qry;
    -	}
    -
    -	/**
    -	* My hibernate safe transaction closure wrapper
    -	* @method the method to closure
    -	* @argCollection the arguments to passthrough
    -	*/
    -	private any function $transactioned( required method, argCollection=structnew() ){
    -		// Are we already in a transaction?
    -		if( structKeyExists(request,"cbox_aop_transaction") ){
    -			return arguments.method(argumentCollection=arguments.argCollection);
    -		}
    -
    -		// transaction safe call, start one
    -		// mark transaction began
    -		request["cbox_aop_transaction"] = true;
    -		transaction{
    -
    -			try{
    -				// Call method
    -				results = arguments.method(argumentCollection=arguments.argCollection);
    -				// commit transaction
    -				transactionCommit();
    -			}
    -			catch(Any e){
    -				// remove pointer
    -				structDelete(request,"cbox_aop_transaction");
    -				// RollBack Transaction
    -				transactionRollback();
    -				//throw it
    -				rethrow;
    -			}
    -
    -		}
    -
    -		// remove pointer, out of transaction now.
    -		structDelete(request,"cbox_aop_transaction");
    -		// Results? If found, return them.
    -		if( NOT isNull(results) ){ return results; }
    -
    -	}
    -}
    diff --git a/src/cfml/system/wirebox/system/orm/hibernate/CriteriaBuilder.cfc b/src/cfml/system/wirebox/system/orm/hibernate/CriteriaBuilder.cfc
    deleted file mode 100644
    index 085f6b3d3..000000000
    --- a/src/cfml/system/wirebox/system/orm/hibernate/CriteriaBuilder.cfc
    +++ /dev/null
    @@ -1,309 +0,0 @@
    -/**
    -********************************************************************************
    -Copyright Since 2005 ColdBox Framework by Luis Majano and Ortus Solutions, Corp
    -www.coldbox.org | www.luismajano.com | www.ortussolutions.com
    -********************************************************************************
    -
    -Author      :	Luis Majano
    -Description :
    -	This is the ColdBox Criteria Builder Class that helps you create a nice programmatic
    -	DSL language for building hibernate criteria queries and projections without the added
    -	complexities.
    -	
    -We also setup several public properties:
    -
    -this.PROJECTIONS - Maps to the Hibernate projections class: org.hibernate.criterion.Projections
    -this.RESTRICTIONS - Maps to our ColdBox restrictions class: wirebox.system.orm.hibernate.criterion.Restrictions
    -
    -Join Types
    -this.FULL_JOIN 
    -	Specifies joining to an entity based on a full join.
    -this.INNER_JOIN 
    -	Specifies joining to an entity based on an inner join.
    -this.LEFT_JOIN 
    -	Specifies joining to an entity based on a left outer join.
    -
    -Result Transformers
    -this.ALIAS_TO_ENTITY_MAP 
    -	Each row of results is a Map from alias to entity instance
    -this.DISTINCT_ROOT_ENTITY 
    -	Each row of results is a distinct instance of the root entity
    -this.PROJECTION 
    -	This result transformer is selected implicitly by calling setProjection()
    -this.ROOT_ENTITY 
    -	Each row of results is an instance of the root entity
    -	
    -*/
    -import wirebox.system.orm.hibernate.*;
    -component accessors="true" extends="wirebox.system.orm.hibernate.BaseBuilder" {
    -	
    -	// The criteria values this criteria builder builds upon.
    -	property name="criterias" type="array";
    -	// The queryCacheRegion name property for all queries in this criteria object
    -	property name="queryCacheRegion" type="string" default="criterias.{entityName}";
    -	// The bit that tells the service to enable query caching, disabled by default
    -	property name="useQueryCaching" type="boolean" default="false";
    -
    -/************************************** Constructor *********************************************/
    -
    -	// Constructor
    -	CriteriaBuilder function init(
    -		required string entityName,
    -		boolean useQueryCaching=false,
    -		string queryCacheRegion="",
    -		required any ORMService
    -	){	
    -								  	  
    -		// Determine datasource for given entityName
    -		var orm			 = getORMUtil();
    -		var datasource 	 = orm.getEntityDatasource( arguments.entityName );	  
    -		
    -		// setup basebuilder with criteria query and restrictions
    -		super.init( entityName=arguments.entityName, 
    -					criteria=orm.getSession( datasource ).createCriteria( arguments.entityName ), 
    -					restrictions=new criterion.Restrictions(), 
    -					ORMService=arguments.ORMService );    
    -		
    -		// local criterion values
    -		variables.criterias = [];	
    -		// caching?
    -		variables.useQueryCaching = arguments.useQueryCaching;
    -		// caching region?
    -		if( len( trim( arguments.queryCacheRegion ) ) EQ 0 ){
    -			arguments.queryCacheRegion = "criterias.#arguments.entityName#";
    -		}
    -		variables.queryCacheRegion = arguments.queryCacheRegion;
    -		 
    -		return this;
    -	}
    -
    -/************************************** PUBLIC *********************************************/	
    -	
    -	/**
    -	* Execute the criteria queries you have defined and return the results, you can pass optional parameters or define them via our methods
    -	*/
    -	any function list(numeric offset=0,
    -	  				  numeric max=0,
    -	  		 		  numeric timeout=0,
    -	  		 		  string  sortOrder="",
    -	  		 		  boolean ignoreCase=false,
    -	  		 		  boolean asQuery=false){
    -	  		 		  	 
    -		// Setup listing options
    -		if( arguments.offset NEQ 0 ){
    -			firstResult(arguments.offset);
    -		}
    -		if(arguments.max GT 0){
    -			maxResults(arguments.max);
    -		}
    -		if( arguments.timeout NEQ 0 ){
    -			this.timeout(arguments.timeout);
    -		}
    -
    -		// Caching
    -		if( getUseQueryCaching() ){
    -			cache(true,getQueryCacheRegion());
    -		}
    -
    -		// Sort Order 
    -		if( Len(Trim(arguments.sortOrder)) ){
    -			normalizeOrder( arguments.sortOrder, arguments.ignoreCase );
    -		}
    -		
    -		// process interception
    -		if( ORMService.getEventHandling() ){
    -			variables.eventManager.processState( "beforeCriteriaBuilderList", {
    -				"criteriaBuilder" = this
    -			});
    -		}
    -
    -		// Get listing
    -		var results = nativeCriteria.list();
    -
    -		// Is it Null? If yes, return empty array
    -		if( isNull(results) ){ results = []; }
    -
    -		// Objects or Query?
    -		if( arguments.asQuery ){
    -			results = EntityToQuery(results);
    -		}
    -
    -		// process interception
    -		if( ORMService.getEventHandling() ){
    -			variables.eventManager.processState( "afterCriteriaBuilderList", {
    -				"criteriaBuilder" = this,
    -				"results" = results
    -			});
    -		}
    -		return results;
    -	}
    -	
    -	// pass off arguments to higher-level restriction builder, and handle the results
    -	any function onMissingMethod(required string missingMethodName, required struct missingMethodArguments) {
    -		// get the restriction/new criteria 
    -		var r = createRestriction( argumentCollection=arguments );
    -		// switch on the object type
    -		switch( getMetaData( r ).name ) {
    -			// if it's a builder, just return this
    -			case 'wirebox.system.orm.hibernate.CriteriaBuilder':
    -				break;
    -			// everything else is a real restriction; add it to native criteria, then return this
    -			default: 
    -				nativeCriteria.add( r );
    -				
    -				// process interception
    -				if( ORMService.getEventHandling() ){
    -					variables.eventManager.processState( "onCriteriaBuilderAddition", {
    -						"type" = "Restriction",
    -						"criteriaBuilder" = this
    -					});
    -				}
    -
    -				break;
    -		}
    -		return this;
    -	}
    -	
    -	// create an instance of a detached criteriabuilder that can be added, like criteria, to the main criteria builder
    -	any function createSubcriteria( required string entityName, string alias="" ) {
    -		// create detached builder
    -		arguments.ORMService = variables.ORMService;
    -		var subcriteria = new DetachedCriteriaBuilder( argumentCollection=arguments );
    -		
    -		// process interception
    -		if( ORMService.getEventHandling() ){
    -			variables.eventManager.processState( "onCriteriaBuilderAddition", {
    -				"type" = "Subquery",
    -				"criteriaBuilder" = this
    -			});
    -		}
    -
    -		// return the subscriteria instance so we can keep chaining methods to it, but rooted to the subcriteria
    -		return subcriteria;
    -	}
    -	
    -	// Enable caching of this query result, provided query caching is enabled for the underlying session factory.
    -	any function cache(required boolean cache=true,string cacheRegion){
    -		nativeCriteria.setCacheable( javaCast("boolean", arguments.cache) );
    -		if( structKeyExists(arguments,"cacheRegion") ){
    -			nativeCriteria.setCacheRegion( arguments.cacheRegion );
    -		}
    -		return this;
    -	}
    -	
    -	// Set the name of the cache region to use for query result caching.
    -	any function cacheRegion(required string cacheRegion){
    -		nativeCriteria.setCacheRegion( arguments.cacheRegion );
    -		return this;
    -	}
    -	
    -	// Set a fetch size for the underlying JDBC query.
    -	any function fetchSize(required numeric fetchSize){
    -		nativeCriteria.setFetchSize( javaCast("int", arguments.fetchSize) );
    -		return this;
    -	}
    -	
    -	// Set the first result to be retrieved or the offset integer
    -	any function firstResult(required numeric firstResult){
    -		nativeCriteria.setFirstResult( javaCast("int", arguments.firstResult) );
    -		if( SQLHelper.canLogLimitOffset() ) {
    -			
    -			// process interception
    -			if( ORMService.getEventHandling() ){
    -				variables.eventManager.processState( "onCriteriaBuilderAddition", {
    -					"type" = "Offset",
    -					"criteriaBuilder" = this
    -				});
    -			}
    -
    -		}
    -		return this;
    -	}
    -	
    -	// Set a limit upon the number of objects to be retrieved.
    -	any function maxResults(required numeric maxResults){
    -		nativeCriteria.setMaxResults( javaCast("int", arguments.maxResults) );
    -		if( SQLHelper.canLogLimitOffset() ) {
    -			
    -			// process interception
    -			if( ORMService.getEventHandling() ){
    -				variables.eventManager.processState( "onCriteriaBuilderAddition", {
    -					"type" = "Max",
    -					"criteriaBuilder" = this
    -				});
    -			}
    -
    -		}
    -		return this;
    -	}
    -	
    -	// Set the read-only/modifiable mode for entities and proxies loaded by this Criteria, defaults to readOnly=true
    -	any function readOnly(boolean readOnly=true){
    -		nativeCriteria.setReadOnly( javaCast("boolean", arguments.readOnly) );
    -		return this;
    -	}
    -	
    -	// Set a timeout for the underlying JDBC query.
    -	any function timeout(required numeric timeout){
    -		nativeCriteria.setTimeout( javaCast("int", arguments.timeout) );
    -		return this;
    -	}
    -	
    -	// Convenience method to return a single instance that matches the built up criterias query, or null if the query returns no results.
    -	any function get(){
    -		return nativeCriteria.uniqueResult();
    -	}
    -	
    -	/**
    -	* Get the record count using hibernate projections for the given criterias
    -	* @propertyName The name of the property to do the count on or do it for all row results instead
    -	*/
    -	numeric function count(propertyName=""){
    -		// process interception
    -		if( ORMService.getEventHandling() ){
    -			variables.eventManager.processState( "beforeCriteriaBuilderCount", {
    -				"criteriaBuilder" = this
    -			});
    -		}
    -		// else project on the local criterias
    -		if( len( arguments.propertyName ) ){
    -			nativeCriteria.setProjection( this.projections.countDistinct( arguments.propertyName ) );
    -		}
    -		else{
    -			nativeCriteria.setProjection( this.projections.distinct( this.projections.rowCount() ) );
    -		}
    -
    -		// process interception
    -		if( ORMService.getEventHandling() ){
    -			variables.eventManager.processState( "onCriteriaBuilderAddition", {
    -				"type" = "Count",
    -				"criteriaBuilder" = this
    -			});
    -		}
    -
    -		var results = nativeCriteria.uniqueResult();
    -		// clear count like a ninja, so we can reuse this criteria object.
    -		nativeCriteria.setProjection( javacast("null","") );
    -		nativeCriteria.setResultTransformer( this.ROOT_ENTITY );
    -
    -		// process interception
    -		if( ORMService.getEventHandling() ){
    -			variables.eventManager.processState( "afterCriteriaBuilderCount", {
    -				"criteriaBuilder" = this,
    -				"results" = results
    -			});
    -		}
    -
    -		return results;
    -	}
    -	
    -	/************************************** PRIVATE *********************************************/
    -	
    -	/**
    -	* Get ORM Util
    -	*/
    -	private function getORMUtil() {
    -		return new wirebox.system.orm.hibernate.util.ORMUtilFactory().getORMUtil();
    -	}
    -	
    -}
    diff --git a/src/cfml/system/wirebox/system/orm/hibernate/DetachedCriteriaBuilder.cfc b/src/cfml/system/wirebox/system/orm/hibernate/DetachedCriteriaBuilder.cfc
    deleted file mode 100644
    index 258caffeb..000000000
    --- a/src/cfml/system/wirebox/system/orm/hibernate/DetachedCriteriaBuilder.cfc
    +++ /dev/null
    @@ -1,80 +0,0 @@
    -/**
    -********************************************************************************
    -Copyright Since 2005 ColdBox Framework by Luis Majano and Ortus Solutions, Corp
    -www.coldbox.org | www.luismajano.com | www.ortussolutions.com
    -********************************************************************************
    -
    -Description :
    -	Based on the general approach of CriteriaBuilder.cfc, DetachedCriteriaBuilder allows you 
    -	to create a detached criteria query that can be used:
    -		* in conjuction with critierion.Subqueries to add a programmatically built subquery as a criterion of another criteria query
    -		* as a detachedSQLProjection, which allows you to build a programmatic subquery that is added as a projection to another criteria query	
    -*/
    -import wirebox.system.orm.hibernate.*;
    -component accessors="true" extends="wirebox.system.orm.hibernate.BaseBuilder" {
    -	
    -	/**
    -	* Constructor
    -	*/
    -	DetachedCriteriaBuilder function init( 
    -		required string entityName, 
    -		required string alias,
    -		required any ORMService 
    -	){
    -		// create new DetachedCriteria
    -		var criteria = createObject( "java", "org.hibernate.criterion.DetachedCriteria" ).forEntityName( arguments.entityName, arguments.alias );
    -		
    -		// setup base builder with detached criteria and subqueries
    -		super.init( entityName=arguments.entityName, 
    -					criteria=criteria, 
    -					restrictions=new criterion.Subqueries( criteria ),
    -					ORMService=arguments.ORMService );
    -		
    -		return this;
    -	}
    -	
    -	// pass off arguments to higher-level restriction builder, and handle the results
    -	any function onMissingMethod( required string missingMethodName, required struct missingMethodArguments ) {
    -		// get the restriction/new criteria
    -		var r = createRestriction( argumentCollection=arguments );
    -		// switch on the object type
    -		switch( getMetaData( r ).name ) {
    -			// if a detached criteria builder, just return this so we can keep chaining
    -			case 'wirebox.system.orm.hibernate.DetachedCriteriaBuilder':
    -				break;
    -			// if a subquery, we *need* to return the restrictino itself, or bad things happen
    -			case 'org.hibernate.criterion.PropertySubqueryExpression': 
    -			case 'org.hibernate.criterion.ExistsSubqueryExpression':
    -			case 'org.hibernate.criterion.SimpleSubqueryExpression':
    -				return r;
    -			// otherwise, just a restriction; add it to nativeCriteria, then return this so we can keep chaining
    -			default: 
    -				nativeCriteria.add( r );
    -				// process interception
    -				variables.eventManager.processState( "onCriteriaBuilderAddition", {
    -					"type" = "Subquery Restriction",
    -					"CriteriaBuilder" = this
    -				});
    -				break;
    -		}
    -		return this;
    -	}
    -	
    -	public any function getNativeCriteria() {
    -		var ormsession = variables.ORMService.getORM().getSession();
    -		return variables.nativeCriteria.getExecutableCriteria( ormsession );
    -	}
    -
    -	public any function createDetachedSQLProjection() {
    -		// get the sql with replaced parameters
    -		var sql = SQLHelper.getSql( returnExecutableSql=true );
    -		var alias = SQLHelper.getProjectionAlias();
    -		var uniqueAlias = SQLHelper.generateSQLAlias();
    -			// by default, alias is this_...convert it to the alias provided
    -			sql = replaceNoCase( sql, "this_", SQLHelper.getRootSQLAlias(), 'all' );
    -			// wrap it up and uniquely alias it
    -			sql = "( #sql# ) as " & alias;
    -		// now that we have the sql string, we can create the sqlProjection
    -		return this.PROJECTIONS.sqlProjection( sql, [ alias ], SQLHelper.getProjectedTypes() );
    -	}
    -}
    \ No newline at end of file
    diff --git a/src/cfml/system/wirebox/system/orm/hibernate/VirtualEntityService.cfc b/src/cfml/system/wirebox/system/orm/hibernate/VirtualEntityService.cfc
    deleted file mode 100644
    index 560a52c21..000000000
    --- a/src/cfml/system/wirebox/system/orm/hibernate/VirtualEntityService.cfc
    +++ /dev/null
    @@ -1,240 +0,0 @@
    -/**
    -********************************************************************************
    -Copyright Since 2005 ColdBox Framework by Luis Majano and Ortus Solutions, Corp
    -www.coldbox.org | www.luismajano.com | www.ortussolutions.com
    -********************************************************************************
    -Author      :	Curt Gratz & Luis Majano
    -Description :
    -
    -This is a Virtual Entity Service that extends the Coldbox BaseORMService to
    -provide easy access to creating virtual services that extend the BaseORMService
    -
    -For example, if you want a UserService, you can either create an object based
    -off this object if no additional functionality is needed like this:
    -
    -UserService=CreateObject("component", "wirebox.system.orm.hibernate.VirtualEntityService").init("User");
    -
    -You can also use this virtual service as a template object and extend and override as needed.
    -
    -import wirebox.system.orm.hibernate.*;
    -component extends="VirtualEntityService"
    -UserService function init(){
    -    // setup properties
    -    setEntityName('User');
    -    setQueryCacheRegion( "#arguments.entityName#.defaultVSCache" );
    -    setUseQueryCaching( false );
    -	setEventHandling( false );
    -	setDefaultAsQuery( true );
    -    return this;
    -}
    -
    -*/
    -component extends="wirebox.system.orm.hibernate.BaseORMService" accessors="true"{
    -
    -	/**
    -	* The entityName property for this "version" of the Virtual Service
    -	*/
    -	property name="entityName" type="string";
    -	
    -	/**
    -	* The datasource property for this "version" of the Virtual Service
    -	*/
    -	property name="datasource" type="string";
    -
    -	/************************************** CONSTRUCTOR *********************************************/
    -
    -	VirtualEntityService function init(required string entityname, 
    -										string queryCacheRegion, 
    -										boolean useQueryCaching,
    -										boolean eventHandling,
    -										boolean useTransactions,
    -										boolean defaultAsQuery,
    -										string datasource){
    -		// create cache region
    -		if( !structKeyExists(arguments,"queryCacheRegion") ){
    -			arguments.queryCacheRegion = "#arguments.entityName#.defaultVSCache";
    -		}
    -
    -		// init parent
    -		super.init(argumentCollection=arguments);
    -		
    -		// Set the local entity to be used in this virtual entity service
    -		setEntityName( arguments.entityName );
    -		
    -		// Set the datasource of the local entity to be used in this virtual entity service
    -		// Only if not passed
    -		if( !StructKeyExists(arguments, "datasource") ){
    -			setDatasource( orm.getEntityDatasource( arguments.entityName ) );
    -		}
    -		else{
    -			setDatasource( arguments.datasource );
    -		}
    -		
    -		return this;
    -	}
    -
    -	/************************************** PUBLIC *********************************************/
    -
    -	any function executeQuery(required string query,
    -							   any params=structnew(),
    -							   numeric offset=0,
    -					  		   numeric max=0,
    -					  		   numeric timeout=0,
    -						       boolean ignorecase=false,
    -						       boolean asQuery=getDefaultAsQuery(),
    -						       boolean unique=false){
    -						       	   
    -		arguments.datasource = this.getDatasource();
    -		return super.executeQuery(argumentCollection=arguments);				       	   
    -	}
    -
    -	any function list(struct criteria=structnew(),
    -					  string sortOrder="",
    -					  numeric offset=0,
    -					  numeric max=0,
    -					  numeric timeout=0,
    -					  boolean ignoreCase=false,
    -					  boolean asQuery=getDefaultAsQuery()){
    -
    -		arguments.entityName = this.getEntityName();
    -		var results = super.list(argumentCollection=arguments);
    -		return results;
    -	}
    -
    -	any function findWhere(required struct criteria){
    -		return super.findWhere(this.getEntityName(), arguments.criteria);
    -	}
    -
    -	array function findAllWhere(required struct criteria, string sortOrder=""){
    -		return super.findAllWhere(this.getEntityName(), arguments.criteria, arguments.sortOrder);
    -	}
    -
    -	any function new(struct properties=structnew(), boolean composeRelationships=true, nullEmptyInclude="", nullEmptyExclude="", boolean ignoreEmpty=false, include="", exclude=""){
    -		arguments.entityName = this.getEntityName();
    -		return super.new(argumentCollection=arguments);
    -	}
    -
    -	boolean function exists(required any id) {
    -		arguments.entityName = this.getEntityName();
    -		return super.exists(argumentCollection=arguments);
    -	}
    -
    -	any function get(required any id,boolean returnNew=true) {
    -		arguments.entityName = this.getEntityName();
    -		return super.get(argumentCollection=arguments);
    -	}
    -
    -	array function getAll(any id,string sortOrder="") {
    -		arguments.entityName = this.getEntityName();
    -		return super.getAll(argumentCollection=arguments);
    -	}
    -
    -	numeric function deleteAll(boolean flush=false,boolean transactional=getUseTransactions()){
    -		arguments.entityName = this.getEntityName();
    -		return super.deleteAll(arguments.entityName,arguments.flush);
    -	}
    -	
    -	boolean function deleteByID(required any id, boolean flush=false,boolean transactional=getUseTransactions()){
    -		arguments.entityName = this.getEntityName();
    -		return super.deleteByID(argumentCollection=arguments);
    -	}
    -	
    -	any function deleteByQuery(required string query, any params, numeric max=0, numeric offset=0, boolean flush=false, boolean transactional=getUseTransactions() ){
    -		arguments.datasource = this.getDatasource();
    -		return super.deleteByQuery(argumentCollection=arguments);
    -	}
    -
    -	numeric function deleteWhere(boolean transactional=getUseTransactions()){
    -		arguments.entityName = this.getEntityName();
    -		return super.deleteWhere(argumentCollection=arguments);
    -	}
    -
    -	numeric function count(string where="", any params=structNew()){
    -		arguments.entityName = this.getEntityName();
    -		return super.count(argumentCollection=arguments);
    -	}
    -
    -	numeric function countWhere(){
    -		arguments.entityName = this.getEntityName();
    -		return super.countWhere(argumentCollection=arguments);
    -	}
    -
    -	void function evict(string collectionName, any id){
    -		arguments.entityName = this.getEntityName();
    -		super.evict(argumentCollection=arguments);
    -	}
    -	
    -	any function clear(string datasource=this.getDatasource()){
    -		return super.clear(argumentCollection=arguments);
    -	}
    -	
    -	boolean function isSessionDirty(string datasource=this.getDatasource()){
    -		arguments.datasource = this.getDatasource();
    -		return super.isSessionDirty(argumentCollection=arguments);
    -	}
    -	
    -	struct function getSessionStatistics(string datasource=this.getDatasource()){
    -		arguments.datasource = this.getDatasource();
    -		return super.getSessionStatistics(argumentCollection=arguments);
    -	}
    -
    -	string function getKey(){
    -		return super.getKey( this.getEntityName() );
    -	}
    -
    -	array function getPropertyNames(){
    -		return super.getPropertyNames(this.getEntityName());
    -	}
    -
    -	string function getTableName(){
    -		return super.getTableName(this.getEntityName());
    -	}
    -	
    -	any function criteriaQuery(array criteria=ArrayNew(1),
    -					  		 		  string sortOrder="",
    -					  		 		  numeric offset=0,
    -					  				  numeric max=0,
    -					  		 		  numeric timeout=0,
    -					  		 		  boolean ignoreCase=false,
    -					  		 		  boolean asQuery=getDefaultAsQuery()){
    -		arguments.entityName = this.getEntityName();
    -		return super.criteriaQuery(argumentCollection=arguments);
    -	}
    -	
    -	numeric function criteriaCount(array criteria=ArrayNew(1)){
    -		return super.criteriaCount(this.getEntityName(), arguments.criteria);
    -	}
    -	
    -	any function newCriteria(boolean useQueryCaching=false, string queryCacheRegion=""){
    -		
    -		arguments.entityName = this.getEntityName();
    -		return super.newCriteria(argumentCollection=arguments);
    -	}
    -	
    -	/**
    -	* Coverts an ID, list of ID's, or array of ID's values to the proper java type
    -	* The method returns a coverted array of ID's
    -	*/
    -	any function convertIDValueToJavaType(required id){
    -		arguments.entityName = this.getEntityName();
    -		return super.convertIDValueToJavaType(argumentCollection=arguments);
    -	}
    -	
    -	/**
    -	* Coverts a value to the correct javaType for the property passed in
    -	* The method returns the value in the proper Java Type
    -	*/
    -	any function convertValueToJavaType(required propertyName, required value){
    -		arguments.entityName = this.getEntityName();
    -		return super.convertValueToJavaType(argumentCollection=arguments);
    -	}
    -	
    -	/**
    -	* A nice onMissingMethod template to create awesome dynamic methods based on a virtual service
    -	*/
    -	any function onMissingMethod(string missingMethodName, struct missingMethodArguments){
    -		// Add the entity name
    -		arguments.missingMethodArguments.entityName = this.getEntityName();
    -		return super.onMissingMethod(argumentCollection=arguments);
    -	}
    -}
    \ No newline at end of file
    diff --git a/src/cfml/system/wirebox/system/orm/hibernate/WBEventHandler.cfc b/src/cfml/system/wirebox/system/orm/hibernate/WBEventHandler.cfc
    deleted file mode 100644
    index 9d74bb3ae..000000000
    --- a/src/cfml/system/wirebox/system/orm/hibernate/WBEventHandler.cfc
    +++ /dev/null
    @@ -1,206 +0,0 @@
    -/**
    -********************************************************************************
    -Copyright Since 2005 ColdBox Framework by Luis Majano and Ortus Solutions, Corp
    -www.coldbox.org | www.luismajano.com | www.ortussolutions.com
    -********************************************************************************
    -Description :
    -
    -This class can be used directly or inherited from for more granular control of ORM injections.
    -This bridges Hibernate to WireBox so you can wire up ORM entities in your application. Please also
    -note that there is no way to intercept new() or entityNew() or createObject() calls done via 
    -ColdFusion and there is no preNew interception point exposed by ColdFusion.  So if you want ORM
    -entity injection enabled for new entities, you will have to send them manually into wirebox for wiring like so:
    -
    -wirebox.autowire( entity );
    -
    -All loaded entities will be wired for you during the postLoad() ORM event handler.
    -
    -This event handler will also announce WireBox events according to hibernate events, so you can
    -create WireBox listeners and perform certain actions on entities.  The announced events are:
    -
    -- ORMPreLoad
    -- ORMPostLoad
    -- ORMPreDelete
    -- ORMPostDelete
    -- ORMPreUpdate
    -- ORMPostUpdate
    -- ORMPreInsert
    -- ORMPostInsert
    -- ORMPreSave
    -- ORMPostSave
    -
    -This class requires that WireBox be in application scope in a key called 'wirebox'. You can
    -override this key by using a private variable in your own implementation.
    -
    -To use:
    -1) In your Application.cfc orm settings point it directly to this file
    -   this.ormsettings.eventHandling = true;
    -   this.ormsettings.eventHandler  = "wirebox.system.orm.hibernate.WBEventHandler";
    -   
    -2) Create a CFC that inherits from "wirebox.system.orm.hibernate.WBEventHandler" and place it somewhere in your app.
    -   Add the orm settings in your Application.cfc
    -   this.ormsettings.eventHandling = true;
    -   this.ormsettings.eventHandler  = "model.EventHandler";
    -
    -If you do the latter, you can use some extra functionality by using the following private variables.
    -
    -// The scope key wirebox is located in application scope
    -scopeKey = "wirebox";
    -
    -// Include list of ORM entities to include in the injection, if blank it includes all, which is the default
    -injectorInclude = "";
    -
    -// Exclude list of ORM entities to exclude in the injection, if blank it includes none, which is the default
    -injectorExclude = "";
    -
    -*/
    -component implements="CFIDE.orm.IEventHandler"{
    -	
    -	/**
    -	* The scope key to use
    -	*/
    -	variables.scopeKey = "wirebox";
    -	
    -	/**
    -	* Include list of ORM entities to include in the injection, if blank it includes all, which is the default
    -	*/
    -	variables.injectorInclude = "";
    -	
    -	/**
    -	* Exclude list of ORM entities to exclude in the injection, if blank it includes none, which is the default
    -	*/
    -	variables.injectorExclude = "";
    -	
    -	/**
    -	* postNew called by ColdBox which in turn announces a coldbox interception: ORMPostNew
    -	*/
    -	public void function postNew( entity, entityName ){
    -		var args = { entity = arguments.entity, entityName=arguments.entityName };
    -		processEntityInjection( args.entityName, args.entity );
    -		announceInterception( "ORMPostNew", args );
    -	}
    -	
    -	/**
    -	* preLoad called by hibernate which in turn announces a WireBox interception: ORMPreLoad
    -	*/
    -	public void function preLoad( entity ){
    -		announceInterception( "ORMPreLoad", { entity = arguments.entity } );
    -	}
    -
    -	/**
    -	* postLoad called by hibernate which in turn announces a WireBox interception: ORMPostLoad
    -	*/
    -	public void function postLoad( entity ){
    -		var orm 		= getORMUtil();
    -		var datasource 	= orm.getEntityDatasource( arguments.entity );
    -		
    -		var args = { entity=arguments.entity, entityName=orm.getSession( datasource ).getEntityName( arguments.entity ) };
    -		processEntityInjection(args.entityName, args.entity);
    -		announceInterception( "ORMPostLoad",args);
    -	}
    -
    -	/**
    -	* postDelete called by hibernate which in turn announces a WireBox interception: ORMPostDelete
    -	*/
    -	public void function postDelete( entity ){
    -		announceInterception( "ORMPostDelete", {entity=arguments.entity});
    -	}
    -
    -	/**
    -	* preDelete called by hibernate which in turn announces a WireBox interception: ORMPreDelete
    -	*/
    -	public void function preDelete( entity ) {
    -		announceInterception( "ORMPreDelete", {entity=arguments.entity});
    -	}
    -
    -	/**
    -	* preUpdate called by hibernate which in turn announces a WireBox interception: ORMPreUpdate
    -	*/
    -	public void function preUpdate( entity, struct oldData=structNew()){
    -		announceInterception( "ORMPreUpdate", {entity=arguments.entity, oldData=arguments.oldData});
    -	}
    -
    -	/**
    -	* postUpdate called by hibernate which in turn announces a WireBox interception: ORMPostUpdate
    -	*/
    -	public void function postUpdate( entity ){
    -		announceInterception( "ORMPostUpdate", {entity=arguments.entity});
    -	}
    -
    -	/**
    -	* preInsert called by hibernate which in turn announces a WireBox interception: ORMPreInsert
    -	*/
    -	public void function preInsert( entity ){
    -		announceInterception( "ORMPreInsert", {entity=arguments.entity});
    -	}
    -
    -	/**
    -	* postInsert called by hibernate which in turn announces a WireBox interception: ORMPostInsert
    -	*/
    -	public void function postInsert( entity ){
    -		announceInterception( "ORMPostInsert", {entity=arguments.entity});
    -	}
    -
    -	/**
    -	* preSave called by WireBox Base service before save() calls
    -	*/
    -	public void function preSave( entity ){
    -		announceInterception( "ORMPreSave", {entity=arguments.entity});
    -	}
    -
    -	/**
    -	* postSave called by WireBox Base service after transaction commit or rollback via the save() method
    -	*/
    -	public void function postSave( entity ){
    -		announceInterception( "ORMPostSave", {entity=arguments.entity});
    -	}
    -
    -	/**
    -	* Process a wirebox event
    -	*/
    -	public function announceInterception( required string state, data=structNew() ){
    -		// announce event
    -		getWireBox().getEventManager().processState( arguments.state, arguments.data );
    -	}
    -
    -	/**
    -	* Get the system Event Manager
    -	*/
    -	public function getEventManager(){
    -		return getWireBox().getEventManager();
    -	}
    -	
    -	/************************************** PRIVATE *********************************************/
    -	
    -	/**
    -	* Get a reference to WireBox
    -	*/
    -	private function getWireBox(){
    -		return application[ scopeKey ];
    -	}
    -	
    -	/**
    -	* Process entity injection
    -	*/
    -	private function processEntityInjection(required entityName,required entity){
    -		
    -		// Include,Exclude?
    -		if( (len(injectorInclude) AND listContainsNoCase(injectorInclude,entityName))
    -		    OR
    -			(len(injectorExclude) AND NOT listContainsNoCase(injectorExclude,entityName))
    -			OR 
    -			(NOT len(injectorInclude) AND NOT len(injectorExclude) ) ){
    -			
    -			// Process DI
    -			getWireBox().autowire(target=entity,targetID="ORMEntity-#entityName#");
    -		}	
    -	}
    -	
    -	/**
    -	* Get ORM Util
    -	*/
    -	private function getORMUtil() {
    -		return new wirebox.system.orm.hibernate.util.ORMUtilFactory().getORMUtil();
    -	}
    -
    -}
    \ No newline at end of file
    diff --git a/src/cfml/system/wirebox/system/orm/hibernate/criterion/Restrictions.cfc b/src/cfml/system/wirebox/system/orm/hibernate/criterion/Restrictions.cfc
    deleted file mode 100644
    index e2087beab..000000000
    --- a/src/cfml/system/wirebox/system/orm/hibernate/criterion/Restrictions.cfc
    +++ /dev/null
    @@ -1,266 +0,0 @@
    -/**
    -********************************************************************************
    -Copyright Since 2005 ColdBox Framework by Luis Majano and Ortus Solutions, Corp
    -www.coldbox.org | www.luismajano.com | www.ortussolutions.com
    -********************************************************************************
    -
    -Author     :	Michael McKellip , Luis Majano
    -Description :
    -	A proxy to hibernate org.hibernate.criterion.Restrictions object to allow
    -	for criteria based querying
    -*/
    -component singleton{
    -	
    -	// Constructor
    -	Restrictions function init(){		
    -		restrictions = CreateObject("java","org.hibernate.criterion.Restrictions");
    -		return this;
    -	}
    -	
    -	// Get the native hibernate restrictions object: org.hibernate.criterion.Restrictions
    -	any function getNativeClass(){
    -		return restrictions;
    -	}
    -	
    -	// Where the property value is between two distinct values
    -	any function between(required string property, required any minValue, required any maxValue){
    -		return restrictions.between(arguments.property, arguments.minValue, arguments.maxValue);
    -	}
    -	
    -	// Where a property equals a particular value, you can also use eq()
    -	any function isEq(required string property, required any propertyValue){
    -		return restrictions.eq(arguments.property, arguments.propertyValue);
    -	}
    -	
    -	// Where a property is true
    -	any function isTrue(required string property){
    -		return restrictions.eq(arguments.property, javaCast("boolean",true) );
    -	}
    -	
    -	// Where a property is false
    -	any function isFalse(required string property){
    -		return restrictions.eq(arguments.property, javaCast("boolean",false) );
    -	}
    -	
    -	// Where one property must equal another
    -	any function eqProperty(required string property, required string otherProperty){
    -		return restrictions.eqProperty(arguments.property, arguments.otherProperty);
    -	}
    -	
    -	// Where a property is greater than a particular value, you can also use gt()
    -	any function isGt(required string property, required any propertyValue){
    -		return restrictions.gt(arguments.property, arguments.propertyValue);
    -	}
    -	
    -	// Where a one property must be greater than another
    -	any function gtProperty(required string property, required string otherProperty){
    -		return restrictions.gtProperty(arguments.property, arguments.otherProperty);
    -	}
    -	
    -	// Where a property is greater than or equal to a particular value, you can also use ge()
    -	any function isGe(required string property, required any propertyValue){
    -		return restrictions.ge(arguments.property, arguments.propertyValue);
    -	}
    -	
    -	// Where a one property must be greater than or equal to another
    -	any function geProperty(required string property, required string otherProperty){
    -		return restrictions.geProperty(arguments.property, arguments.otherProperty);
    -	}
    -	
    -	// Where an objects id equals the specified value
    -	any function idEQ(required any propertyValue){
    -		return restrictions.idEQ(arguments.propertyValue);
    -	}
    -	
    -	// A case-insensitive 'like' expression
    -	any function ilike(required string property, required string propertyValue){
    -		return restrictions.ilike(arguments.property, arguments.propertyValue);
    -	}
    -	
    -	// Where a property is contained within the specified list of values, the property value can be a collection (struct) or array or list, you can also use in()
    -	any function isIn(required string property, required any propertyValue){
    -		// infalte to array if simple values
    -		if( isSimpleValue(arguments.propertyValue) ){ arguments.propertyValue = listToArray( arguments.propertyValue); } 
    -		return restrictions.in(arguments.property, arguments.propertyValue);
    -	}
    -	
    -	// Where a collection property is empty
    -	any function isEmpty(required string property){
    -		return restrictions.isEmpty(arguments.property);
    -	}
    -	
    -	// Where a collection property is not empty
    -	any function isNotEmpty(required string property){
    -		return restrictions.isNotEmpty(arguments.property);
    -	}
    -	
    -	// Where a property is null
    -	any function isNull(required string property){
    -		return restrictions.isNull(arguments.property);
    -	}
    -	
    -	// Where a property is not null
    -	any function isNotNull(required string property){
    -		return restrictions.isNotNull(arguments.property);
    -	}
    -	
    -	// Where a property is less than a particular value, you can also use lt()
    -	any function islt(required string property, required any propertyValue){
    -		return restrictions.lt(arguments.property, arguments.propertyValue);
    -	}
    -	
    -	// Where a one property must be less than another
    -	any function ltProperty(required string property, required string otherProperty){
    -		return restrictions.ltProperty(arguments.property, arguments.otherProperty);
    -	}
    -	
    -	// Where a property is less than or equal a particular value, you can also use le()
    -	any function isle(required string property, required any propertyValue){
    -		return restrictions.le(arguments.property, arguments.propertyValue);
    -	}
    -	
    -	// Where a one property must be less than or equal to another
    -	any function leProperty(required string property, required string otherProperty){
    -		return restrictions.leProperty(arguments.property, arguments.otherProperty);
    -	}
    -	
    -	// Equivalent to SQL like expression
    -	any function like(required string property, required string propertyValue){
    -		return restrictions.like(arguments.property, arguments.propertyValue);
    -	}
    -	
    -	// Where a property does not equal a particular value
    -	any function ne(required string property, required any propertyValue){
    -		return restrictions.ne(arguments.property, arguments.propertyValue);
    -	}
    -	
    -	// Where one property does not equal another
    -	any function neProperty(required string property, required any otherProperty){
    -		return restrictions.neProperty(arguments.property, arguments.otherProperty);
    -	}
    -	
    -	// Where a collection property's size equals a particular value
    -	any function sizeEq(required string property, required any propertyValue){
    -		return restrictions.sizeEq(arguments.property, arguments.propertyValue);
    -	}
    -	
    -	// Where a collection property's size is greater than a particular value
    -	any function sizeGT(required string property, required any propertyValue){
    -		return restrictions.sizeGT(arguments.property, arguments.propertyValue);
    -	}
    -	
    -	// Where a collection property's size is greater than or equal a particular value
    -	any function sizeGE(required string property, required any propertyValue){
    -		return restrictions.sizeGE(arguments.property, arguments.propertyValue);
    -	}
    -	
    -	// Where a collection property's size is less than a particular value
    -	any function sizeLT(required string property, required any propertyValue){
    -		return restrictions.sizeLT(arguments.property, arguments.propertyValue);
    -	}
    -	
    -	// Where a collection property's size is less than or equal a particular value
    -	any function sizeLE(required string property, required any propertyValue){
    -		return restrictions.sizeLE(arguments.property, arguments.propertyValue);
    -	}
    -	
    -	// Where a collection property's size is not equal to a particular value
    -	any function sizeNE(required string property, required any propertyValue){
    -		return restrictions.sizeNE(arguments.property, arguments.propertyValue);
    -	}
    -	
    -	// Use arbitrary SQL to modify the resultset
    -	any function sqlRestriction(required string sql){
    -		return restrictions.sqlRestriction(arguments.sql);
    -	}
    -	
    -	// Group expressions together in a single conjunction (A and B and C...) and return the conjunction
    -	any function conjunction(required array restrictionValues){
    -		var cj = restrictions.conjunction();
    -		
    -		for(var i=1; i LTE ArrayLen(arguments.restrictionValues); i++){
    -			cj.add( arguments.restrictionValues[i] );
    -		}
    -		
    -		return cj;
    -	}
    -	
    -	// Return the conjuction of N expressions as arguments
    -	any function $and(){
    -		var expressions = [];
    -		for(var key in arguments){
    -			arrayAppend(expressions, arguments[key]);
    -		}
    -		return this.conjunction(expressions);
    -	}
    -	
    -	// Return the disjunction of N expressions as arguments
    -	any function $or(){
    -		var expressions = [];
    -		for(var key in arguments){
    -			arrayAppend(expressions, arguments[key]);
    -		}
    -		return this.disjunction(expressions);
    -	}
    -	
    -	// Group expressions together in a single disjunction (A or B or C...)
    -	any function disjunction(required array restrictionValues){
    -		var dj = restrictions.disjunction();
    -		
    -		for(var i=1; i LTE ArrayLen(arguments.restrictionValues); i++){
    -			dj.add( arguments.restrictionValues[i] );
    -		}
    -		
    -		return dj;
    -	}
    -	
    -	// Return the negation of an expression
    -	any function isNot(required any criterion){
    -		return restrictions.not(arguments.criterion);
    -	}
    -	
    -	any function onMissingMethod(required string missingMethodName, required struct missingMethodArguments){
    -		// build args to array
    - 		var args = [];
    - 		for(var i = 1; i <= structCount(arguments.missingMethodArguments); i++){
    - 			ArrayAppend(args, "arguments.missingMethodArguments[#i#]");
    - 		}
    -				
    -		switch(arguments.missingMethodName){
    -			case "eq":
    -				return isEq(argumentCollection=arguments.missingMethodArguments);
    -				break;
    -			case "in":
    -				return isIn(argumentCollection=arguments.missingMethodArguments);
    -				break;
    -			case "gt":
    -				return isGt(argumentCollection=arguments.missingMethodArguments);
    -				break;
    -			case "lt":
    -				return isLT(argumentCollection=arguments.missingMethodArguments);
    -				break;
    -			case "le":
    -				return isLE(argumentCollection=arguments.missingMethodArguments);
    -				break;
    -			case "ge":
    -				return isGe(argumentCollection=arguments.missingMethodArguments);
    -				break;
    -			case "and":
    -				return $and(argumentCollection=arguments.missingMethodArguments);
    -				break;
    -			case "or":
    -				return $or(argumentCollection=arguments.missingMethodArguments);
    -				break;
    -			case "not":
    -				return isNot(argumentCollection=arguments.missingMethodArguments);
    -				break;
    -			default:{
    -				if( arrayLen(args) ){
    -					return evaluate("restrictions.#arguments.missingMethodName#(#arrayToList(args)#)");
    -				}
    -				return evaluate("restrictions.#arguments.missingMethodName#()");
    -			}
    -		}
    -	
    -	}
    -}
    diff --git a/src/cfml/system/wirebox/system/orm/hibernate/criterion/Subqueries.cfc b/src/cfml/system/wirebox/system/orm/hibernate/criterion/Subqueries.cfc
    deleted file mode 100644
    index 690e7211c..000000000
    --- a/src/cfml/system/wirebox/system/orm/hibernate/criterion/Subqueries.cfc
    +++ /dev/null
    @@ -1,134 +0,0 @@
    -/**
    -********************************************************************************
    -Copyright Since 2005 ColdBox Framework by Luis Majano and Ortus Solutions, Corp
    -www.coldbox.org | www.luismajano.com | www.ortussolutions.com
    -********************************************************************************
    -
    -Description :
    -	A proxy to hibernate org.hibernate.criterion.Subqueries object to allow
    -	for criteria based subquerying
    -*/
    -component singleton extends="wirebox.system.orm.hibernate.criterion.Restrictions"{
    -	
    -	// Constructor
    -	Subqueries function init( required criteria ) {
    -		detachedCriteria = arguments.criteria;
    -		subqueries   = CreateObject( "java", "org.hibernate.criterion.Subqueries" );  
    -		restrictions = CreateObject( "java", "org.hibernate.criterion.Restrictions" );
    -		return this;
    -	}
    -	// Get the native hibernate subqueries object: org.hibernate.criterion.Subqueries
    -	any function getNativeClass(){
    -		return subqueries;
    -	}
    -	any function subEq( required any value ) {
    -		return subqueries.eq( arguments.value, detachedCriteria );
    -	}
    -	any function subEqAll( required any value ) {
    -		return subqueries.eqAll( arguments.value, detachedCriteria );
    -	}
    -	any function subGe( required any value ) {
    -		return subqueries.ge( arguments.value, detachedCriteria );
    -	}
    -	any function subGeAll( required any value ) {
    -		return subqueries.geAll( arguments.value, detachedCriteria );
    -	}
    -	any function subGeSome( required any value ) {
    -		return subqueries.geSome( arguments.value, detachedCriteria );
    -	}
    -	any function subGt( required any value ) {
    -		return subqueries.gt( arguments.value, detachedCriteria );
    -	}
    -	any function subGtAll( required any value ) {
    -		return subqueries.gtAll( arguments.value, detachedCriteria );
    -	}
    -	any function subGtSome( required any value ) {
    -		return subqueries.gtSome( arguments.value, detachedCriteria );
    -	}
    -	any function subIn( required any value ) {
    -		return subqueries.in( arguments.value, detachedCriteria );
    -	}
    -	any function subLe( required any value ) {
    -		return subqueries.le( arguments.value, detachedCriteria );
    -	}
    -	any function subLeAll( required any value ) {
    -		return subqueries.leAll( arguments.value, detachedCriteria );
    -	}
    -	any function subLeSome( required any value ) {
    -		return subqueries.leSome( arguments.value, detachedCriteria );
    -	}
    -	any function subLt( required any value ) {
    -		return subqueries.lt( arguments.value, detachedCriteria );
    -	}
    -	any function subLtAll( required any value ) {
    -		return subqueries.ltAll( arguments.value, detachedCriteria );
    -	}
    -	any function subLtSome( required any value ) {
    -		return subqueries.ltSome( arguments.value, detachedCriteria );
    -	}
    -	any function subNe( required any value ) {
    -		return subqueries.ne( arguments.value, detachedCriteria );
    -	}
    -	any function subNotIn( required any value ) {
    -		return subqueries.notIn( arguments.value, detachedCriteria );
    -	}
    -	// where subquery returns a result
    -	any function exists() {
    -		return subqueries.exists( detachedCriteria );
    -	}
    -	// where subquery returns no result
    -	any function notExists() {
    -		return subqueries.notExists( detachedCriteria );
    -	}
    -	any function propertyEq( required string property ){
    -		return subqueries.propertyEq( arguments.property, detachedCriteria );
    -	}
    -	any function propertyEqAll( required string property ){
    -		return subqueries.propertyEqAll( arguments.property, detachedCriteria );
    -	}
    -	any function propertyGe( required string property ){
    -		return subqueries.propertyGe( arguments.property, detachedCriteria );
    -	}
    -	any function propertyGeAll( required string property ){
    -		return subqueries.propertyGeAll( arguments.property, detachedCriteria );
    -	}
    -	any function propertyGeSome( required string property ){
    -		return subqueries.propertyGeSome( arguments.property, detachedCriteria );
    -	}
    -	any function propertyGt( required string property ){
    -		return subqueries.propertyGt( arguments.property, detachedCriteria );
    -	}
    -	any function propertyGtAll( required string property ){
    -		return subqueries.propertyGtAll( arguments.property, detachedCriteria );
    -	}
    -	any function propertyGtSome( required string property ){
    -		return subqueries.propertyGtSome( arguments.property, detachedCriteria );
    -	}
    -	any function propertyIn( required string property ){
    -		return subqueries.propertyIn( arguments.property, detachedCriteria );
    -	}
    -	any function propertyLe( required string property ){
    -		return subqueries.propertyLe( arguments.property, detachedCriteria );
    -	}
    -	any function propertyLeAll( required string property ){
    -		return subqueries.propertyLeAll( arguments.property, detachedCriteria );
    -	}
    -	any function propertyLeSome( required string property ){
    -		return subqueries.propertyLeSome( arguments.property, detachedCriteria );
    -	}
    -	any function propertyLt( required string property ){
    -		return subqueries.propertyLt( arguments.property, detachedCriteria );
    -	}
    -	any function propertyLtAll( required string property ){
    -		return subqueries.propertyLtAll( arguments.property, detachedCriteria );
    -	}
    -	any function propertyLtSome( required string property ){
    -		return subqueries.propertyLtSome( arguments.property, detachedCriteria );
    -	}
    -	any function propertyNe( required string property ){
    -		return subqueries.propertyNe( arguments.property, detachedCriteria );
    -	}
    -	any function propertyNotIn( required string property ){
    -		return subqueries.propertyNotIn( arguments.property, detachedCriteria );
    -	}
    -}
    \ No newline at end of file
    diff --git a/src/cfml/system/wirebox/system/orm/hibernate/sql/SQLHelper.cfc b/src/cfml/system/wirebox/system/orm/hibernate/sql/SQLHelper.cfc
    deleted file mode 100644
    index 92a20aa6b..000000000
    --- a/src/cfml/system/wirebox/system/orm/hibernate/sql/SQLHelper.cfc
    +++ /dev/null
    @@ -1,427 +0,0 @@
    -/**
    -********************************************************************************
    -Copyright Since 2005 ColdBox Framework by Luis Majano and Ortus Solutions, Corp
    -www.coldbox.org | www.luismajano.com | www.ortussolutions.com
    -********************************************************************************
    -
    -Description :
    -    Simple utility for extracting SQL from native Criteria Query object
    -*/
    -import org.hibernate.*;
    -component displayName="SQLHelper" accessors="true" {
    -
    -    /**
    -    * The log array
    -    */
    -    property name="log"                 type="array";
    -    /**
    -    * Format the SQL or not.
    -    */
    -    property name="formatSql"           type="boolean"  default="false";
    -    /**
    -    * Bit to return the executable SQL or not
    -    */
    -    property name="returnExecutableSql" type="boolean"  default="false";
    -
    -    /**
    -    * Constructor
    -    */
    -    SQLHelper function init( 
    -        required any criteriaBuilder, 
    -        boolean returnExecutableSql = false, 
    -        boolean formatSql = false  
    -    ){
    -
    -        // Setup properties
    -        variables.cb            = arguments.criteriaBuilder;
    -        variables.entityName    = cb.getEntityName();
    -        variables.criteriaImpl  = cb.getNativeCriteria();
    -        variables.ormSession    = criteriaImpl.getSession();
    -        variables.factory       = ormSession.getFactory();
    -        // get formatter for sql string beautification
    -        variables.formatter     = createObject( "java", "org.hibernate.jdbc.util.BasicFormatterImpl" );
    -        // set properties
    -        variables.log           = [];
    -        variables.formatSQL     = arguments.formatSQL;
    -        variables.returnExecutableSql = arguments.returnExecutableSql;
    -
    -        return this;
    -    }
    -
    -    /**
    -     * Logs current state of criteria to internal tracking log
    -     * @label {string} The label for the log record
    -     * return void
    -     */
    -    function log( required string label="Criteria" ) {
    -        var logentry = {
    -            "type" = arguments.label,
    -            "sql"  = getSQL( argumentCollection=arguments )
    -        };
    -        arrayAppend( variables.log, logentry );
    -
    -        return this;
    -    }
    -
    -    /**
    -     * Returns the SQL string that will be prepared for the criteria object at the time of request
    -     * @returnExecutableSql {Boolean} Whether or not to do query param replacements on returned SQL string
    -     * @formatSql {Boolean} Whether to format the sql
    -     * return string
    -     */
    -    string function getSQL( 
    -        required boolean returnExecutableSql=getReturnExecutableSql(), 
    -        required boolean formatSql=getFormatSql() 
    -    ){
    -
    -        var sql = getCriteriaJoinWalker().getSQLstring();
    -        var selection = getQueryParameters().getRowSelection();
    -        var useLimit = useLimit( selection );
    -        var hasFirstRow = getFirstRow( selection ) > 0;
    -        var useOffset = hasFirstRow && useLimit && getDialect().supportsLimitOffset();
    -       
    -        // try to add limit/offset in
    -        if( useLimit ) {
    -            sql = getDialect().getLimitstring( 
    -                sql, 
    -                useOffset ? getFirstRow(selection) : 0,
    -                getMaxOrLimit( selection )
    -            );
    -        }
    -
    -        // if we want executable sql string...
    -        if( arguments.returnExecutableSql ) {
    -            sql = replaceQueryParameters( sql, arguments.formatSql );
    -        }
    -        
    -        // if we want to beautify the sql string
    -        if( arguments.formatSql ) {
    -            sql = applyFormatting( sql );
    -        }
    -        
    -        return sql;
    -    }
    -
    -    /**
    -     * Applies pretty formatting to a sql string
    -     * @sql {string} The SQL string to format
    -     * return string
    -     */
    -    string function applyFormatting( required string sql ) {
    -        return "
    " & formatter.format( arguments.sql ) & "
    "; - } - - /** - * Gets the positional SQL parameter values from the criteria query - * return array - */ - array function getPositionalSQLParameterValues() { - return getCriteriaQueryTranslator().getQueryParameters().getPositionalParameterValues(); - } - - /** - * Gets positional SQL parameter types from the criteria query - * @simple {Boolean} Whether to return a simply array or full objects - * return any - */ - any function getPositionalSQLParameterTypes( required Boolean simple=true ) { - var types = getCriteriaQueryTranslator().getQueryParameters().getPositionalParameterTypes(); - if( !arguments.simple ) { - return types; - } - var simplifiedTypes = []; - for( var x=1; x <= arrayLen( types ); x++ ) { - arrayAppend( simplifiedTypes, types[ x ].getName() ); - } - return simplifiedTypes; - } - - /** - * Returns a formatted array of parameter value and types - * return array - */ - public Array function getPositionalSQLParameters() { - var params = []; - var values = getPositionalSQLParameterValues(); - var types = getPositionalSQLParameterTypes( true ); - // loop over them - for( var x=1; x <= arrayLen( types ); x++ ) { - arrayAppend( params, { - "type" = types [ x ], - "value" = values[ x ] - }); - } - return params; - } - - /** - * Generates a unique SQL Alias within the criteria query - * return string - */ - string function generateSQLAlias() { - return getCriteriaQueryTranslator().generateSQLAlias(); - } - - /** - * Retrieves the "rooted" SQL alias for the criteria query - * return string - */ - string function getRootSQLAlias() { - return getCriteriaQueryTranslator().getRootSQLAlias(); - } - - /** - * Retrieves the projected types of the criteria query - * return string - */ - any function getProjectedTypes() { - return getCriteriaQueryTranslator().getProjectedTypes(); - } - - /** - * Get the alias of the current projection - * return string - */ - string function getProjectionAlias() { - return getCriteriaQueryTranslator().getProjectedAliases()[ 1 ]; - } - - /** - * Retrieves the correct dialect of the database engine - * return any - */ - any function getDialect() { - return factory.getDialect(); - } - - Boolean function canLogLimitOffset() { - var dialect = getDialect(); - var max = !isNull( criteriaImpl.getMaxResults() ) ? criteriaImpl.getMaxResults() : 0; - return dialect.supportsLimitOffset() && max > 0; - } - - /********************************* PRIVATE *********************************/ - - /** - * Small utility method to convert weird arrays from Java methods into something CF understands - * @array {Array} The array to convert - * return Array - */ - private array function convertToCFArray( required any array ) { - var newArray = []; - newArray.addAll( createObject( "java", "java.util.Arrays" ).asList( arguments.array ) ); - return newArray; - } - - /** - * Gets currently applied query parameters for the query object - * return org.hibernate.engine.QueryParameters - */ - private any function getQueryParameters() { - var translator = getCriteriaQueryTranslator(); - return translator.getQueryParameters(); - } - - /** - * replace query parameter placeholders with their actual values (for detachedSQLProjection) - * @sql (string) The sql string to massage - * returns string - */ - private string function replaceQueryParameters( required string sql ) { - var dialect = getDialect(); - var parameters = getQueryParameters(); - // get parameter values and types - var values = parameters.getPositionalParameterValues(); - var types = parameters.getPositionalParameterTypes(); - // get query so we can see full number of ordinal parameters - var query = ormsession.createSQLQuery( sql ); - var meta = query.getParameterMetaData(); - var positionalParameterCount = meta.getOrdinalParameterCount(); - // get row selection - var selection = parameters.getRowSelection(); - // prepare some meta about the limit info...need to handle this separately - var useLimit = useLimit( selection ); - var firstRow = dialect.convertToFirstRowValue( getFirstRow( selection ) ); - var hasFirstRow = dialect.supportsLimitOffset() && ( firstRow > 0 || dialect.forceLimitUsage() ); - var useOffset = hasFirstRow && useLimit && dialect.supportsLimitOffset(); - var reverse = dialect.bindLimitParametersInReverseOrder(); - /** - APPROACH: - Unfortunately, there does not seem to be any really good way to retrieve the SQL that will be executed, - since it isn't actually sent to the db engine as executable SQL - So, we have to rely upon the QueryTranslator to provide us details about positional paramters that are going to be sent - However, the "limit/offset" data isn't handled by the Translator, so we also need to spin up a regular SQL Query to determine - how many total ordinal parameters are getting sent with the query string. - - This, combined with info that Hibernate knows about each db dialect, we can smartly fill in the gaps for the "limit/offset" - information, as well as fill in the ordinal parameters values and return a SQL string that is as close to the actual string - that will be executed on the db as possible. - - So the actual idea is to take the ordinal parameter values and types which QueryTranslator knows about, and intelligently add to - those lists based on the dialect of the database engine. - */ - // if we have positional parameters - if( positionalParameterCount ) { - var positionalValues = convertToCFArray( values ); - var positionalTypes = convertToCFArray( types ); - // if our query at this point in time is using "limit/offset" - if( useLimit ) { - // we'll reuse this - var integerType = createObject( "java", "org.hibernate.type.IntegerType" ); - // Ex: Engines like SQL Server put limits first - if( dialect.bindLimitParametersFirst() ) { - positionalValues = bindLimitParameters( positionalValues, false, selection ); - // add for max/limit - arrayInsertAt( positionalTypes, 1, integerType ); - if( hasFirstRow ) { - arrayInsertAt( positionalTypes, 1, integerType ); - } - } - // Ex: Engines like MySQL put limits last - else { - positionalValues = bindLimitParameters( positionalValues, true, selection ); - // append for max/limit - arrayAppend( positionalTypes, integerType ); - if( hasFirstRow ) { - arrayAppend( positionalTypes, integerType ); - } - } - } - // loop over parameters; need to replace those pesky "?" with the real values - for( var x=1; x<=arrayLen( positionalTypes ); x++ ) { - var type = positionalTypes[ x ]; - var value = positionalValues[ x ]; - // cast values to appropriate SQL type - if( !type.isAssociationType() && type.getName() != "text" ) { - var pvTyped = type.objectToSQLstring( value, getDialect() ); - // remove parameter placeholders - arguments.sql = reReplaceNoCase( arguments.sql, "\?", pvTyped, "one" ); - } - else if( type.getName() == "text" ) { - // remove parameter placeholders - arguments.sql = reReplaceNoCase( arguments.sql, "\?", "'#value#'", "one" ); - } - // association values can't be cast to SQL string by normal convention; just do a simple replace - else { - arguments.sql = reReplaceNoCase( arguments.sql, "\?", value, "one" ); - } - } - // for some reason, JoinWalker doesn't sync up root paramters with the generated alias...so fix those - arguments.sql = reReplaceNoCase( arguments.sql, "this\.", "this_.", "all" ); - } - return arguments.sql; - } - - /** - * Inserts parameter values into the running list based on the dialect of the database engine - * @positionalValues {Array} The positional values for this query - * @append {Boolean} Whether values are appended or prepended to the array - * @selection {any} The current row selection - * return Array - */ - private Array function bindLimitParameters( required Array positionalValues, required Boolean append, required any selection ) { - var dialect = getDialect(); - // trackers - var newPositionalValues = []; - var finalArray = []; - // prepare some meta about the limit info - var firstRow = dialect.convertToFirstRowValue( getFirstRow( selection ) ); - var lastRow = getMaxOrLimit( selection ); - var hasFirstRow = dialect.supportsLimitOffset() && ( firstRow > 0 || dialect.forceLimitUsage() ); - var reverse = dialect.bindLimitParametersInReverseOrder(); - // has offset...need to add both limit and offset - if ( hasFirstRow ) { - // if offset/limit are reversed - // EX: Other engines "reverse" this and use: LIMIT {limit}, {offset} - if( reverse ) { - arrayAppend( newPositionalValues, selection.getMaxRows() ); - arrayAppend( newPositionalValues, firstRow ); - } - // EX: In MySQL, offset limit are: LIMIT {offset}, {limit} - else { - arrayAppend( newPositionalValues, firstRow ); - arrayAppend( newPositionalValues, selection.getMaxRows() ); - } - } - // no start row...just add regular limit - else { - arrayAppend( newPositionalValues, selection.getMaxRows() ); - } - // APPEND: Engines like MySQL, etc. put limit/offset at the end of the statement - if( append ) { - positionalValues.addAll( newPositionalValues ); - return positionalValues; - } - // PREPEND:Engines like SQL Server, etc. use top/row numbering - else { - newPositionalValues.addAll( positionalValues ); - return newPositionalValues; - } - } - - /** - * Determines whether the database engine allows for the use of "limit/offset" syntax - * @selection {any} The current row selection - * return Boolean - */ - private Boolean function useLimit( required any selection ) { - return getDialect().supportsLimit() && hasMaxRows( argumentCollection=arguments ); - } - - /** - * Determines whether the current row selection has a limit already applied - * @selection {any} The current row selection - * return Boolean - */ - private Boolean function hasMaxRows( required any selection ) { - return !isNull( selection.getMaxRows() ); - } - - /** - * Gets the first row (or 0) for the current row selection - * @selection {any} The current row selection - * return Numeric - */ - private Numeric function getFirstRow( required any selection ) { - return isNull( selection.getFirstRow() ) ? 0 : selection.getFirstRow().intValue(); - } - - /** - * Gets correct "limit" value for the current row selection - * @selection {any} The current row selection - * return Numeric - */ - private Numeric function getMaxOrLimit( required any selection ) { - var dialect = getDialect(); - var firstRow = dialect.convertToFirstRowValue( getFirstRow( selection ) ); - var lastRow = selection.getMaxRows().intValue(); - return dialect.useMaxForLimit() ? lastRow+firstRow : lastRow; - } - - /** gets an instance of CriteriaJoinWalker, which can allow for translating criteria query into a sql string - * returns CriteriaJoinWalker - */ - private any function getCriteriaJoinWalker() { - // not nearly as cool as the walking dead kind, but is still handy for turning a criteria into a sql string ;) - return createObject( "java", "org.hibernate.loader.criteria.CriteriaJoinWalker" ).init( - factory.getEntityPersister( entityName ), // persister (loadable) - getCriteriaQueryTranslator(), // translator - factory, // factory - criteriaImpl, // criteria - entityName, // rootEntityName - ormSession.getLoadQueryInfluencers() // loadQueryInfluencers - ); - } - /** gets an instance of CriteriaQueryTranslator, which can prepares criteria query for conversion to SQL - * returns CriteriaQueryTranslator - */ - private any function getCriteriaQueryTranslator() { - // create new criteria query translator; we'll use this to build up the query string - return createObject( "java", "org.hibernate.loader.criteria.CriteriaQueryTranslator" ).init( - factory, // factory - criteriaImpl, // criteria - entityName, // rootEntityName - criteriaImpl.getAlias() // rootSQLAlias - ); - } -} \ No newline at end of file diff --git a/src/cfml/system/wirebox/system/orm/hibernate/util/CFORMUtil.cfc b/src/cfml/system/wirebox/system/orm/hibernate/util/CFORMUtil.cfc deleted file mode 100644 index 8d67202dc..000000000 --- a/src/cfml/system/wirebox/system/orm/hibernate/util/CFORMUtil.cfc +++ /dev/null @@ -1,97 +0,0 @@ -/** -******************************************************************************** -Copyright Since 2005 ColdBox Framework by Luis Majano and Ortus Solutions, Corp -www.coldbox.org | www.luismajano.com | www.ortussolutions.com -******************************************************************************** -Author : Luis Majano & Mike McKellip -Description : - -This implementation supports multiple DSNs for ORM a-la Adobe ColdFusion 9 - ------------------------------------------------------------------------> -*/ -component implements="wirebox.system.orm.hibernate.util.IORMUtil"{ - - public void function flush(string datasource) { - if(StructKeyExists(arguments,"datasource")) - ORMFlush(arguments.datasource); - else - ORMFlush(); - } - - public any function getSession(string datasource) { - if(StructKeyExists(arguments,"datasource")) - // get actual session from coldfusion.orm.hibernate.SessionWrapper - return ORMGetSession(arguments.datasource).getActualSession(); - else - // get actual session from coldfusion.orm.hibernate.SessionWrapper - return ORMGetSession().getActualSession(); - } - - public any function getSessionFactory(string datasource) { - if(StructKeyExists(arguments,"datasource")) - return ORMGetSessionFactory(arguments.datasource); - else - return ORMGetSessionFactory(); - } - - public void function clearSession(string datasource) { - if(StructKeyExists(arguments,"datasource")) - ORMClearSession(arguments.datasource); - else - ORMClearSession(); - } - - public void function closeSession(string datasource) { - if(StructKeyExists(arguments,"datasource")) - ORMCloseSession(arguments.datasource); - else - ORMCloseSession(); - } - - public void function evictQueries(string cachename, string datasource) { - if(StructKeyExists(arguments,"cachename") AND StructKeyExists(arguments,"datasource")) - ORMEvictQueries(arguments.cachename, arguments.datasource); - else if(StructKeyExists(arguments,"cachename")) - ORMEvictQueries(arguments.cachename); - else - ORMEvictQueries(); - } - - /** - * Returns the datasource for a given entity - * @entity The entity reference. Can be passed as an object or as the entity name. - */ - public string function getEntityDatasource(required entity) { - // DEFAULT datasource - var datasource = getDefaultDatasource(); - - if(!IsObject(arguments.entity)) arguments.entity= EntityNew(arguments.entity); - - var md = getMetaData(arguments.entity); - if( StructKeyExists(md,"DATASOURCE") ) datasource = md.DATASOURCE; - - return datasource; - } - - /** - * Get the default application datasource - */ - public string function getDefaultDatasource(){ - // get application metadata - if( listFirst(server.coldfusion.productVersion,",") gte 10 ){ - var settings = getApplicationMetadata(); - } - else{ - var settings = application.getApplicationSettings(); - } - - // check orm settings first - if( structKeyExists( settings,"ormsettings") AND structKeyExists(settings.ormsettings,"datasource")){ - return settings.ormsettings.datasource; - } - // else default to app datasource - return settings.datasource; - }; - -} \ No newline at end of file diff --git a/src/cfml/system/wirebox/system/orm/hibernate/util/IORMUtil.cfc b/src/cfml/system/wirebox/system/orm/hibernate/util/IORMUtil.cfc deleted file mode 100644 index fe26a8a31..000000000 --- a/src/cfml/system/wirebox/system/orm/hibernate/util/IORMUtil.cfc +++ /dev/null @@ -1,25 +0,0 @@ -/** -******************************************************************************** -Copyright Since 2005 ColdBox Framework by Luis Majano and Ortus Solutions, Corp -www.coldbox.org | www.luismajano.com | www.ortussolutions.com -******************************************************************************** -Author : Luis Majano & Mike McKellip -Description : - -The base interface for retreieveing the right CF ORM session for CFML engines -that do not support multiple dsn's yet. - -Once they do, these implementations will disappear. - ------------------------------------------------------------------------> -*/ -interface { - public void function flush(string datasource); - public any function getSession(string datasource); - public any function getSessionFactory(string datasource); - public void function clearSession(string datasource); - public void function closeSession(string datasource); - public void function evictQueries(string cachename, string datasource); - public string function getEntityDatasource(required entity); - public string function getDefaultDatasource(); -} \ No newline at end of file diff --git a/src/cfml/system/wirebox/system/orm/hibernate/util/ORMUtil.cfc b/src/cfml/system/wirebox/system/orm/hibernate/util/ORMUtil.cfc deleted file mode 100644 index 80f0eccb8..000000000 --- a/src/cfml/system/wirebox/system/orm/hibernate/util/ORMUtil.cfc +++ /dev/null @@ -1,63 +0,0 @@ -/** -******************************************************************************** -Copyright Since 2005 ColdBox Framework by Luis Majano and Ortus Solutions, Corp -www.coldbox.org | www.luismajano.com | www.ortussolutions.com -******************************************************************************** -Author : Luis Majano & Mike McKellip -Description : - -This ORM utility implementation is for engines that do NOT support multiple dsn's - ------------------------------------------------------------------------> -*/ -component implements="wirebox.system.orm.hibernate.util.IORMUtil"{ - - public void function flush(string datasource) { - ORMFlush(); - } - - public any function getSession(string datasource) { - return ORMGetSession(); - } - - public any function getSessionFactory(string datasource) { - return ORMGetSessionFactory(); - } - - public void function clearSession(string datasource) { - ORMClearSession(); - } - - public void function closeSession(string datasource) { - ORMCloseSession(); - } - - public void function evictQueries(string cachename, string datasource) { - if(StructKeyExists(arguments,"cachename")) - ORMEvictQueries(arguments.cachename); - else - ORMEvictQueries(); - } - - /** - * Returns the datasource for a given entity - * @entity The entity reference. Can be passed as an object or as the entity name. - */ - public string function getEntityDatasource(required entity) { - return getDefaultDatasource(); - } - - /** - * Get the default application datasource - */ - public string function getDefaultDatasource(){ - var settings = application.getApplicationSettings(); - // check orm settings first - if( structKeyExists( settings,"ormsettings") AND structKeyExists(settings.ormsettings,"datasource")){ - return settings.ormsettings.datasource; - } - // else default to app datasource - return settings.datasource; - }; - -} \ No newline at end of file diff --git a/src/cfml/system/wirebox/system/orm/hibernate/util/ORMUtilFactory.cfc b/src/cfml/system/wirebox/system/orm/hibernate/util/ORMUtilFactory.cfc deleted file mode 100644 index 423c495dd..000000000 --- a/src/cfml/system/wirebox/system/orm/hibernate/util/ORMUtilFactory.cfc +++ /dev/null @@ -1,31 +0,0 @@ -/** -******************************************************************************** -Copyright Since 2005 ColdBox Framework by Luis Majano and Ortus Solutions, Corp -www.coldbox.org | www.luismajano.com | www.ortussolutions.com -******************************************************************************** -Author : Luis Majano & Mike McKellip -Description : - -A simple factory to return the right ORM utility according to CFML engine - ------------------------------------------------------------------------> -*/ -import wirebox.system.orm.hibernate.util.*; - -component{ - - public any function getORMUtil() { - switch( getPlatform() ) { - case "ColdFusion Server": - return new CFORMUtil(); - break; - default: - return new ORMUtil(); - } - } - - private string function getPlatform() { - return server.coldfusion.productname; - } - -} \ No newline at end of file diff --git a/src/cfml/templates/cpu.json b/src/cfml/templates/cpu.json deleted file mode 100644 index 1f7beda3e..000000000 --- a/src/cfml/templates/cpu.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "projectURL" : "http://localhost", - "testbox" : { - "runnerURL" : "http://localhost", - "browserURL" : "http://localhost" - } -} \ No newline at end of file diff --git a/src/cfml/userconfig/commandbox.json b/src/cfml/userconfig/commandbox.json deleted file mode 100644 index 4eb7c3f98..000000000 --- a/src/cfml/userconfig/commandbox.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - -} \ No newline at end of file diff --git a/src/cfml/userconfig/readme.txt b/src/cfml/userconfig/readme.txt deleted file mode 100644 index ee83d88de..000000000 --- a/src/cfml/userconfig/readme.txt +++ /dev/null @@ -1,16 +0,0 @@ - _____ _ ____ - / ____| | | _ \ - | | ___ _ __ ___ _ __ ___ __ _ _ __ __| | |_) | _____ __ - | | / _ \| '_ ` _ \| '_ ` _ \ / _` | '_ \ / _` | _ < / _ \ \/ / - | |___| (_) | | | | | | | | | | | (_| | | | | (_| | |_) | (_) > < - \_____\___/|_| |_| |_|_| |_| |_|\__,_|_| |_|\__,_|____/ \___/_/\_\ -******************************************************************************** -Copyright Since 2005 ColdBox Framework by Luis Majano and Ortus Solutions, Corp -www.coldbox.org | www.luismajano.com | www.ortussolutions.com -******************************************************************************** -COMMANDBOX.JSON HELP -******************************************************************************** -The commandbox.json is your user preferences file you can tweak to alter the -behavior of CommandBox. Below is a description of what the settings can do: - - diff --git a/src/java/com/ortussolutions/commandbox/authentication/ProxyAuthenticator.java b/src/java/com/ortussolutions/commandbox/authentication/ProxyAuthenticator.java new file mode 100644 index 000000000..4ae9b7fff --- /dev/null +++ b/src/java/com/ortussolutions/commandbox/authentication/ProxyAuthenticator.java @@ -0,0 +1,27 @@ +/** +********************************************************************************* +* Copyright Since 2014 CommandBox by Ortus Solutions, Corp +* www.coldbox.org | www.ortussolutions.com +******************************************************************************** +* @author Brad Wood, Luis Majano +* +* I implement proxy authentication +*/ +package com.ortussolutions.commandbox.authentication; + +import java.net.Authenticator; +import java.net.PasswordAuthentication; + +public class ProxyAuthenticator extends Authenticator { + + private String user, password; + + public ProxyAuthenticator(String user, String password) { + this.user = user; + this.password = password; + } + + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication(user, password.toCharArray()); + } +} diff --git a/tests/cfml/commands/TestHelp.cfc b/tests/cfml/commands/TestHelp.cfc index bc6505db5..7c709b551 100644 --- a/tests/cfml/commands/TestHelp.cfc +++ b/tests/cfml/commands/TestHelp.cfc @@ -2,7 +2,7 @@ component name="TestHelp" extends="mxunit.framework.TestCase" { public void function testCommandService() { shell = application.wirebox.getInstance( 'Shell' ); - helpCommand = application.wirebox.getInstance( 'commandbox.system.commands.help' ); + // helpCommand = application.wirebox.getInstance( 'commandbox.system.commands.help' ); }