Fixed the catalog editor. Support using a branch
Project: http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/repo Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/commit/7ccfa3aa Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/tree/7ccfa3aa Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/diff/7ccfa3aa Branch: refs/heads/master Commit: 7ccfa3aa83376bf79ac931f2d4cced4bad0e8341 Parents: 3b40bf6 Author: Ralph Goers <rgo...@apache.org> Authored: Sun Apr 8 09:49:04 2018 -0700 Committer: Ralph Goers <rgo...@apache.org> Committed: Sun Apr 8 09:49:04 2018 -0700 ---------------------------------------------------------------------- .../log4j/catalog/config/WebMvcAppContext.java | 85 +- .../src/main/resources/application.properties | 6 + .../src/main/resources/static/css/app.css | 205 + .../resources/static/images/ajax-loader.gif | Bin 0 -> 3208 bytes .../main/resources/static/images/attributes.png | Bin 0 -> 1981 bytes .../main/resources/static/images/constraint.png | Bin 0 -> 2586 bytes .../src/main/resources/static/js/app.js | 81 + .../src/main/resources/static/js/attributes.js | 364 + .../src/main/resources/static/js/categories.js | 257 + .../src/main/resources/static/js/events.js | 291 + .../resources/static/js/jquery-1.12.4.min.js | 5 + .../resources/static/js/jquery-2.2.4.min.js | 4 + .../resources/static/js/jquery-3.2.1.min.js | 4 + .../static/js/jquery-ui-1.12.1/AUTHORS.txt | 333 + .../static/js/jquery-ui-1.12.1/LICENSE.txt | 43 + .../jquery-ui-1.12.1/external/jquery/jquery.js | 11008 ++++++++++ .../images/ui-icons_444444_256x240.png | Bin 0 -> 7006 bytes .../images/ui-icons_555555_256x240.png | Bin 0 -> 7074 bytes .../images/ui-icons_777620_256x240.png | Bin 0 -> 4676 bytes .../images/ui-icons_777777_256x240.png | Bin 0 -> 7013 bytes .../images/ui-icons_cc0000_256x240.png | Bin 0 -> 4632 bytes .../images/ui-icons_ffffff_256x240.png | Bin 0 -> 6313 bytes .../static/js/jquery-ui-1.12.1/index.html | 559 + .../static/js/jquery-ui-1.12.1/jquery-ui.css | 1312 ++ .../static/js/jquery-ui-1.12.1/jquery-ui.js | 18706 +++++++++++++++++ .../js/jquery-ui-1.12.1/jquery-ui.min.css | 7 + .../static/js/jquery-ui-1.12.1/jquery-ui.min.js | 13 + .../js/jquery-ui-1.12.1/jquery-ui.structure.css | 886 + .../jquery-ui.structure.min.css | 5 + .../js/jquery-ui-1.12.1/jquery-ui.theme.css | 443 + .../js/jquery-ui-1.12.1/jquery-ui.theme.min.css | 5 + .../static/js/jquery-ui-1.12.1/package.json | 74 + .../jquery.jtable.aspnetpagemethods.js | 150 + .../jquery.jtable.aspnetpagemethods.min.js | 27 + .../static/js/jtable.2.4.0/external/json2.js | 486 + .../js/jtable.2.4.0/external/json2.min.js | 8 + .../static/js/jtable.2.4.0/jquery.jtable.js | 5021 +++++ .../static/js/jtable.2.4.0/jquery.jtable.min.js | 157 + .../localization/jquery.jtable.bd.js | 30 + .../localization/jquery.jtable.ca.js | 30 + .../localization/jquery.jtable.cz.js | 30 + .../localization/jquery.jtable.de.js | 30 + .../localization/jquery.jtable.es.js | 30 + .../localization/jquery.jtable.fa.js | 30 + .../localization/jquery.jtable.fr.js | 30 + .../localization/jquery.jtable.hr.js | 30 + .../localization/jquery.jtable.hu.js | 30 + .../localization/jquery.jtable.id.js | 31 + .../localization/jquery.jtable.it.js | 30 + .../localization/jquery.jtable.lt.js | 30 + .../localization/jquery.jtable.nl-NL.js | 30 + .../localization/jquery.jtable.no.js | 30 + .../localization/jquery.jtable.pl.js | 30 + .../localization/jquery.jtable.pt-BR.js | 30 + .../localization/jquery.jtable.pt-PT.js | 29 + .../localization/jquery.jtable.ro.js | 30 + .../localization/jquery.jtable.ru.js | 31 + .../localization/jquery.jtable.se.js | 30 + .../localization/jquery.jtable.tr.js | 30 + .../localization/jquery.jtable.vi.js | 28 + .../localization/jquery.jtable.zh-CN.js | 30 + .../js/jtable.2.4.0/themes/basic/close.png | Bin 0 -> 3350 bytes .../js/jtable.2.4.0/themes/basic/column-asc.png | Bin 0 -> 362 bytes .../jtable.2.4.0/themes/basic/column-desc.png | Bin 0 -> 349 bytes .../themes/basic/column-sortable.png | Bin 0 -> 347 bytes .../js/jtable.2.4.0/themes/basic/delete.png | Bin 0 -> 150 bytes .../js/jtable.2.4.0/themes/basic/edit.png | Bin 0 -> 590 bytes .../jtable.2.4.0/themes/basic/jtable_basic.css | 282 + .../jtable.2.4.0/themes/basic/jtable_basic.less | 83 + .../themes/basic/jtable_basic.min.css | 1 + .../js/jtable.2.4.0/themes/jqueryui/add.png | Bin 0 -> 482 bytes .../jtable.2.4.0/themes/jqueryui/bg-thead.png | Bin 0 -> 2811 bytes .../js/jtable.2.4.0/themes/jqueryui/close.png | Bin 0 -> 1217 bytes .../jtable.2.4.0/themes/jqueryui/column-asc.png | Bin 0 -> 362 bytes .../themes/jqueryui/column-desc.png | Bin 0 -> 349 bytes .../themes/jqueryui/column-sortable.png | Bin 0 -> 347 bytes .../js/jtable.2.4.0/themes/jqueryui/delete.png | Bin 0 -> 150 bytes .../js/jtable.2.4.0/themes/jqueryui/edit.png | Bin 0 -> 590 bytes .../themes/jqueryui/jtable_jqueryui.css | 398 + .../themes/jqueryui/jtable_jqueryui.less | 296 + .../themes/jqueryui/jtable_jqueryui.min.css | 1 + .../js/jtable.2.4.0/themes/jqueryui/loading.gif | Bin 0 -> 723 bytes .../jtable.2.4.0/themes/jtable_theme_base.less | 524 + .../js/jtable.2.4.0/themes/lightcolor/add.png | Bin 0 -> 482 bytes .../jtable.2.4.0/themes/lightcolor/bg-thead.png | Bin 0 -> 2811 bytes .../themes/lightcolor/blue/jtable.css | 521 + .../themes/lightcolor/blue/jtable.less | 90 + .../themes/lightcolor/blue/jtable.min.css | 1 + .../themes/lightcolor/blue/loading.gif | Bin 0 -> 723 bytes .../js/jtable.2.4.0/themes/lightcolor/close.png | Bin 0 -> 1217 bytes .../themes/lightcolor/column-asc.png | Bin 0 -> 362 bytes .../themes/lightcolor/column-desc.png | Bin 0 -> 349 bytes .../themes/lightcolor/column-sortable.png | Bin 0 -> 347 bytes .../jtable.2.4.0/themes/lightcolor/delete.png | Bin 0 -> 150 bytes .../js/jtable.2.4.0/themes/lightcolor/edit.png | Bin 0 -> 590 bytes .../themes/lightcolor/gray/jtable.css | 521 + .../themes/lightcolor/gray/jtable.less | 90 + .../themes/lightcolor/gray/jtable.min.css | 1 + .../themes/lightcolor/gray/loading.gif | Bin 0 -> 723 bytes .../themes/lightcolor/green/jtable.css | 521 + .../themes/lightcolor/green/jtable.less | 90 + .../themes/lightcolor/green/jtable.min.css | 1 + .../themes/lightcolor/green/loading.gif | Bin 0 -> 723 bytes .../lightcolor/jtable_lightcolor_base.less | 329 + .../themes/lightcolor/orange/jtable.css | 521 + .../themes/lightcolor/orange/jtable.less | 90 + .../themes/lightcolor/orange/jtable.min.css | 1 + .../themes/lightcolor/orange/loading.gif | Bin 0 -> 723 bytes .../themes/lightcolor/red/jtable.css | 521 + .../themes/lightcolor/red/jtable.less | 90 + .../themes/lightcolor/red/jtable.min.css | 1 + .../themes/lightcolor/red/loading.gif | Bin 0 -> 723 bytes .../static/js/jtable.2.4.0/themes/metro/add.png | Bin 0 -> 482 bytes .../jtable.2.4.0/themes/metro/blue/jtable.css | 495 + .../jtable.2.4.0/themes/metro/blue/jtable.less | 11 + .../themes/metro/blue/jtable.min.css | 1 + .../jtable.2.4.0/themes/metro/blue/loading.gif | Bin 0 -> 404 bytes .../jtable.2.4.0/themes/metro/brown/jtable.css | 495 + .../jtable.2.4.0/themes/metro/brown/jtable.less | 11 + .../themes/metro/brown/jtable.min.css | 1 + .../jtable.2.4.0/themes/metro/brown/loading.gif | Bin 0 -> 404 bytes .../js/jtable.2.4.0/themes/metro/close.png | Bin 0 -> 3350 bytes .../js/jtable.2.4.0/themes/metro/column-asc.png | Bin 0 -> 320 bytes .../jtable.2.4.0/themes/metro/column-desc.png | Bin 0 -> 311 bytes .../themes/metro/column-sortable.png | Bin 0 -> 314 bytes .../themes/metro/crimson/jtable.css | 495 + .../themes/metro/crimson/jtable.less | 11 + .../themes/metro/crimson/jtable.min.css | 1 + .../themes/metro/crimson/loading.gif | Bin 0 -> 404 bytes .../themes/metro/darkgray/jtable.css | 495 + .../themes/metro/darkgray/jtable.less | 11 + .../themes/metro/darkgray/jtable.min.css | 1 + .../themes/metro/darkgray/loading.gif | Bin 0 -> 404 bytes .../themes/metro/darkorange/jtable.css | 495 + .../themes/metro/darkorange/jtable.less | 11 + .../themes/metro/darkorange/jtable.min.css | 1 + .../themes/metro/darkorange/loading.gif | Bin 0 -> 404 bytes .../js/jtable.2.4.0/themes/metro/delete.png | Bin 0 -> 3167 bytes .../js/jtable.2.4.0/themes/metro/edit.png | Bin 0 -> 3359 bytes .../jtable.2.4.0/themes/metro/green/jtable.css | 495 + .../jtable.2.4.0/themes/metro/green/jtable.less | 11 + .../themes/metro/green/jtable.min.css | 1 + .../jtable.2.4.0/themes/metro/green/loading.gif | Bin 0 -> 404 bytes .../themes/metro/jtable_metro_base.css | 48 + .../themes/metro/jtable_metro_base.less | 439 + .../themes/metro/jtable_metro_base.min.css | 1 + .../themes/metro/lightgray/jtable.css | 495 + .../themes/metro/lightgray/jtable.less | 11 + .../themes/metro/lightgray/jtable.min.css | 1 + .../themes/metro/lightgray/loading.gif | Bin 0 -> 404 bytes .../jtable.2.4.0/themes/metro/pink/jtable.css | 495 + .../jtable.2.4.0/themes/metro/pink/jtable.less | 11 + .../themes/metro/pink/jtable.min.css | 1 + .../jtable.2.4.0/themes/metro/pink/loading.gif | Bin 0 -> 404 bytes .../jtable.2.4.0/themes/metro/purple/jtable.css | 495 + .../themes/metro/purple/jtable.less | 11 + .../themes/metro/purple/jtable.min.css | 1 + .../themes/metro/purple/loading.gif | Bin 0 -> 404 bytes .../js/jtable.2.4.0/themes/metro/red/jtable.css | 495 + .../jtable.2.4.0/themes/metro/red/jtable.less | 11 + .../themes/metro/red/jtable.min.css | 1 + .../jtable.2.4.0/themes/metro/red/loading.gif | Bin 0 -> 404 bytes .../src/main/resources/static/js/products.js | 257 + .../main/resources/templates/attributes.html | 44 + .../main/resources/templates/categories.html | 43 + .../src/main/resources/templates/events.html | 44 + .../src/main/resources/templates/products.html | 43 + .../src/main/resources/templates/template.html | 42 + .../webapp/WEB-INF/templates/attributes.html | 44 - .../webapp/WEB-INF/templates/categories.html | 43 - .../main/webapp/WEB-INF/templates/events.html | 44 - .../main/webapp/WEB-INF/templates/products.html | 43 - .../main/webapp/WEB-INF/templates/template.html | 42 - .../src/main/webapp/css/app.css | 205 - .../src/main/webapp/images/ajax-loader.gif | Bin 3208 -> 0 bytes .../src/main/webapp/images/attributes.png | Bin 1981 -> 0 bytes .../src/main/webapp/images/constraint.png | Bin 2586 -> 0 bytes .../src/main/webapp/js/app.js | 81 - .../src/main/webapp/js/attributes.js | 364 - .../src/main/webapp/js/categories.js | 257 - .../src/main/webapp/js/events.js | 291 - .../src/main/webapp/js/jquery-1.12.4.min.js | 5 - .../src/main/webapp/js/jquery-2.2.4.min.js | 4 - .../src/main/webapp/js/jquery-3.2.1.min.js | 4 - .../main/webapp/js/jquery-ui-1.12.1/AUTHORS.txt | 333 - .../main/webapp/js/jquery-ui-1.12.1/LICENSE.txt | 43 - .../jquery-ui-1.12.1/external/jquery/jquery.js | 11008 ---------- .../images/ui-icons_444444_256x240.png | Bin 7006 -> 0 bytes .../images/ui-icons_555555_256x240.png | Bin 7074 -> 0 bytes .../images/ui-icons_777620_256x240.png | Bin 4676 -> 0 bytes .../images/ui-icons_777777_256x240.png | Bin 7013 -> 0 bytes .../images/ui-icons_cc0000_256x240.png | Bin 4632 -> 0 bytes .../images/ui-icons_ffffff_256x240.png | Bin 6313 -> 0 bytes .../main/webapp/js/jquery-ui-1.12.1/index.html | 559 - .../webapp/js/jquery-ui-1.12.1/jquery-ui.css | 1312 -- .../webapp/js/jquery-ui-1.12.1/jquery-ui.js | 18706 ----------------- .../js/jquery-ui-1.12.1/jquery-ui.min.css | 7 - .../webapp/js/jquery-ui-1.12.1/jquery-ui.min.js | 13 - .../js/jquery-ui-1.12.1/jquery-ui.structure.css | 886 - .../jquery-ui.structure.min.css | 5 - .../js/jquery-ui-1.12.1/jquery-ui.theme.css | 443 - .../js/jquery-ui-1.12.1/jquery-ui.theme.min.css | 5 - .../webapp/js/jquery-ui-1.12.1/package.json | 74 - .../jquery.jtable.aspnetpagemethods.js | 150 - .../jquery.jtable.aspnetpagemethods.min.js | 27 - .../webapp/js/jtable.2.4.0/external/json2.js | 486 - .../js/jtable.2.4.0/external/json2.min.js | 8 - .../webapp/js/jtable.2.4.0/jquery.jtable.js | 5021 ----- .../webapp/js/jtable.2.4.0/jquery.jtable.min.js | 157 - .../localization/jquery.jtable.bd.js | 30 - .../localization/jquery.jtable.ca.js | 30 - .../localization/jquery.jtable.cz.js | 30 - .../localization/jquery.jtable.de.js | 30 - .../localization/jquery.jtable.es.js | 30 - .../localization/jquery.jtable.fa.js | 30 - .../localization/jquery.jtable.fr.js | 30 - .../localization/jquery.jtable.hr.js | 30 - .../localization/jquery.jtable.hu.js | 30 - .../localization/jquery.jtable.id.js | 31 - .../localization/jquery.jtable.it.js | 30 - .../localization/jquery.jtable.lt.js | 30 - .../localization/jquery.jtable.nl-NL.js | 30 - .../localization/jquery.jtable.no.js | 30 - .../localization/jquery.jtable.pl.js | 30 - .../localization/jquery.jtable.pt-BR.js | 30 - .../localization/jquery.jtable.pt-PT.js | 29 - .../localization/jquery.jtable.ro.js | 30 - .../localization/jquery.jtable.ru.js | 31 - .../localization/jquery.jtable.se.js | 30 - .../localization/jquery.jtable.tr.js | 30 - .../localization/jquery.jtable.vi.js | 28 - .../localization/jquery.jtable.zh-CN.js | 30 - .../js/jtable.2.4.0/themes/basic/close.png | Bin 3350 -> 0 bytes .../js/jtable.2.4.0/themes/basic/column-asc.png | Bin 362 -> 0 bytes .../jtable.2.4.0/themes/basic/column-desc.png | Bin 349 -> 0 bytes .../themes/basic/column-sortable.png | Bin 347 -> 0 bytes .../js/jtable.2.4.0/themes/basic/delete.png | Bin 150 -> 0 bytes .../js/jtable.2.4.0/themes/basic/edit.png | Bin 590 -> 0 bytes .../jtable.2.4.0/themes/basic/jtable_basic.css | 282 - .../jtable.2.4.0/themes/basic/jtable_basic.less | 83 - .../themes/basic/jtable_basic.min.css | 1 - .../js/jtable.2.4.0/themes/jqueryui/add.png | Bin 482 -> 0 bytes .../jtable.2.4.0/themes/jqueryui/bg-thead.png | Bin 2811 -> 0 bytes .../js/jtable.2.4.0/themes/jqueryui/close.png | Bin 1217 -> 0 bytes .../jtable.2.4.0/themes/jqueryui/column-asc.png | Bin 362 -> 0 bytes .../themes/jqueryui/column-desc.png | Bin 349 -> 0 bytes .../themes/jqueryui/column-sortable.png | Bin 347 -> 0 bytes .../js/jtable.2.4.0/themes/jqueryui/delete.png | Bin 150 -> 0 bytes .../js/jtable.2.4.0/themes/jqueryui/edit.png | Bin 590 -> 0 bytes .../themes/jqueryui/jtable_jqueryui.css | 398 - .../themes/jqueryui/jtable_jqueryui.less | 296 - .../themes/jqueryui/jtable_jqueryui.min.css | 1 - .../js/jtable.2.4.0/themes/jqueryui/loading.gif | Bin 723 -> 0 bytes .../jtable.2.4.0/themes/jtable_theme_base.less | 524 - .../js/jtable.2.4.0/themes/lightcolor/add.png | Bin 482 -> 0 bytes .../jtable.2.4.0/themes/lightcolor/bg-thead.png | Bin 2811 -> 0 bytes .../themes/lightcolor/blue/jtable.css | 521 - .../themes/lightcolor/blue/jtable.less | 90 - .../themes/lightcolor/blue/jtable.min.css | 1 - .../themes/lightcolor/blue/loading.gif | Bin 723 -> 0 bytes .../js/jtable.2.4.0/themes/lightcolor/close.png | Bin 1217 -> 0 bytes .../themes/lightcolor/column-asc.png | Bin 362 -> 0 bytes .../themes/lightcolor/column-desc.png | Bin 349 -> 0 bytes .../themes/lightcolor/column-sortable.png | Bin 347 -> 0 bytes .../jtable.2.4.0/themes/lightcolor/delete.png | Bin 150 -> 0 bytes .../js/jtable.2.4.0/themes/lightcolor/edit.png | Bin 590 -> 0 bytes .../themes/lightcolor/gray/jtable.css | 521 - .../themes/lightcolor/gray/jtable.less | 90 - .../themes/lightcolor/gray/jtable.min.css | 1 - .../themes/lightcolor/gray/loading.gif | Bin 723 -> 0 bytes .../themes/lightcolor/green/jtable.css | 521 - .../themes/lightcolor/green/jtable.less | 90 - .../themes/lightcolor/green/jtable.min.css | 1 - .../themes/lightcolor/green/loading.gif | Bin 723 -> 0 bytes .../lightcolor/jtable_lightcolor_base.less | 329 - .../themes/lightcolor/orange/jtable.css | 521 - .../themes/lightcolor/orange/jtable.less | 90 - .../themes/lightcolor/orange/jtable.min.css | 1 - .../themes/lightcolor/orange/loading.gif | Bin 723 -> 0 bytes .../themes/lightcolor/red/jtable.css | 521 - .../themes/lightcolor/red/jtable.less | 90 - .../themes/lightcolor/red/jtable.min.css | 1 - .../themes/lightcolor/red/loading.gif | Bin 723 -> 0 bytes .../webapp/js/jtable.2.4.0/themes/metro/add.png | Bin 482 -> 0 bytes .../jtable.2.4.0/themes/metro/blue/jtable.css | 495 - .../jtable.2.4.0/themes/metro/blue/jtable.less | 11 - .../themes/metro/blue/jtable.min.css | 1 - .../jtable.2.4.0/themes/metro/blue/loading.gif | Bin 404 -> 0 bytes .../jtable.2.4.0/themes/metro/brown/jtable.css | 495 - .../jtable.2.4.0/themes/metro/brown/jtable.less | 11 - .../themes/metro/brown/jtable.min.css | 1 - .../jtable.2.4.0/themes/metro/brown/loading.gif | Bin 404 -> 0 bytes .../js/jtable.2.4.0/themes/metro/close.png | Bin 3350 -> 0 bytes .../js/jtable.2.4.0/themes/metro/column-asc.png | Bin 320 -> 0 bytes .../jtable.2.4.0/themes/metro/column-desc.png | Bin 311 -> 0 bytes .../themes/metro/column-sortable.png | Bin 314 -> 0 bytes .../themes/metro/crimson/jtable.css | 495 - .../themes/metro/crimson/jtable.less | 11 - .../themes/metro/crimson/jtable.min.css | 1 - .../themes/metro/crimson/loading.gif | Bin 404 -> 0 bytes .../themes/metro/darkgray/jtable.css | 495 - .../themes/metro/darkgray/jtable.less | 11 - .../themes/metro/darkgray/jtable.min.css | 1 - .../themes/metro/darkgray/loading.gif | Bin 404 -> 0 bytes .../themes/metro/darkorange/jtable.css | 495 - .../themes/metro/darkorange/jtable.less | 11 - .../themes/metro/darkorange/jtable.min.css | 1 - .../themes/metro/darkorange/loading.gif | Bin 404 -> 0 bytes .../js/jtable.2.4.0/themes/metro/delete.png | Bin 3167 -> 0 bytes .../js/jtable.2.4.0/themes/metro/edit.png | Bin 3359 -> 0 bytes .../jtable.2.4.0/themes/metro/green/jtable.css | 495 - .../jtable.2.4.0/themes/metro/green/jtable.less | 11 - .../themes/metro/green/jtable.min.css | 1 - .../jtable.2.4.0/themes/metro/green/loading.gif | Bin 404 -> 0 bytes .../themes/metro/jtable_metro_base.css | 48 - .../themes/metro/jtable_metro_base.less | 439 - .../themes/metro/jtable_metro_base.min.css | 1 - .../themes/metro/lightgray/jtable.css | 495 - .../themes/metro/lightgray/jtable.less | 11 - .../themes/metro/lightgray/jtable.min.css | 1 - .../themes/metro/lightgray/loading.gif | Bin 404 -> 0 bytes .../jtable.2.4.0/themes/metro/pink/jtable.css | 495 - .../jtable.2.4.0/themes/metro/pink/jtable.less | 11 - .../themes/metro/pink/jtable.min.css | 1 - .../jtable.2.4.0/themes/metro/pink/loading.gif | Bin 404 -> 0 bytes .../jtable.2.4.0/themes/metro/purple/jtable.css | 495 - .../themes/metro/purple/jtable.less | 11 - .../themes/metro/purple/jtable.min.css | 1 - .../themes/metro/purple/loading.gif | Bin 404 -> 0 bytes .../js/jtable.2.4.0/themes/metro/red/jtable.css | 495 - .../jtable.2.4.0/themes/metro/red/jtable.less | 11 - .../themes/metro/red/jtable.min.css | 1 - .../jtable.2.4.0/themes/metro/red/loading.gif | Bin 404 -> 0 bytes .../src/main/webapp/js/products.js | 257 - .../log4j/catalog/git/dao/GitCatalogDao.java | 12 + 335 files changed, 52175 insertions(+), 52224 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/7ccfa3aa/log4j-catalog/log4j-catalog-editor/src/main/java/org/apache/logging/log4j/catalog/config/WebMvcAppContext.java ---------------------------------------------------------------------- diff --git a/log4j-catalog/log4j-catalog-editor/src/main/java/org/apache/logging/log4j/catalog/config/WebMvcAppContext.java b/log4j-catalog/log4j-catalog-editor/src/main/java/org/apache/logging/log4j/catalog/config/WebMvcAppContext.java index 181024d..5239d23 100644 --- a/log4j-catalog/log4j-catalog-editor/src/main/java/org/apache/logging/log4j/catalog/config/WebMvcAppContext.java +++ b/log4j-catalog/log4j-catalog-editor/src/main/java/org/apache/logging/log4j/catalog/config/WebMvcAppContext.java @@ -99,9 +99,9 @@ public class WebMvcAppContext extends WebMvcConfigurerAdapter implements Applica @Override public void addResourceHandlers(final ResourceHandlerRegistry registry) { super.addResourceHandlers(registry); - registry.addResourceHandler("/images/**").addResourceLocations("/images/"); - registry.addResourceHandler("/css/**").addResourceLocations("/css/"); - registry.addResourceHandler("/js/**").addResourceLocations("/js/"); + registry.addResourceHandler("/images/**").addResourceLocations("classpath:/static/images/"); + registry.addResourceHandler("/css/**").addResourceLocations("classpath:/static/css/"); + registry.addResourceHandler("/js/**").addResourceLocations("classpath:/static/js/"); registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/"); registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/"); } @@ -119,20 +119,6 @@ public class WebMvcAppContext extends WebMvcConfigurerAdapter implements Applica converters.add(jsonMessageConverter()); } - - /* - @Override - public void addInterceptors(InterceptorRegistry registry) { - registry.addInterceptor(localAuthorizationInterceptor()) - .addPathPatterns("/**") - .excludePathPatterns("/swagger**") - .excludePathPatterns("/v2/api-docs**") - .excludePathPatterns("/configuration/security**") - .excludePathPatterns("/configuration/ui**") - .excludePathPatterns("/webjars/**"); - } - */ - @Bean public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() { DefaultAdvisorAutoProxyCreator proxyCreator = new DefaultAdvisorAutoProxyCreator(); @@ -140,17 +126,6 @@ public class WebMvcAppContext extends WebMvcConfigurerAdapter implements Applica return proxyCreator; } - /* - @Bean - public ViewResolver internalResourceViewResolver() { - InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); - viewResolver.setViewClass(JstlView.class); - viewResolver.setPrefix("/WEB-INF/views/"); - viewResolver.setSuffix(".jsp"); - viewResolver.setOrder(10); - return viewResolver; - } */ - @Bean public MessageSource messageSource() { ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource(); @@ -189,6 +164,9 @@ public class WebMvcAppContext extends WebMvcConfigurerAdapter implements Applica @Value("${localRepoUrl:#{null}}") private String localRepoUrl; + @Value("${branch:#{null}}") + private String branch; + @Value("${privateKeyPath:#{null}}") private String privateKeyPath; @@ -263,6 +241,9 @@ public class WebMvcAppContext extends WebMvcConfigurerAdapter implements Applica } else { LOGGER.error("No remote repo URL provided."); } + if (isNotBlank(branch)) { + dataSource.setBranch(branch); + } if (isNotBlank(localRepoUrl)) { dataSource.setLocalRepoPath(localRepoUrl); @@ -280,52 +261,4 @@ public class WebMvcAppContext extends WebMvcConfigurerAdapter implements Applica } return dataSource; } - - public SpringResourceTemplateResolver templateResolver(){ - // SpringResourceTemplateResolver automatically integrates with Spring's own - // resource resolution infrastructure, which is highly recommended. - SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver(); - templateResolver.setApplicationContext(this.applicationContext); - templateResolver.setPrefix("/WEB-INF/templates/"); - templateResolver.setSuffix(".html"); - // HTML is the default value, added here for the sake of clarity. - templateResolver.setTemplateMode(TemplateMode.HTML); - // Template cache is true by default. Set to false if you want - // templates to be automatically updated when modified. - templateResolver.setCacheable(true); - return templateResolver; - } - - public SpringTemplateEngine templateEngine(){ - // SpringTemplateEngine automatically applies SpringStandardDialect and - // enables Spring's own MessageSource message resolution mechanisms. - SpringTemplateEngine templateEngine = new SpringTemplateEngine(); - templateEngine.setTemplateResolver(templateResolver()); - // Enabling the SpringEL compiler with Spring 4.2.4 or newer can - // speed up execution in most scenarios, but might be incompatible - // with specific cases when expressions in one template are reused - // across different data types, so this flag is "false" by default - // for safer backwards compatibility. - templateEngine.setEnableSpringELCompiler(true); - return templateEngine; - } - - @Bean - public ViewResolver thymeleafViewResolver(){ - ThymeleafViewResolver viewResolver = new ThymeleafViewResolver(); - viewResolver.setTemplateEngine(templateEngine()); - // NOTE 'order' and 'viewNames' are optional - viewResolver.setOrder(1); - viewResolver.setViewNames(new String[] {"products", "categories", "events", "attributes"}); - return viewResolver; - } - - @Bean - @Scope("prototype") - public ThymeleafView mainView() { - ThymeleafView view = new ThymeleafView("index"); // templateName = 'main' - view.setStaticVariables( - Collections.singletonMap("footer", "The Apache Software Foundation")); - return view; - } } http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/7ccfa3aa/log4j-catalog/log4j-catalog-editor/src/main/resources/application.properties ---------------------------------------------------------------------- diff --git a/log4j-catalog/log4j-catalog-editor/src/main/resources/application.properties b/log4j-catalog/log4j-catalog-editor/src/main/resources/application.properties new file mode 100644 index 0000000..e9e2b8a --- /dev/null +++ b/log4j-catalog/log4j-catalog-editor/src/main/resources/application.properties @@ -0,0 +1,6 @@ +spring.thymeleaf.cache=false +spring.thymeleaf.enabled=true +spring.thymeleaf.prefix=classpath:/templates/ +spring.thymeleaf.suffix=.html + +spring.application.name=Log4j Catalog Editor \ No newline at end of file http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/7ccfa3aa/log4j-catalog/log4j-catalog-editor/src/main/resources/static/css/app.css ---------------------------------------------------------------------- diff --git a/log4j-catalog/log4j-catalog-editor/src/main/resources/static/css/app.css b/log4j-catalog/log4j-catalog-editor/src/main/resources/static/css/app.css new file mode 100644 index 0000000..d1ffda7 --- /dev/null +++ b/log4j-catalog/log4j-catalog-editor/src/main/resources/static/css/app.css @@ -0,0 +1,205 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache license, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the license for the specific language governing permissions and + * limitations under the license. + */ +@import url('https://fonts.googleapis.com/css?family=Lato'); + +body { + font-family: 'Lato', sans-serif; + margin: 0; + padding: 0; +} + +#nav { + background-color: #f3f3f3; + border-bottom: 1px solid #e7e7e7; + display: flex; + height: 48px; + justify-content: space-between; + margin-bottom: 24px; + width: 100%; +} + +#nav a { + border-right: 1px solid #e7e7e7; + color: #666; + font-size: 16px; + line-height: 48px; + padding: 0 14px; + text-decoration: none; +} + +#nav #save-all { + border-right: none; + border-left: 1px solid #e7e7e7; + margin-left: auto; +} + +#nav a:hover, +#nav #save-all:hover { + background-color: #0b67cd; + border-right: 1px solid #0b67cd; + color: #fff; +} + +#ftr { + margin: 24px; + text-align: center; +} + +.log4j-table-container { + padding: 0 24px; +} + +.form-processing { + position: absolute; + width: 100%; + height: 100%; + background-color: #fff; + z-index: 100; + opacity: .75; +} + +.form-processing .gif { + position: absolute; + top: calc(50% - 16px); + left: calc(50% - 16px); + width: 32px; + height: 32px; + background-image: url(../images/ajax-loader.gif); + background-repeat: no-repeat; +} + +.log4J-action-icon { + opacity: .4; +} + +.log4j-catalog-form { + position: relative; +} + +.log4j-catalog-form p { + position: relative; +} + +.log4j-catalog-form input[type="text"], +.log4j-catalog-form select, +.log4j-catalog-form textarea { + width: 80%; + border: 1px solid #ddd; + padding: 2px 7px; + background-color: #fff; +} + +.log4j-catalog-form select[multiple] { + height: 200px; +} + +.log4j-catalog-form label { + display: block; + margin-bottom: 7px; + color: #aaa; +} + +.log4j-catalog-form .form-error { + position: absolute; + top: 52px; + left: 354px; + color: #ff0000; + font-size: 12px; +} + +.log4j-catalog-modal { + background-color: #fff; + border: 1px solid #ddd; + box-shadow: 0 0 20px #ccc; + left: 0; + margin: auto; + padding: 24px; + position: absolute; + right: 0; + top: 25%; + width: 500px; +} + +.log4j-catalog-title { + border-bottom: 1px solid #ddd; + margin-bottom: 24px; + padding-bottom: 14px; +} + +.log4j-catalog-button + .log4j-catalog-button { + margin-left: 24px; +} + +/* Events */ +.event-attributes, +.event-attribute-row { + font-size: 12px; +} + +.event-attribute-row, +.attribute-constraint-row, +.product-event-row { + display: block; + clear: both; + line-height: 12px; + margin: 2px 0; + vertical-align: middle; +} + +.event-attribute-row input[type="text"] { + width: 270px; + margin-right: 24px; +} + +.event-attribute-item-required { + font-size: 10px; + color: #aaa; +} + +.event-attribute-row button { + margin-left: 24px; +} + +.attribute-constraint-row .form-error { + position: static; + padding: 0 4px; +} + +.attribute-constraint-name { + font-size: 12px; + display: inline-block; + text-transform: uppercase; + width: 145px; +} + +.attribute-constraint-data, +#addAttributeConstraintValue { + width: 251px !important; +} + +#addAttributeConstraintName { + width: 145px; +} + +#addEventAttribute { + width: 375px !important; +} + +#addEventAttributeButton, +.remove-event-attribute-button { + cursor: pointer; +} http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/7ccfa3aa/log4j-catalog/log4j-catalog-editor/src/main/resources/static/images/ajax-loader.gif ---------------------------------------------------------------------- diff --git a/log4j-catalog/log4j-catalog-editor/src/main/resources/static/images/ajax-loader.gif b/log4j-catalog/log4j-catalog-editor/src/main/resources/static/images/ajax-loader.gif new file mode 100644 index 0000000..bd6dd97 Binary files /dev/null and b/log4j-catalog/log4j-catalog-editor/src/main/resources/static/images/ajax-loader.gif differ http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/7ccfa3aa/log4j-catalog/log4j-catalog-editor/src/main/resources/static/images/attributes.png ---------------------------------------------------------------------- diff --git a/log4j-catalog/log4j-catalog-editor/src/main/resources/static/images/attributes.png b/log4j-catalog/log4j-catalog-editor/src/main/resources/static/images/attributes.png new file mode 100644 index 0000000..7957193 Binary files /dev/null and b/log4j-catalog/log4j-catalog-editor/src/main/resources/static/images/attributes.png differ http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/7ccfa3aa/log4j-catalog/log4j-catalog-editor/src/main/resources/static/images/constraint.png ---------------------------------------------------------------------- diff --git a/log4j-catalog/log4j-catalog-editor/src/main/resources/static/images/constraint.png b/log4j-catalog/log4j-catalog-editor/src/main/resources/static/images/constraint.png new file mode 100644 index 0000000..7604751 Binary files /dev/null and b/log4j-catalog/log4j-catalog-editor/src/main/resources/static/images/constraint.png differ http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/7ccfa3aa/log4j-catalog/log4j-catalog-editor/src/main/resources/static/js/app.js ---------------------------------------------------------------------- diff --git a/log4j-catalog/log4j-catalog-editor/src/main/resources/static/js/app.js b/log4j-catalog/log4j-catalog-editor/src/main/resources/static/js/app.js new file mode 100644 index 0000000..1e906d3 --- /dev/null +++ b/log4j-catalog/log4j-catalog-editor/src/main/resources/static/js/app.js @@ -0,0 +1,81 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache license, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the license for the specific language governing permissions and + * limitations under the license. + */ +$(document).ready(function () { + // Clear localStorage + localStorage.clear(); + + $('#save-all').click(function(e) { + e.preventDefault(); + saveAllChanges(); + }); +}); + +// Modal action handlers +function closeLog4jModal() { + $('.log4j-catalog-modal').remove(); +} + +function log4jSubmitHandler(submitHandler) { + submitHandler(); + closeLog4jModal(); +} + +function showLog4JModal(title, content) { + closeLog4jModal(); + var modalContent = ' \ + <div class="log4j-catalog-modal"> \ + <div class="log4j-catalog-title">' + title + '</div> \ + <div class="log4j-catalog-content">' + content + '</div> \ + </div>'; + + $('body').append(modalContent); + window.scrollTo(0, 0); +} + +function showLoadingAnimation() { + $('.log4j-catalog-form').prepend('<div class="form-processing"><div class="gif"></div></div>'); +} + +function validateFormContent() { + var errors = 0; + $('.form-error').remove(); + $('.required').each(function() { + if (!$(this).val()) { + errors++; + $('<span class="form-error">Required.</span>').insertAfter($(this)); + } + }); + if (errors) return false; + return true; +} + +function saveAllChanges() { + $.ajax({ + type: 'POST', + contentType: 'application/json', + url: 'catalog', + data: null, + success:function(response) { + if (response.Result === 'OK') { + $('.log4j-table-container"').jtable('load'); + } + }, + error:function(jqXhr, textStatus, errorThrown) { + console.error(textStatus + ' - ' + errorThrown); + } + }); +} http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/7ccfa3aa/log4j-catalog/log4j-catalog-editor/src/main/resources/static/js/attributes.js ---------------------------------------------------------------------- diff --git a/log4j-catalog/log4j-catalog-editor/src/main/resources/static/js/attributes.js b/log4j-catalog/log4j-catalog-editor/src/main/resources/static/js/attributes.js new file mode 100644 index 0000000..bb71036 --- /dev/null +++ b/log4j-catalog/log4j-catalog-editor/src/main/resources/static/js/attributes.js @@ -0,0 +1,364 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache license, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the license for the specific language governing permissions and + * limitations under the license. + */ +$(document).ready(function () { + $('#AttributesTableContainer').jtable({ + title: 'Table of Attributes', + paging: true, //Enable paging + pageSize: 25, //Set page size (default: 25) + sorting: true, //Enable sorting + defaultSorting: 'Name ASC', //Set default sorting + actions: { + listAction: 'api/attributes/list', + }, + toolbar: { + items: [{ + icon: 'js/jtable.2.4.0/themes/metro/add.png', + text: 'Add new record', + click: () => { addEditAttributeItem() } + }] + }, + fields: { + id: { + key: true, + list: false + }, + name: { + title: 'Name', + width: '15%' + }, + displayName: { + title: 'Display Name', + width: '15%' + }, + description: { + title: 'Description', + width: '25%' + }, + dataType: { + title: 'Data Type', + width: '5%' + }, + indexed: { + title: 'Indexed', + width: '5%', + display: function (attributeData) { + return attributeData.record.indexed ? 'true' : 'false'; + } + }, + sortable: { + title: 'Sortable', + width: '5%', + display: function (attributeData) { + return attributeData.record.sortable ? 'true' : 'false'; + } + }, + required: { + title: 'Required', + width: '5%', + display: function (attributeData) { + return attributeData.record.required ? 'true' : 'false'; + } + }, + requestContext: { + title: 'RequestContext', + width: '3%', + display: function (attributeData) { + return attributeData.record.requestContext ? 'true' : 'false'; + } + }, + constraints: { + title: 'Constraints', + width: '16%', + sorting: false, + edit: false, + create: false, + display: function (attributeData) { + var constraintList = ''; + if (typeof(attributeData.record.constraints) != 'undefined' && attributeData.record.constraints != null) { + constraintList = attributeData.record.constraints.map(function (elem) { + return elem.constraintType.name + '("' + elem.value + '")' + }).join(' | '); + } + //Create a div that will be used to view associated attributes + var $divConstraints = $('<div class="constraints">' + constraintList + '</div>'); + return $divConstraints; + } + }, + edit: { + title: '', + width: '2%', + display: function (attributeData) { + // Store attribute item data in localStorage + var attributeDataItem = JSON.stringify(attributeData.record); + localStorage.setItem('attributeItem' + attributeData.record.id,attributeDataItem); + return '<img class="log4J-action-icon" src="js/jtable.2.4.0/themes/metro/edit.png" onClick="addEditAttributeItem(' + attributeData.record.id + ')" />'; + } + }, + delete: { + title: '', + width: '2%', + display: function (attributeData) { + return '<img class="log4J-action-icon" src="js/jtable.2.4.0/themes/metro/delete.png" onClick="deleteAttributeItem(' + attributeData.record.id + ')" />'; + } + } + } + }); + $.ajax({ + type: 'GET', + url: 'api/constraints/types', + success:function(response){ + localStorage.setItem('allConstraints', response); + }, + error:function(jqXhr, textStatus, errorThrown){ + console.error(textStatus + ' - ' + errorThrown); + } + }); + //Load attributes list from server + $('#AttributesTableContainer').jtable('load'); +}); + +function deleteAttributeItem(attributeId) { + var response = confirm('Are you sure you want to delete this attribute?'); + if (response) { + var postData = {}; + postData['id'] = attributeId + $.ajax({ + type: 'POST', + contentType: 'application/json', + url: 'api/attributes/delete', + data: JSON.stringify(postData), + success:function(response) { + if (response.Result === 'OK') { + $('#AttributesTableContainer').jtable('load'); + } + }, + error:function(jqXhr, textStatus, errorThrown) { + console.error(textStatus + ' - ' + errorThrown); + } + }); + } +} + +function addEditattributeItemHandler() { + var validForm = validateFormContent(); + if (validForm) { + showLoadingAnimation(); + var postUrl = 'api/attributes/create'; + var postData = {}; + var attributeConstraints = []; + postData['name'] = $('#attributeName').val(); + postData['displayName'] = $('#attributeDisplayName').val(); + postData['description'] = $('#attributeDescription').val(); + postData['dataType'] = $('#attributeDataType').val(); + postData['indexed'] = $('#attributeIndexed').val(); + postData['sortable'] = $('#attributeSortable').val(); + postData['required'] = $('#attributeRequired').val(); + postData['requestContext'] = $('#attributeRequestContext').val(); + $('#attributeConstraints .attribute-constraint-row').each(function() { + var attributeConstraintItem = { + constraintType: { name: $(this).find('.attribute-constraint-name').text().toLowerCase() }, + value: $(this).find('input')[0].value, + }; + attributeConstraints.push(attributeConstraintItem); + }); + postData['constraints'] = attributeConstraints; + if ($('#attributeId').val()) { + postUrl = 'api/attributes/update'; + postData['id'] = $('#attributeId').val(); + } + $.ajax({ + type: 'POST', + contentType: 'application/json', + url: postUrl, + data: JSON.stringify(postData), + success:function(response) { + if (response.Result === 'OK') { + $('#AttributesTableContainer').jtable('load'); + closeLog4jModal(); + } + }, + error:function(jqXhr, textStatus, errorThrown) { + console.error(textStatus + ' - ' + errorThrown); + } + }); + } +} + +function addEditAttributeItem(attributeId) { + var hiddenIdField = ''; + var attributeData = {}; + if (attributeId) { + hiddenIdField = '<input type="hidden" id="attributeId" name="id" value="' + attributeId + '" />'; + } else { + attributeId = 'tempEventData'; + var tempEventData = { + id: attributeId, + constraints: [], + } + localStorage.setItem('attributeItem' + attributeId, JSON.stringify(tempEventData)); + } + attributeFormContent = ' \ + <form id="add-edit-attribute-form" class="log4j-catalog-form" method="post"> \ + ' + hiddenIdField + ' \ + <p> \ + <label>Name</label> \ + <input type="text" id="attributeName" name="name" class="required" /> \ + </p> \ + <p> \ + <label>Display Name</label> \ + <input type="text" id="attributeDisplayName" name="displayName" class="required" /> \ + </p> \ + <p> \ + <label>Description</label> \ + <input type="text" id="attributeDescription" name="description" class="required" /> \ + </p> \ + <p> \ + <label>Data Type</label> \ + <select id="attributeDataType" name="indexed" class="required"> \ + </select> \ + </p> \ + <p> \ + <label>Indexed</label> \ + <select id="attributeIndexed" name="indexed" class="required"> \ + <option value="false">false</option> \ + <option value="true">true</option> \ + </select> \ + </p> \ + <p> \ + <label>Sortable</label> \ + <select id="attributeSortable" name="sortable" class="required"> \ + <option value="false">false</option> \ + <option value="true">true</option> \ + </select> \ + </p> \ + <p> \ + <label>Required</label> \ + <select id="attributeRequired" name="required" class="required"> \ + <option value="false">false</option> \ + <option value="true">true</option> \ + </select> \ + </p> \ + <p> \ + <label>Request Context</label> \ + <select id="attributeRequestContext" name="requestContext" class="required"> \ + <option value="false">false</option> \ + <option value="true">true</option> \ + </select> \ + </p> \ + <p> \ + <label>Assigned Constraints</label> \ + <span id="attributeConstraints"></span> \ + </p> \ + <p> \ + <label>Add Constraint</label> \ + <span> \ + <select name="addAttributeConstraintName" id="addAttributeConstraintName"> \ + <option value="">loading...</option> \ + </select> \ + <input type="text" name="addAttributeConstraintValue" id="addAttributeConstraintValue" /> \ + <button id="addAttributeConstraintButton">+</button> \ + </span> \ + </p> \ + </form> \ + <div class="log4j-catalog-button-row"> \ + <button class="log4j-catalog-button" onclick="closeLog4jModal()">Cancel</button>\ + <button class="log4j-catalog-button" onclick="addEditattributeItemHandler()">Save</button> \ + </div> \ + '; + showLog4JModal('Add / Edit Attribute Item', attributeFormContent); + var dataTypes = ['STRING', 'BIG_DECIMAL', 'DOUBLE', 'FLOAT', 'INT', 'LONG', 'BOOLEAN', 'LIST', 'MAP']; + $.each(dataTypes.sort(), function(index, value) { + $('#attributeDataType').append('<option value="' + value + '">' + value + '</option>'); + }); + if (localStorage.getItem('attributeItem' + attributeId)) { + attributeData = JSON.parse(localStorage.getItem('attributeItem' + attributeId)); + $('#attributeName').val(attributeData.name); + $('#attributeDisplayName').val(attributeData.displayName); + $('#attributeDescription').val(attributeData.description); + $('#attributeDataType option[value="' + attributeData.dataType + '"]').attr('selected', 'selected'); + $('#attributeIndexed option[value="' + attributeData.indexed + '"]').attr('selected', 'selected'); + $('#attributeSortable option[value="' + attributeData.sortable + '"]').attr('selected', 'selected'); + $('#attributeRequired option[value="' + attributeData.required + '"]').attr('selected', 'selected'); + $('#attributeRequestContext option[value="' + attributeData.requestContext + '"]').attr('selected', 'selected'); + } + populateAttributeConstraints(attributeData.constraints, attributeId); +} + +function populateAttributeConstraints(assignedConstraints, attributeId) { + var selectedConstraints = []; + $('#attributeConstraints').children().remove(); + if (attributeId && assignedConstraints) { + assignedConstraints.map((item) => { + selectedConstraints.push(item.constraintType.name); + $('#attributeConstraints').append(' \ + <span class="attribute-constraint-row"> \ + <span class="attribute-constraint-name">' + item.constraintType.name + '</span> \ + <input type="text" name="constraints[]" class="attribute-constraint-data required" value="' + item.value + '" /> \ + <button class="remove-attribute-constraint-button" alt="' + attributeId + '" rel="' + item.constraintType.name + '">-</button> \ + </span> \ + '); + }); + } + function checkPendingRequest() { + if ($.active > 0) { + window.setTimeout(checkPendingRequest, 1000); + } else { + var allConstraints = localStorage.getItem('allConstraints').split(','); + allConstraints.sort(); + $('#addAttributeConstraintName option').remove(); + allConstraints.map((item) => { + if (!selectedConstraints.includes(item)) { + $('#addAttributeConstraintName').append(' \ + <option value="' + item + '">' + item.toUpperCase() + '</option> \ + '); + } + }); + } + } + checkPendingRequest(); + assignAttributeConstraintListeners(attributeId); +} + +function assignAttributeConstraintListeners(attributeId) { + $('#addAttributeConstraintButton, .remove-attribute-constraint-button').unbind(); + $('#addAttributeConstraintButton').click(function(e) { + e.preventDefault(); + var allConstraints = localStorage.getItem('allConstraints').split(','); + attributeData = JSON.parse(localStorage.getItem('attributeItem' + attributeId)); + if (typeof(attributeData.constraints) == 'undefined' || attributeData.constraints == null) { + attributeData.constraints = []; + } + attributeData.constraints.push({ + constraintType: { name: $('#addAttributeConstraintName').val() }, + value: $('#addAttributeConstraintValue').val() + }); + localStorage.setItem('attributeItem' + attributeId, JSON.stringify(attributeData)); + $('#addAttributeConstraintValue').val(''); + populateAttributeConstraints(attributeData.constraints, attributeId); + }); + $('.remove-attribute-constraint-button').click(function(e) { + e.preventDefault(); + var allConstraints = localStorage.getItem('allConstraints').split(','); + attributeData = JSON.parse(localStorage.getItem('attributeItem' + attributeId)); + var newConstraints = attributeData.constraints.filter((obj) => { + return obj.constraintType.name !== $(this).attr('rel'); + }); + attributeData['constraints'] = newConstraints; + localStorage.setItem('attributeItem' + attributeId, JSON.stringify(attributeData)); + populateAttributeConstraints(attributeData.constraints, attributeId); + }); +} http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/7ccfa3aa/log4j-catalog/log4j-catalog-editor/src/main/resources/static/js/categories.js ---------------------------------------------------------------------- diff --git a/log4j-catalog/log4j-catalog-editor/src/main/resources/static/js/categories.js b/log4j-catalog/log4j-catalog-editor/src/main/resources/static/js/categories.js new file mode 100644 index 0000000..2860099 --- /dev/null +++ b/log4j-catalog/log4j-catalog-editor/src/main/resources/static/js/categories.js @@ -0,0 +1,257 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache license, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the license for the specific language governing permissions and + * limitations under the license. + */ +$(document).ready(function () { + $('#CategoriesTableContainer').jtable({ + title: 'Table of categories', + paging: true, //Enable paging + pageSize: 25, //Set page size (default: 25) + sorting: true, //Enable sorting + defaultSorting: 'Name ASC', //Set default sorting + actions: { + listAction: 'api/categories/list', + }, + toolbar: { + items: [{ + icon: 'js/jtable.2.4.0/themes/metro/add.png', + text: 'Add new record', + click: () => { addEditCategoryItem() } + }] + }, + fields: { + id: { + key: true, + list: false + }, + name: { + title: 'Name', + width: '25%' + }, + displayName: { + title: 'Display Name', + width: '25%' + }, + description: { + title: 'Description', + width: '50%' + }, + edit: { + title: '', + width: '25', + display: function (categoryData) { + // Store event item data in localStorage + var categoryDataItem = JSON.stringify(categoryData.record); + localStorage.setItem('categoryItem' + categoryData.record.id, categoryDataItem); + return '<img class="log4J-action-icon" src="js/jtable.2.4.0/themes/metro/edit.png" onClick="addEditCategoryItem(' + categoryData.record.id + ')" />'; + } + }, + delete: { + title: '', + width: '25', + display: function (categoryData) { + return '<img class="log4J-action-icon" src="js/jtable.2.4.0/themes/metro/delete.png" onClick="deleteCategoryItem(' + categoryData.record.id + ')" />'; + } + } + } + }); + $.ajax({ + type: 'POST', + url: 'api/events/list', + success:function(response){ + if (response.Result === 'OK') { + var allEvents = response.Records.map((item) => { + return item.name; + }); + localStorage.setItem('allEvents', allEvents); + } + }, + error:function(jqXhr, textStatus, errorThrown){ + console.error(textStatus + ' - ' + errorThrown); + } + }); + //Load categories list from server + $('#CategoriesTableContainer').jtable('load'); +}); + +function deleteCategoryItem(categoryId) { + var response = confirm('Are you sure you want to delete this category?'); + if (response) { + var postData = {}; + postData['id'] = categoryId; + $.ajax({ + type: 'POST', + contentType: 'application/json', + url: 'api/categories/delete', + data: JSON.stringify(postData), + success:function(response) { + if (response.Result === 'OK') { + $('#CategoriesTableContainer').jtable('load'); + } + }, + error:function(jqXhr, textStatus, errorThrown) { + console.error(textStatus + ' - ' + errorThrown); + } + }); + } +} + +function addEditCategoryItemHandler() { + var validForm = validateFormContent(); + if (validForm) { + showLoadingAnimation(); + var postUrl = 'api/categories/create'; + var postData = {}; + var categoryEvents = []; + postData['name'] = $('#categoryName').val(); + postData['displayName'] = $('#categoryDisplayName').val(); + postData['description'] = $('#categoryDescription').val(); + $('#categoryEvents .category-event-row').each(function() { + categoryEvents.push($(this).find('input')[0].value); + }); + postData['events'] = categoryEvents; + if ($('#categoryId').val()) { + postUrl = 'api/categories/update'; + postData['id'] = $('#categoryId').val(); + } + $.ajax({ + type: 'POST', + contentType: 'application/json', + url: postUrl, + data: JSON.stringify(postData), + success:function(response) { + if (response.Result === 'OK') { + $('#CategoriesTableContainer').jtable('load'); + closeLog4jModal(); + } + }, + error:function(jqXhr, textStatus, errorThrown) { + console.error(textStatus + ' - ' + errorThrown); + } + }); + } +} + +function addEditCategoryItem(categoryId) { + var hiddenIdField = ''; + var categoryData = {}; + if (categoryId) { + hiddenIdField = '<input type="hidden" id="categoryId" name="id" value="' + categoryId + '" />'; + } else { + categoryId = 'tempCategoryData'; + var tempCategoryData = { + id: categoryId, + events: [], + } + localStorage.setItem('categoryItem' + categoryId, JSON.stringify(tempCategoryData)); + } + categoryFormContent = ' \ + <form id="add-edit-category-form" class="log4j-catalog-form" method="post"> \ + ' + hiddenIdField + ' \ + <p> \ + <label>Name</label> \ + <input type="text" id="categoryName" name="name" class="required" /> \ + </p> \ + <p> \ + <label>Display Name</label> \ + <input type="text" id="categoryDisplayName" name="displayName" class="required" /> \ + </p> \ + <p> \ + <label>Description</label> \ + <input type="text" id="categoryDescription" name="description" class="required" /> \ + </p> \ + <p> \ + <label>Assigned Events</label> \ + <span id="categoryEvents"></span> \ + </p> \ + <p> \ + <label>Add Event</label> \ + <span> \ + <select name="addCategoryEvent" id="addCategoryEvent"> \ + <option value="">loading...</option> \ + </select> \ + <button id="addCategoryEventButton">+</button> \ + </span> \ + </p> \ + </form> \ + <div class="log4j-catalog-button-row"> \ + <button class="log4j-catalog-button" onclick="closeLog4jModal()">Cancel</button>\ + <button class="log4j-catalog-button" onclick="addEditCategoryItemHandler()">Save</button> \ + </div> \ + '; + showLog4JModal('Add / Edit Category Item', categoryFormContent); + if (localStorage.getItem('categoryItem' + categoryId)) { + categoryData = JSON.parse(localStorage.getItem('categoryItem' + categoryId)); + $('#categoryName').val(categoryData.name); + $('#categoryDisplayName').val(categoryData.displayName); + $('#categoryDescription').val(categoryData.description); + } + populateCategoryEvents(categoryData.events, categoryId); +} + +function populateCategoryEvents(assignedEvents, categoryId) { + var selectedEvents = []; + $('#categoryEvents').children().remove(); + if (categoryId) { + assignedEvents.map((item) => { + selectedEvents.push(item); + $('#categoryEvents').append(' \ + <span class="category-event-row"> \ + <input type="text" name="events[]" value="' + item + '" disabled /> \ + <button class="remove-category-event-button" alt="' + categoryId + '" rel="' + item + '">-</button> \ + </span> \ + '); + }); + } + function checkPendingRequest() { + if ($.active > 0) { + window.setTimeout(checkPendingRequest, 1000); + } else { + var allEvents = localStorage.getItem('allEvents').split(','); + allEvents.sort(); + $('#addCategoryEvent option').remove(); + allEvents.map((item) => { + if (!selectedEvents.includes(item)) { + $('#addCategoryEvent').append(' \ + <option value="' + item + '">' + item + '</option> \ + '); + } + }); + } + }; + checkPendingRequest(); + assignCategoryEventListeners(categoryId); +} + +function assignCategoryEventListeners(categoryId) { + $('#addCategoryEventButton, .remove-category-event-button').unbind(); + $('#addCategoryEventButton').click(function(e) { + e.preventDefault(); + var allEvents = localStorage.getItem('allEvents').split(','); + var categoryData = JSON.parse(localStorage.getItem('categoryItem' + categoryId)); + categoryData.events.push($('#addCategoryEvent').val()); + localStorage.setItem('categoryItem' + categoryId, JSON.stringify(categoryData)); + populateCategoryEvents(categoryData.events, categoryId); + }); + + $('.remove-category-event-button').click(function(e) { + e.preventDefault(); + var allEvents = localStorage.getItem('allEvents').split(','); + var categoryData = JSON.parse(localStorage.getItem('categoryItem' + categoryId)); + categoryData.events.pop($(this).attr('rel')); + localStorage.setItem('categoryItem' + categoryId, JSON.stringify(categoryData)); + populateCategoryEvents(categoryData.events, categoryId); + }); +} http://git-wip-us.apache.org/repos/asf/logging-log4j-audit/blob/7ccfa3aa/log4j-catalog/log4j-catalog-editor/src/main/resources/static/js/events.js ---------------------------------------------------------------------- diff --git a/log4j-catalog/log4j-catalog-editor/src/main/resources/static/js/events.js b/log4j-catalog/log4j-catalog-editor/src/main/resources/static/js/events.js new file mode 100644 index 0000000..9f0ec01 --- /dev/null +++ b/log4j-catalog/log4j-catalog-editor/src/main/resources/static/js/events.js @@ -0,0 +1,291 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache license, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the license for the specific language governing permissions and + * limitations under the license. + */ +$(document).ready(function () { + $('#EventsTableContainer').jtable({ + title: 'Table of events', + paging: true, //Enable paging + pageSize: 25, //Set page size (default: 25) + sorting: true, //Enable sorting + defaultSorting: 'Name ASC', //Set default sorting + actions: { + listAction: 'api/events/list', + }, + toolbar: { + items: [{ + icon: 'js/jtable.2.4.0/themes/metro/add.png', + text: 'Add new record', + click: () => { addEditEventItem() } + }] + }, + fields: { + id: { + key: true, + list: false + }, + name: { + title: 'Name', + width: '15%' + }, + displayName: { + title: 'Display Name', + width: '15%' + }, + description: { + title: 'Description', + width: '30%' + }, + attributes: { + title: 'Assigned Attributes', + width: 'auto', + sorting: false, + edit: false, + create: false, + display: function (eventData) { + var attributeList = eventData.record.attributes.map(function(elem){return elem.name + (elem.required ? ' (required)' : '')}).join(' | '); + //Create a div that will be used to view associated attributes + var $divAttributes = $('<div class="event-attributes">' + attributeList + '</div>'); + return $divAttributes; + } + }, + edit: { + title: '', + width: '25', + display: function (eventData) { + // Store event item data in localStorage + var eventDataItem = JSON.stringify(eventData.record); + localStorage.setItem('eventItem' + eventData.record.id, eventDataItem); + return '<img class="log4J-action-icon" src="js/jtable.2.4.0/themes/metro/edit.png" onClick="addEditEventItem(' + eventData.record.id + ')" />'; + } + }, + delete: { + title: '', + width: '25', + display: function (eventData) { + return '<img class="log4J-action-icon" src="js/jtable.2.4.0/themes/metro/delete.png" onClick="deleteEventItem(' + eventData.record.id + ')" />'; + } + } + } + }); + $.ajax({ + type: 'GET', + url: 'api/attributes', + success:function(response){ + if (response.result === 'OK') { + localStorage.setItem('allAttributes', response.data); + } + }, + error:function(jqXhr, textStatus, errorThrown){ + console.error(textStatus + ' - ' + errorThrown); + } + }); + $('#EventsTableContainer').jtable('load'); +}); + +function deleteEventItem(eventId) { + var response = confirm('Are you sure you want to delete this event?'); + if (response) { + var postData = {}; + postData['id'] = eventId; + $.ajax({ + type: 'POST', + contentType: 'application/json', + url: 'api/events/delete', + data: JSON.stringify(postData), + success:function(response) { + if (response.Result === 'OK') { + $('#EventsTableContainer').jtable('load'); + } + }, + error:function(jqXhr, textStatus, errorThrown) { + console.error(textStatus + ' - ' + errorThrown); + } + }); + } +} + +function addEditEventItemHandler() { + var validForm = validateFormContent(); + if (validForm) { + showLoadingAnimation(); + var postUrl = 'api/events/create'; + var postData = {}; + var eventAttributes = []; + postData['name'] = $('#eventName').val(); + postData['displayName'] = $('#eventDisplayName').val(); + postData['description'] = $('#eventDescription').val(); + $('#eventAttributes .event-attribute-row').each(function() { + var required = null; + $(this).children('[type="checkbox"]').each(function(i, e) { + if ($(e).prop('checked')) { + required = ($(e).attr('rel') == 'true'); + } + }); + var eventAttributeItem = { + name: $(this).find('input')[0].value, + required: required, + }; + eventAttributes.push(eventAttributeItem); + }); + postData['attributes'] = eventAttributes; + if ($('#eventId').val()) { + postUrl = 'api/events/update'; + postData['id'] = $('#eventId').val(); + } + $.ajax({ + type: 'POST', + contentType: 'application/json', + url: postUrl, + data: JSON.stringify(postData), + success:function(response) { + if (response.Result === 'OK') { + $('#EventsTableContainer').jtable('load'); + closeLog4jModal(); + } + }, + error:function(jqXhr, textStatus, errorThrown) { + console.error(textStatus + ' - ' + errorThrown); + } + }); + } +} + +function addEditEventItem(eventId) { + var hiddenIdField = ''; + var eventData = {}; + if (eventId) { + hiddenIdField = '<input type="hidden" id="eventId" name="id" value="' + eventId + '" />'; + } else { + eventId = 'tempEventData'; + var tempEventData = { + id: eventId, + attributes: [], + } + localStorage.setItem('eventItem' + eventId, JSON.stringify(tempEventData)); + } + eventFormContent = ' \ + <form id="add-edit-event-form" class="log4j-catalog-form" method="post"> \ + ' + hiddenIdField + ' \ + <p> \ + <label>Name</label> \ + <input type="text" id="eventName" name="name" class="required" /> \ + </p> \ + <p> \ + <label>Display Name</label> \ + <input type="text" id="eventDisplayName" name="displayName" class="required" /> \ + </p> \ + <p> \ + <label>Description</label> \ + <input type="text" id="eventDescription" name="description" class="required" /> \ + </p> \ + <p> \ + <label>Assigned Attributes</label> \ + <span id="eventAttributes"></span> \ + </p> \ + <p> \ + <label>Add Attribute</label> \ + <span> \ + <select name="addEventAttribute" id="addEventAttribute"> \ + <option value="">--</option> \ + </select> \ + <button id="addEventAttributeButton">+</button> \ + </span> \ + </p> \ + </form> \ + <div class="log4j-catalog-button-row"> \ + <button class="log4j-catalog-button" onclick="closeLog4jModal()">Cancel</button>\ + <button class="log4j-catalog-button" onclick="addEditEventItemHandler()">Save</button> \ + </div> \ + '; + showLog4JModal('Add / Edit Event Item', eventFormContent); + if (localStorage.getItem('eventItem' + eventId)) { + eventData = JSON.parse(localStorage.getItem('eventItem' + eventId)); + $('#eventName').val(eventData.name); + $('#eventDisplayName').val(eventData.displayName); + $('#eventDescription').val(eventData.description); + } + populateEventAttributes(eventData.attributes, eventId); +} + +function populateEventAttributes(assignedAttributes, eventId) { + var selectedAttributes = []; + var allAttributes = localStorage.getItem('allAttributes').split(','); + $('#eventAttributes').children().remove(); + if (eventId) { + assignedAttributes.map((item) => { + selectedAttributes.push(item.name); + var attributeRequiredTrue = ''; + var attributeRequiredFalse = ''; + var attributeRequired = item.required; + if (attributeRequired === true) { + attributeRequiredTrue = 'checked'; + } else if (attributeRequired === false) { + attributeRequiredFalse = 'checked'; + } + $('#eventAttributes').append(' \ + <span class="event-attribute-row"> \ + <input type="text" name="attributes[]" value="' + item.name + '" disabled /> \ + <input type="checkbox" name="attribute-required_' + item.name + '" rel="true" ' + attributeRequiredTrue + ' /> \ + <span class="event-attribute-item-required">YES</span> \ + <input type="checkbox" name="attribute-required_' + item.name + '" rel="false" ' + attributeRequiredFalse + ' /> \ + <span class="event-attribute-item-required">NO</span> \ + <button class="remove-event-attribute-button" alt="' + eventId + '" rel="' + item.name + '">-</button> \ + </span> \ + '); + }); + } + allAttributes.sort(); + $('#addEventAttribute option').remove(); + allAttributes.map((item) => { + if (!selectedAttributes.includes(item)) { + $('#addEventAttribute').append(' \ + <option value="' + item + '">' + item + '</option> \ + '); + } + }); + assignEventAttributeListeners(eventId); +} + +function assignEventAttributeListeners(eventId) { + $('#addEventAttributeButton, .remove-event-attribute-button').unbind(); + $('#addEventAttributeButton').click(function(e) { + e.preventDefault(); + var allAttributes = localStorage.getItem('allAttributes').split(','); + var eventData = JSON.parse(localStorage.getItem('eventItem' + eventId)); + eventData.attributes.push({name: $('#addEventAttribute').val(), required: false}); + localStorage.setItem('eventItem' + eventId, JSON.stringify(eventData)); + populateEventAttributes(eventData.attributes, eventId); + }); + + $('.remove-event-attribute-button').click(function(e) { + e.preventDefault(); + var allAttributes = localStorage.getItem('allAttributes').split(','); + var eventData = JSON.parse(localStorage.getItem('eventItem' + eventId)); + var newAttributes = eventData.attributes.filter((obj) => { + return obj.name !== $(this).attr('rel'); + }); + eventData['attributes'] = newAttributes; + localStorage.setItem('eventItem' + eventId, JSON.stringify(eventData)); + populateEventAttributes(eventData.attributes, eventId); + }); + + $('input[name^="attribute-required_"]').change(function() { + if ($(this).is(":checked")) { + $(this).siblings('input').prop('checked', false); + $(this).prop('checked', true); + } + }); +}