component { public any function init() { var osName = createObject( 'java', 'java.lang.System' ).getProperty( 'os.name' ); variables.defaultLineEnding = osName.findNoCase( 'windows' ) ? chr( 13 ) & chr( 10 ) : chr( 10 ); variables.defaultIndent = ' '; return this; } public string function formatJson( required any json, string indent = defaultIndent, string lineEnding = defaultLineEnding, boolean spaceAfterColon = false, boolean sortKeys = false ) { if ( !isSimpleValue( json ) ) { /* even though we are going to work from native CFML types we have to ensure we have only structs, arrays, and simple types so we have to start by serializing if we have a CFML object */ json = serializeJSON( json ); } json = deserializeJSON( json ); var settings = { indent: indent, lineEnding: lineEnding, colon: spaceAfterColon ? ': ' : ':', sortKeys: sortKeys }; return printString( json, settings ); } private string function printString( json, settings, baseIndent = '' ) { if ( isStruct( json ) ) { if ( structIsEmpty( json ) ) { return '{}'; } var keys = json.keyArray(); if ( settings.sortKeys ) { keys.sort( 'text' ); } var strs = [ ]; for ( var key in keys ) { var str = baseIndent & settings.indent & '"#key#"' & settings.colon; str &= printString( json[ key ], settings, baseIndent & settings.indent ); strs.append( str ); } return '{' & settings.lineEnding & strs.toList( ',' & settings.lineEnding ) & settings.lineEnding & baseIndent & '}'; } if ( isArray( json ) ) { if ( arrayIsEmpty( json ) ) { return '[]'; } var strs = [ ]; for ( var item in json ) { var str = baseIndent & settings.indent & printString( item, settings, baseIndent & settings.indent ); strs.append( str ); } return '[' & settings.lineEnding & strs.toList( ',' & settings.lineEnding ) & settings.lineEnding & baseIndent & ']'; } /* Simple types don't require any special formatting so we can let serializeJSON convert them to JSON for us. */ return serializeJSON( json ); } }