Created
November 15, 2021 02:49
-
-
Save lucasff/8fae1368387a1f1bd9673c45cb3d570d to your computer and use it in GitHub Desktop.
FreeMarker FTL json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#-- The black_list contains bad hash keys. Any hash key which matches a | |
-- black_list entry is prevented from being displayed. | |
--> | |
<#assign black_list = [ | |
"class", | |
"getclass", | |
"getmethod", | |
"getenclosingmethod", | |
"getcanonicalname", | |
"hashcode", | |
"getproviders", | |
"getdeclaredfields", | |
"cast", | |
"equals", | |
"tostring", | |
"isdisplayinfo", | |
"islocalclass", | |
"isinstance", | |
"isinterface", | |
"issynthetic", | |
"assubclass", | |
"getfield", | |
"getcomponenttype", | |
"isarray", | |
"isprimitive", | |
"isannotation", | |
"getdeclaredconstructors", | |
"isassignableform", | |
"isassignablefrom", | |
"getdeclaringclass", | |
"package" | |
] /> | |
<#-- | |
-- The main macro. | |
--> | |
<#macro stringify data depth=0> | |
<#compress> | |
<#if depth gt 6> | |
/* stringify: refusing to run ${depth} */ | |
<#return> | |
</#if> | |
<#-- | |
-- Test for hashes/objects | |
--> | |
<#local isHash = false> | |
<#attempt> | |
<#local isHash = data?is_hash || data?is_hash_ex> | |
<#recover> | |
/* can't evaluate if object is hash */ | |
undefined | |
<#return> | |
</#attempt> | |
<#if isHash> | |
<#attempt> | |
<@printHashEx data depth+1 />, | |
<#recover> | |
undefined | |
/* printHashEx failed */ | |
<#return> | |
</#attempt> | |
</#if> | |
<#-- | |
-- Test for arrays | |
--> | |
<#local isEnumerable = false> | |
<#attempt> | |
<#local isEnumerable = data?is_enumerable> | |
<#--/* stringify: data is enumerable? ${isEnumerable?c} */--> | |
<#recover> | |
undefined | |
/* can't evaluate if object is enumerable */ | |
<#return> | |
</#attempt> | |
<#if isEnumerable> | |
<#attempt> | |
<@printList data />, | |
<#recover> | |
undefined | |
/* printList failed */ | |
<#return> | |
</#attempt> | |
</#if> | |
<#local isMethod = false> | |
<#attempt> | |
<#local isMethod = data?is_method> | |
<#--/* stringify: data is a method? ${isMethod?c} */--> | |
<#recover> | |
/* can't test if object is a method */ | |
undefined | |
<#return> | |
</#attempt> | |
<#if isMethod> | |
undefined | |
</#if> | |
<#local isBoolean = false> | |
<#attempt> | |
<#local isBoolean = data?is_boolean> | |
<#--/* stringify: data is a boolean? ${isBoolean?c} */--> | |
<#recover> | |
/* can't test if object is a boolean */ | |
undefined | |
<#return> | |
</#attempt> | |
<#if isBoolean> | |
${data?c} | |
</#if> | |
<#local isString = false> | |
<#attempt> | |
<#local isString = data?is_string> | |
<#--/* stringify: data is a boolean? ${isBoolean?c} */--> | |
<#recover> | |
/* can't test if object is a boolean */ | |
<#return> | |
</#attempt> | |
<#if isString> | |
<#if data?lower_case?index_of("bean") gte 0> | |
<#return> | |
</#if> | |
<#t>"${data?json_string}" | |
</#if> | |
</#compress> | |
</#macro> | |
<#macro debug data> | |
<#attempt> | |
/* debug: hasContent? ${data?has_content?c} */ | |
/* debug: hasApi? ${data?has_api?c} */ | |
/* debug: isHash? ${data?is_hash?c} */ | |
/* debug: isEnumerable? ${data?is_enumerable?c} */ | |
/* debug: isString? ${data?is_string?c} */ | |
/* debug: isBoolean? ${data?is_boolean?c} */ | |
/* debug: isMethod? ${data?is_method?c} */ | |
/* debug: isSequence? ${data?is_sequence?c} */ | |
/* debug: isCollection? ${data?is_collection?c} */ | |
/* debug: isCollectionEx? ${data?is_collection_ex?c} */ | |
<#recover> | |
/* can't debug */ | |
<#return> | |
</#attempt> | |
</#macro> | |
<#macro rawStringify data> | |
/* called rawStringify /* | |
<#if data?is_enumerable> | |
<@printList data /> | |
<#elseif data?is_hash> | |
<@printHashEx data /> | |
</#if> | |
</#macro> | |
<#macro printList data> | |
/* printList start */ | |
<#list data> | |
[${'\n'} | |
<#items as item> | |
<#attempt> | |
<@printListItem item /> | |
<#recover> | |
/* printList: couldn't call printListItem */ | |
<#return> | |
</#attempt> | |
<#--"${item}"--> | |
<#sep>,</#sep> | |
<#--/* isString: "${item?is_string?c}" */--> | |
<#--/* isMethod: "${item?is_boolean?c}" */--> | |
<#--/* isBoolean: "${item?is_boolean?c}" */--> | |
</#items> | |
]${'\n'} | |
<#else> | |
/* printList empty! */ | |
[] | |
</#list> | |
/* printList end */ | |
</#macro> | |
<#macro printHashEx hash depth=0> | |
${'\t'} | |
<#if depth gt 7> | |
/* printHashEx: refusing to run ${depth} */ | |
<#return> | |
</#if> | |
<#t>{ | |
<#list hash as key, item> | |
<#if omit(key?string)> | |
<#continue> | |
</#if> | |
"${key}":<@stringify item!'' depth+1 /><#sep>,</#sep> | |
<#--"${key}":<#if item??><@printHashItem item key depth /></#if>--> | |
</#list>} | |
</#macro> | |
<#macro printHashItem item key depth> | |
<#if depth gt 7> | |
/* printHashItem: refusing to run ${depth} */ | |
undefined | |
<#return> | |
</#if> | |
/* call printHashItem with ${key} */ | |
<#if omit(key?string)> | |
/* omit: ${omit(key?string)?c} */ | |
undefined | |
<#return> | |
</#if> | |
<#if item?is_enumerable> | |
/* printHashItem -> printList */ | |
<#t>"${key?js_string}":<@printList item /> | |
<#elseif item?is_hash_ex && omit(key?string)><#-- omit bean-wrapped java.lang.Class objects --> | |
undefined | |
<#elseif item?is_hash> | |
/* printHashItem -> printHashEx */ | |
"${key?js_string}":<@printHashEx item depth+1 /> | |
<#elseif item?is_number> | |
<#t>"${key?js_string}":${item?string.computer} | |
<#elseif item?is_string> | |
<#t>"${key?js_string}":"${item?js_string}" | |
<#elseif item?is_boolean> | |
<#t>"${key?js_string}":${item?c} | |
<#elseif item?is_date> | |
<#t>"${key?js_string}":"${item?string("yyyy-MM-dd'T'HH:mm:sszzzz")}" | |
</#if> | |
</#macro> | |
<#macro printListItem item> | |
/* printListItem */ | |
<#if item?is_enumerable> | |
/* printListItem -> printList */ | |
<#t><@printList item /> | |
<#elseif item?is_hash_ex> | |
/* printListItem -> printHashEx */ | |
<@printHashEx item /> | |
<#elseif item?is_number> | |
<#t>${item?string.computer} | |
<#elseif item?is_string> | |
<#t>"${item?js_string}" | |
<#elseif item?is_boolean> | |
<#t>"${item?c}" | |
<#elseif item?is_date> | |
<#t>"${item?string("yyyy-MM-dd'T'HH:mm:sszzzz")}" | |
</#if> | |
</#macro> | |
<#function omit key> | |
<#local what = key?lower_case> | |
<#list black_list as item> | |
<#if what?index_of(item) gte 0> | |
<#return true> | |
</#if> | |
</#list> | |
<#return false> | |
</#function> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment