From 69397e750ec45da28d11744f4b035eb20abe76a2 Mon Sep 17 00:00:00 2001 From: Mike Hugo Date: Fri, 30 Mar 2012 07:11:44 -0500 Subject: [PATCH] get and metrics projects --- BuildingQuality/sample-code/gebish/.classpath | 14 + BuildingQuality/sample-code/gebish/.gitignore | 15 + BuildingQuality/sample-code/gebish/.project | 19 + .../sample-code/gebish/application.properties | 6 + BuildingQuality/sample-code/gebish/gebish.ipr | 220 ++++++ .../conf/ApplicationResources.groovy | 5 + .../gebish/grails-app/conf/BootStrap.groovy | 7 + .../gebish/grails-app/conf/BuildConfig.groovy | 66 ++ .../gebish/grails-app/conf/Config.groovy | 93 +++ .../gebish/grails-app/conf/DataSource.groovy | 43 ++ .../gebish/grails-app/conf/UrlMappings.groovy | 13 + .../grails-app/conf/spring/resources.groovy | 3 + .../gebish/PersonController.groovy | 103 +++ .../grails-app/domain/gebish/Person.groovy | 10 + .../grails-app/i18n/messages.properties | 55 ++ .../grails-app/i18n/messages_cs_CZ.properties | 55 ++ .../grails-app/i18n/messages_da.properties | 56 ++ .../grails-app/i18n/messages_de.properties | 55 ++ .../grails-app/i18n/messages_es.properties | 55 ++ .../grails-app/i18n/messages_fr.properties | 19 + .../grails-app/i18n/messages_it.properties | 19 + .../grails-app/i18n/messages_ja.properties | 55 ++ .../grails-app/i18n/messages_nl.properties | 55 ++ .../grails-app/i18n/messages_pt_BR.properties | 59 ++ .../grails-app/i18n/messages_pt_PT.properties | 34 + .../grails-app/i18n/messages_ru.properties | 31 + .../grails-app/i18n/messages_sv.properties | 55 ++ .../grails-app/i18n/messages_th.properties | 55 ++ .../grails-app/i18n/messages_zh_CN.properties | 18 + .../gebish/grails-app/views/error.gsp | 11 + .../gebish/grails-app/views/index.gsp | 122 ++++ .../gebish/grails-app/views/layouts/main.gsp | 28 + .../gebish/grails-app/views/person/_form.gsp | 28 + .../gebish/grails-app/views/person/create.gsp | 39 + .../gebish/grails-app/views/person/edit.gsp | 43 ++ .../gebish/grails-app/views/person/list.gsp | 54 ++ .../gebish/grails-app/views/person/show.gsp | 63 ++ .../gebish/projectFilesBackup/gebish.ipr | 83 +++ .../gebish/test/functional/GebConfig.groovy | 43 ++ .../functional/geb/PersonCRUDTests.groovy | 49 ++ .../test/functional/pages/CreatePage.groovy | 15 + .../test/functional/pages/EditPage.groovy | 16 + .../test/functional/pages/ListPage.groovy | 29 + .../test/functional/pages/ScaffoldPage.groovy | 10 + .../test/functional/pages/ShowPage.groovy | 18 + .../web-app/WEB-INF/applicationContext.xml | 33 + .../gebish/web-app/WEB-INF/sitemesh.xml | 14 + .../gebish/web-app/WEB-INF/tld/c.tld | 572 +++++++++++++++ .../gebish/web-app/WEB-INF/tld/fmt.tld | 671 ++++++++++++++++++ .../gebish/web-app/WEB-INF/tld/grails.tld | 550 ++++++++++++++ .../gebish/web-app/WEB-INF/tld/spring.tld | 311 ++++++++ .../sample-code/gebish/web-app/css/errors.css | 109 +++ .../sample-code/gebish/web-app/css/main.css | 591 +++++++++++++++ .../sample-code/gebish/web-app/css/mobile.css | 82 +++ .../images/apple-touch-icon-retina.png | Bin 0 -> 14986 bytes .../web-app/images/apple-touch-icon.png | Bin 0 -> 5434 bytes .../gebish/web-app/images/favicon.ico | Bin 0 -> 10134 bytes .../gebish/web-app/images/grails_logo.jpg | Bin 0 -> 8065 bytes .../gebish/web-app/images/grails_logo.png | Bin 0 -> 10172 bytes .../gebish/web-app/images/leftnav_btm.png | Bin 0 -> 3859 bytes .../web-app/images/leftnav_midstretch.png | Bin 0 -> 2883 bytes .../gebish/web-app/images/leftnav_top.png | Bin 0 -> 3317 bytes .../web-app/images/skin/database_add.png | Bin 0 -> 658 bytes .../web-app/images/skin/database_delete.png | Bin 0 -> 659 bytes .../web-app/images/skin/database_edit.png | Bin 0 -> 767 bytes .../web-app/images/skin/database_save.png | Bin 0 -> 755 bytes .../web-app/images/skin/database_table.png | Bin 0 -> 726 bytes .../web-app/images/skin/exclamation.png | Bin 0 -> 701 bytes .../gebish/web-app/images/skin/house.png | Bin 0 -> 806 bytes .../web-app/images/skin/information.png | Bin 0 -> 778 bytes .../gebish/web-app/images/skin/shadow.jpg | Bin 0 -> 300 bytes .../gebish/web-app/images/skin/sorted_asc.gif | Bin 0 -> 835 bytes .../web-app/images/skin/sorted_desc.gif | Bin 0 -> 834 bytes .../gebish/web-app/images/spinner.gif | Bin 0 -> 2037 bytes .../gebish/web-app/images/springsource.png | Bin 0 -> 9109 bytes .../gebish/web-app/js/application.js | 9 + .../sample-code/metrics/.classpath | 14 + .../sample-code/metrics/.gitignore | 15 + BuildingQuality/sample-code/metrics/.project | 19 + .../metrics/application.properties | 9 + .../conf/ApplicationResources.groovy | 5 + .../metrics/grails-app/conf/BootStrap.groovy | 7 + .../grails-app/conf/BuildConfig.groovy | 51 ++ .../metrics/grails-app/conf/Config.groovy | 93 +++ .../metrics/grails-app/conf/DataSource.groovy | 43 ++ .../grails-app/conf/UrlMappings.groovy | 13 + .../grails-app/conf/spring/resources.groovy | 3 + .../controllers/metrics/BookController.groovy | 103 +++ .../grails-app/domain/metrics/Book.groovy | 7 + .../grails-app/i18n/messages.properties | 55 ++ .../grails-app/i18n/messages_cs_CZ.properties | 55 ++ .../grails-app/i18n/messages_da.properties | 56 ++ .../grails-app/i18n/messages_de.properties | 55 ++ .../grails-app/i18n/messages_es.properties | 55 ++ .../grails-app/i18n/messages_fr.properties | 19 + .../grails-app/i18n/messages_it.properties | 19 + .../grails-app/i18n/messages_ja.properties | 55 ++ .../grails-app/i18n/messages_nl.properties | 55 ++ .../grails-app/i18n/messages_pt_BR.properties | 59 ++ .../grails-app/i18n/messages_pt_PT.properties | 34 + .../grails-app/i18n/messages_ru.properties | 31 + .../grails-app/i18n/messages_sv.properties | 55 ++ .../grails-app/i18n/messages_th.properties | 55 ++ .../grails-app/i18n/messages_zh_CN.properties | 18 + .../metrics/grails-app/views/book/_form.gsp | 4 + .../metrics/grails-app/views/book/create.gsp | 39 + .../metrics/grails-app/views/book/edit.gsp | 43 ++ .../metrics/grails-app/views/book/list.gsp | 42 ++ .../metrics/grails-app/views/book/show.gsp | 36 + .../metrics/grails-app/views/error.gsp | 11 + .../metrics/grails-app/views/index.gsp | 122 ++++ .../metrics/grails-app/views/layouts/main.gsp | 28 + .../unit/metrics/BookControllerTests.groovy | 159 +++++ .../test/unit/metrics/BookTests.groovy | 17 + .../web-app/WEB-INF/applicationContext.xml | 33 + .../metrics/web-app/WEB-INF/sitemesh.xml | 14 + .../metrics/web-app/WEB-INF/tld/c.tld | 572 +++++++++++++++ .../metrics/web-app/WEB-INF/tld/fmt.tld | 671 ++++++++++++++++++ .../metrics/web-app/WEB-INF/tld/grails.tld | 550 ++++++++++++++ .../metrics/web-app/WEB-INF/tld/spring.tld | 311 ++++++++ .../metrics/web-app/css/errors.css | 109 +++ .../sample-code/metrics/web-app/css/main.css | 591 +++++++++++++++ .../metrics/web-app/css/mobile.css | 82 +++ .../images/apple-touch-icon-retina.png | Bin 0 -> 14986 bytes .../web-app/images/apple-touch-icon.png | Bin 0 -> 5434 bytes .../metrics/web-app/images/favicon.ico | Bin 0 -> 10134 bytes .../metrics/web-app/images/grails_logo.jpg | Bin 0 -> 8065 bytes .../metrics/web-app/images/grails_logo.png | Bin 0 -> 10172 bytes .../metrics/web-app/images/leftnav_btm.png | Bin 0 -> 3859 bytes .../web-app/images/leftnav_midstretch.png | Bin 0 -> 2883 bytes .../metrics/web-app/images/leftnav_top.png | Bin 0 -> 3317 bytes .../web-app/images/skin/database_add.png | Bin 0 -> 658 bytes .../web-app/images/skin/database_delete.png | Bin 0 -> 659 bytes .../web-app/images/skin/database_edit.png | Bin 0 -> 767 bytes .../web-app/images/skin/database_save.png | Bin 0 -> 755 bytes .../web-app/images/skin/database_table.png | Bin 0 -> 726 bytes .../web-app/images/skin/exclamation.png | Bin 0 -> 701 bytes .../metrics/web-app/images/skin/house.png | Bin 0 -> 806 bytes .../web-app/images/skin/information.png | Bin 0 -> 778 bytes .../metrics/web-app/images/skin/shadow.jpg | Bin 0 -> 300 bytes .../web-app/images/skin/sorted_asc.gif | Bin 0 -> 835 bytes .../web-app/images/skin/sorted_desc.gif | Bin 0 -> 834 bytes .../metrics/web-app/images/spinner.gif | Bin 0 -> 2037 bytes .../metrics/web-app/images/springsource.png | Bin 0 -> 9109 bytes .../metrics/web-app/js/application.js | 9 + 145 files changed, 9387 insertions(+) create mode 100644 BuildingQuality/sample-code/gebish/.classpath create mode 100644 BuildingQuality/sample-code/gebish/.gitignore create mode 100644 BuildingQuality/sample-code/gebish/.project create mode 100644 BuildingQuality/sample-code/gebish/application.properties create mode 100644 BuildingQuality/sample-code/gebish/gebish.ipr create mode 100644 BuildingQuality/sample-code/gebish/grails-app/conf/ApplicationResources.groovy create mode 100644 BuildingQuality/sample-code/gebish/grails-app/conf/BootStrap.groovy create mode 100644 BuildingQuality/sample-code/gebish/grails-app/conf/BuildConfig.groovy create mode 100644 BuildingQuality/sample-code/gebish/grails-app/conf/Config.groovy create mode 100644 BuildingQuality/sample-code/gebish/grails-app/conf/DataSource.groovy create mode 100644 BuildingQuality/sample-code/gebish/grails-app/conf/UrlMappings.groovy create mode 100644 BuildingQuality/sample-code/gebish/grails-app/conf/spring/resources.groovy create mode 100644 BuildingQuality/sample-code/gebish/grails-app/controllers/gebish/PersonController.groovy create mode 100644 BuildingQuality/sample-code/gebish/grails-app/domain/gebish/Person.groovy create mode 100644 BuildingQuality/sample-code/gebish/grails-app/i18n/messages.properties create mode 100644 BuildingQuality/sample-code/gebish/grails-app/i18n/messages_cs_CZ.properties create mode 100644 BuildingQuality/sample-code/gebish/grails-app/i18n/messages_da.properties create mode 100644 BuildingQuality/sample-code/gebish/grails-app/i18n/messages_de.properties create mode 100644 BuildingQuality/sample-code/gebish/grails-app/i18n/messages_es.properties create mode 100644 BuildingQuality/sample-code/gebish/grails-app/i18n/messages_fr.properties create mode 100644 BuildingQuality/sample-code/gebish/grails-app/i18n/messages_it.properties create mode 100644 BuildingQuality/sample-code/gebish/grails-app/i18n/messages_ja.properties create mode 100644 BuildingQuality/sample-code/gebish/grails-app/i18n/messages_nl.properties create mode 100644 BuildingQuality/sample-code/gebish/grails-app/i18n/messages_pt_BR.properties create mode 100644 BuildingQuality/sample-code/gebish/grails-app/i18n/messages_pt_PT.properties create mode 100644 BuildingQuality/sample-code/gebish/grails-app/i18n/messages_ru.properties create mode 100644 BuildingQuality/sample-code/gebish/grails-app/i18n/messages_sv.properties create mode 100644 BuildingQuality/sample-code/gebish/grails-app/i18n/messages_th.properties create mode 100644 BuildingQuality/sample-code/gebish/grails-app/i18n/messages_zh_CN.properties create mode 100644 BuildingQuality/sample-code/gebish/grails-app/views/error.gsp create mode 100644 BuildingQuality/sample-code/gebish/grails-app/views/index.gsp create mode 100644 BuildingQuality/sample-code/gebish/grails-app/views/layouts/main.gsp create mode 100644 BuildingQuality/sample-code/gebish/grails-app/views/person/_form.gsp create mode 100644 BuildingQuality/sample-code/gebish/grails-app/views/person/create.gsp create mode 100644 BuildingQuality/sample-code/gebish/grails-app/views/person/edit.gsp create mode 100644 BuildingQuality/sample-code/gebish/grails-app/views/person/list.gsp create mode 100644 BuildingQuality/sample-code/gebish/grails-app/views/person/show.gsp create mode 100644 BuildingQuality/sample-code/gebish/projectFilesBackup/gebish.ipr create mode 100644 BuildingQuality/sample-code/gebish/test/functional/GebConfig.groovy create mode 100644 BuildingQuality/sample-code/gebish/test/functional/geb/PersonCRUDTests.groovy create mode 100644 BuildingQuality/sample-code/gebish/test/functional/pages/CreatePage.groovy create mode 100644 BuildingQuality/sample-code/gebish/test/functional/pages/EditPage.groovy create mode 100644 BuildingQuality/sample-code/gebish/test/functional/pages/ListPage.groovy create mode 100644 BuildingQuality/sample-code/gebish/test/functional/pages/ScaffoldPage.groovy create mode 100644 BuildingQuality/sample-code/gebish/test/functional/pages/ShowPage.groovy create mode 100644 BuildingQuality/sample-code/gebish/web-app/WEB-INF/applicationContext.xml create mode 100644 BuildingQuality/sample-code/gebish/web-app/WEB-INF/sitemesh.xml create mode 100644 BuildingQuality/sample-code/gebish/web-app/WEB-INF/tld/c.tld create mode 100644 BuildingQuality/sample-code/gebish/web-app/WEB-INF/tld/fmt.tld create mode 100644 BuildingQuality/sample-code/gebish/web-app/WEB-INF/tld/grails.tld create mode 100644 BuildingQuality/sample-code/gebish/web-app/WEB-INF/tld/spring.tld create mode 100644 BuildingQuality/sample-code/gebish/web-app/css/errors.css create mode 100644 BuildingQuality/sample-code/gebish/web-app/css/main.css create mode 100644 BuildingQuality/sample-code/gebish/web-app/css/mobile.css create mode 100644 BuildingQuality/sample-code/gebish/web-app/images/apple-touch-icon-retina.png create mode 100644 BuildingQuality/sample-code/gebish/web-app/images/apple-touch-icon.png create mode 100644 BuildingQuality/sample-code/gebish/web-app/images/favicon.ico create mode 100644 BuildingQuality/sample-code/gebish/web-app/images/grails_logo.jpg create mode 100644 BuildingQuality/sample-code/gebish/web-app/images/grails_logo.png create mode 100644 BuildingQuality/sample-code/gebish/web-app/images/leftnav_btm.png create mode 100644 BuildingQuality/sample-code/gebish/web-app/images/leftnav_midstretch.png create mode 100644 BuildingQuality/sample-code/gebish/web-app/images/leftnav_top.png create mode 100644 BuildingQuality/sample-code/gebish/web-app/images/skin/database_add.png create mode 100644 BuildingQuality/sample-code/gebish/web-app/images/skin/database_delete.png create mode 100644 BuildingQuality/sample-code/gebish/web-app/images/skin/database_edit.png create mode 100644 BuildingQuality/sample-code/gebish/web-app/images/skin/database_save.png create mode 100644 BuildingQuality/sample-code/gebish/web-app/images/skin/database_table.png create mode 100644 BuildingQuality/sample-code/gebish/web-app/images/skin/exclamation.png create mode 100644 BuildingQuality/sample-code/gebish/web-app/images/skin/house.png create mode 100644 BuildingQuality/sample-code/gebish/web-app/images/skin/information.png create mode 100644 BuildingQuality/sample-code/gebish/web-app/images/skin/shadow.jpg create mode 100644 BuildingQuality/sample-code/gebish/web-app/images/skin/sorted_asc.gif create mode 100644 BuildingQuality/sample-code/gebish/web-app/images/skin/sorted_desc.gif create mode 100644 BuildingQuality/sample-code/gebish/web-app/images/spinner.gif create mode 100644 BuildingQuality/sample-code/gebish/web-app/images/springsource.png create mode 100644 BuildingQuality/sample-code/gebish/web-app/js/application.js create mode 100644 BuildingQuality/sample-code/metrics/.classpath create mode 100644 BuildingQuality/sample-code/metrics/.gitignore create mode 100644 BuildingQuality/sample-code/metrics/.project create mode 100644 BuildingQuality/sample-code/metrics/application.properties create mode 100644 BuildingQuality/sample-code/metrics/grails-app/conf/ApplicationResources.groovy create mode 100644 BuildingQuality/sample-code/metrics/grails-app/conf/BootStrap.groovy create mode 100644 BuildingQuality/sample-code/metrics/grails-app/conf/BuildConfig.groovy create mode 100644 BuildingQuality/sample-code/metrics/grails-app/conf/Config.groovy create mode 100644 BuildingQuality/sample-code/metrics/grails-app/conf/DataSource.groovy create mode 100644 BuildingQuality/sample-code/metrics/grails-app/conf/UrlMappings.groovy create mode 100644 BuildingQuality/sample-code/metrics/grails-app/conf/spring/resources.groovy create mode 100644 BuildingQuality/sample-code/metrics/grails-app/controllers/metrics/BookController.groovy create mode 100644 BuildingQuality/sample-code/metrics/grails-app/domain/metrics/Book.groovy create mode 100644 BuildingQuality/sample-code/metrics/grails-app/i18n/messages.properties create mode 100644 BuildingQuality/sample-code/metrics/grails-app/i18n/messages_cs_CZ.properties create mode 100644 BuildingQuality/sample-code/metrics/grails-app/i18n/messages_da.properties create mode 100644 BuildingQuality/sample-code/metrics/grails-app/i18n/messages_de.properties create mode 100644 BuildingQuality/sample-code/metrics/grails-app/i18n/messages_es.properties create mode 100644 BuildingQuality/sample-code/metrics/grails-app/i18n/messages_fr.properties create mode 100644 BuildingQuality/sample-code/metrics/grails-app/i18n/messages_it.properties create mode 100644 BuildingQuality/sample-code/metrics/grails-app/i18n/messages_ja.properties create mode 100644 BuildingQuality/sample-code/metrics/grails-app/i18n/messages_nl.properties create mode 100644 BuildingQuality/sample-code/metrics/grails-app/i18n/messages_pt_BR.properties create mode 100644 BuildingQuality/sample-code/metrics/grails-app/i18n/messages_pt_PT.properties create mode 100644 BuildingQuality/sample-code/metrics/grails-app/i18n/messages_ru.properties create mode 100644 BuildingQuality/sample-code/metrics/grails-app/i18n/messages_sv.properties create mode 100644 BuildingQuality/sample-code/metrics/grails-app/i18n/messages_th.properties create mode 100644 BuildingQuality/sample-code/metrics/grails-app/i18n/messages_zh_CN.properties create mode 100644 BuildingQuality/sample-code/metrics/grails-app/views/book/_form.gsp create mode 100644 BuildingQuality/sample-code/metrics/grails-app/views/book/create.gsp create mode 100644 BuildingQuality/sample-code/metrics/grails-app/views/book/edit.gsp create mode 100644 BuildingQuality/sample-code/metrics/grails-app/views/book/list.gsp create mode 100644 BuildingQuality/sample-code/metrics/grails-app/views/book/show.gsp create mode 100644 BuildingQuality/sample-code/metrics/grails-app/views/error.gsp create mode 100644 BuildingQuality/sample-code/metrics/grails-app/views/index.gsp create mode 100644 BuildingQuality/sample-code/metrics/grails-app/views/layouts/main.gsp create mode 100644 BuildingQuality/sample-code/metrics/test/unit/metrics/BookControllerTests.groovy create mode 100644 BuildingQuality/sample-code/metrics/test/unit/metrics/BookTests.groovy create mode 100644 BuildingQuality/sample-code/metrics/web-app/WEB-INF/applicationContext.xml create mode 100644 BuildingQuality/sample-code/metrics/web-app/WEB-INF/sitemesh.xml create mode 100644 BuildingQuality/sample-code/metrics/web-app/WEB-INF/tld/c.tld create mode 100644 BuildingQuality/sample-code/metrics/web-app/WEB-INF/tld/fmt.tld create mode 100644 BuildingQuality/sample-code/metrics/web-app/WEB-INF/tld/grails.tld create mode 100644 BuildingQuality/sample-code/metrics/web-app/WEB-INF/tld/spring.tld create mode 100644 BuildingQuality/sample-code/metrics/web-app/css/errors.css create mode 100644 BuildingQuality/sample-code/metrics/web-app/css/main.css create mode 100644 BuildingQuality/sample-code/metrics/web-app/css/mobile.css create mode 100644 BuildingQuality/sample-code/metrics/web-app/images/apple-touch-icon-retina.png create mode 100644 BuildingQuality/sample-code/metrics/web-app/images/apple-touch-icon.png create mode 100644 BuildingQuality/sample-code/metrics/web-app/images/favicon.ico create mode 100644 BuildingQuality/sample-code/metrics/web-app/images/grails_logo.jpg create mode 100644 BuildingQuality/sample-code/metrics/web-app/images/grails_logo.png create mode 100644 BuildingQuality/sample-code/metrics/web-app/images/leftnav_btm.png create mode 100644 BuildingQuality/sample-code/metrics/web-app/images/leftnav_midstretch.png create mode 100644 BuildingQuality/sample-code/metrics/web-app/images/leftnav_top.png create mode 100644 BuildingQuality/sample-code/metrics/web-app/images/skin/database_add.png create mode 100644 BuildingQuality/sample-code/metrics/web-app/images/skin/database_delete.png create mode 100644 BuildingQuality/sample-code/metrics/web-app/images/skin/database_edit.png create mode 100644 BuildingQuality/sample-code/metrics/web-app/images/skin/database_save.png create mode 100644 BuildingQuality/sample-code/metrics/web-app/images/skin/database_table.png create mode 100644 BuildingQuality/sample-code/metrics/web-app/images/skin/exclamation.png create mode 100644 BuildingQuality/sample-code/metrics/web-app/images/skin/house.png create mode 100644 BuildingQuality/sample-code/metrics/web-app/images/skin/information.png create mode 100644 BuildingQuality/sample-code/metrics/web-app/images/skin/shadow.jpg create mode 100644 BuildingQuality/sample-code/metrics/web-app/images/skin/sorted_asc.gif create mode 100644 BuildingQuality/sample-code/metrics/web-app/images/skin/sorted_desc.gif create mode 100644 BuildingQuality/sample-code/metrics/web-app/images/spinner.gif create mode 100644 BuildingQuality/sample-code/metrics/web-app/images/springsource.png create mode 100644 BuildingQuality/sample-code/metrics/web-app/js/application.js diff --git a/BuildingQuality/sample-code/gebish/.classpath b/BuildingQuality/sample-code/gebish/.classpath new file mode 100644 index 0000000..ebd5145 --- /dev/null +++ b/BuildingQuality/sample-code/gebish/.classpath @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/BuildingQuality/sample-code/gebish/.gitignore b/BuildingQuality/sample-code/gebish/.gitignore new file mode 100644 index 0000000..398559c --- /dev/null +++ b/BuildingQuality/sample-code/gebish/.gitignore @@ -0,0 +1,15 @@ +*.iws +*Db.properties +*Db.script +.settings +stacktrace.log +/*.zip +/plugin.xml +/*.log +/*DB.* +/cobertura.ser +.DS_Store +/target/ +/out/ +/web-app/plugins +/web-app/WEB-INF/classes \ No newline at end of file diff --git a/BuildingQuality/sample-code/gebish/.project b/BuildingQuality/sample-code/gebish/.project new file mode 100644 index 0000000..4ea382b --- /dev/null +++ b/BuildingQuality/sample-code/gebish/.project @@ -0,0 +1,19 @@ + + + gebish + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + com.springsource.sts.grails.core.nature + org.eclipse.jdt.groovy.core.groovyNature + org.eclipse.jdt.core.javanature + + diff --git a/BuildingQuality/sample-code/gebish/application.properties b/BuildingQuality/sample-code/gebish/application.properties new file mode 100644 index 0000000..314a0e5 --- /dev/null +++ b/BuildingQuality/sample-code/gebish/application.properties @@ -0,0 +1,6 @@ +#Grails Metadata file +#Thu Mar 29 21:29:20 CDT 2012 +app.grails.version=2.0.1 +app.name=gebish +app.servlet.version=2.5 +app.version=0.1 diff --git a/BuildingQuality/sample-code/gebish/gebish.ipr b/BuildingQuality/sample-code/gebish/gebish.ipr new file mode 100644 index 0000000..568117a --- /dev/null +++ b/BuildingQuality/sample-code/gebish/gebish.ipr @@ -0,0 +1,220 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + http://www.w3.org/1999/xhtml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/BuildingQuality/sample-code/gebish/grails-app/conf/ApplicationResources.groovy b/BuildingQuality/sample-code/gebish/grails-app/conf/ApplicationResources.groovy new file mode 100644 index 0000000..06b60c7 --- /dev/null +++ b/BuildingQuality/sample-code/gebish/grails-app/conf/ApplicationResources.groovy @@ -0,0 +1,5 @@ +modules = { + application { + resource url:'js/application.js' + } +} \ No newline at end of file diff --git a/BuildingQuality/sample-code/gebish/grails-app/conf/BootStrap.groovy b/BuildingQuality/sample-code/gebish/grails-app/conf/BootStrap.groovy new file mode 100644 index 0000000..1287dae --- /dev/null +++ b/BuildingQuality/sample-code/gebish/grails-app/conf/BootStrap.groovy @@ -0,0 +1,7 @@ +class BootStrap { + + def init = { servletContext -> + } + def destroy = { + } +} diff --git a/BuildingQuality/sample-code/gebish/grails-app/conf/BuildConfig.groovy b/BuildingQuality/sample-code/gebish/grails-app/conf/BuildConfig.groovy new file mode 100644 index 0000000..24c7456 --- /dev/null +++ b/BuildingQuality/sample-code/gebish/grails-app/conf/BuildConfig.groovy @@ -0,0 +1,66 @@ +grails.servlet.version = "2.5" // Change depending on target container compliance (2.5 or 3.0) +grails.project.class.dir = "target/classes" +grails.project.test.class.dir = "target/test-classes" +grails.project.test.reports.dir = "target/test-reports" +grails.project.target.level = 1.6 +grails.project.source.level = 1.6 +//grails.project.war.file = "target/${appName}-${appVersion}.war" + +grails.project.dependency.resolution = { + // inherit Grails' default dependencies + inherits("global") { + // uncomment to disable ehcache + // excludes 'ehcache' + } + log "error" // log level of Ivy resolver, either 'error', 'warn', 'info', 'debug' or 'verbose' + checksums true // Whether to verify checksums on resolve + + def gebVersion = "0.6.3" + def seleniumVersion = "2.20.0" + + + repositories { + inherits true // Whether to inherit repository definitions from plugins + grailsPlugins() + grailsHome() + grailsCentral() + mavenCentral() + + // uncomment these to enable remote dependency resolution from public Maven repositories + //mavenCentral() + //mavenLocal() + //mavenRepo "http://snapshots.repository.codehaus.org" + //mavenRepo "http://repository.codehaus.org" + //mavenRepo "http://download.java.net/maven/2/" + //mavenRepo "http://repository.jboss.com/maven2/" + } + dependencies { + // specify dependencies here under either 'build', 'compile', 'runtime', 'test' or 'provided' scopes eg. + + // runtime 'mysql:mysql-connector-java:5.1.16' + test("org.seleniumhq.selenium:selenium-htmlunit-driver:$seleniumVersion") { + exclude "xml-apis" + } + test("org.seleniumhq.selenium:selenium-chrome-driver:$seleniumVersion") + test("org.seleniumhq.selenium:selenium-firefox-driver:$seleniumVersion") + test("org.seleniumhq.selenium:selenium-ie-driver:$seleniumVersion") + + // You usually only need one of these, but this project uses both + test "org.codehaus.geb:geb-spock:$gebVersion" + test "org.codehaus.geb:geb-junit4:$gebVersion" + } + + plugins { + runtime ":hibernate:$grailsVersion" + runtime ":jquery:1.7.1" + runtime ":resources:1.1.6" + + // Uncomment these (or add new ones) to enable additional resources capabilities + //runtime ":zipped-resources:1.0" + //runtime ":cached-resources:1.0" + //runtime ":yui-minify-resources:0.1.4 + build ":tomcat:$grailsVersion" + + test ":geb:$gebVersion" + } +} diff --git a/BuildingQuality/sample-code/gebish/grails-app/conf/Config.groovy b/BuildingQuality/sample-code/gebish/grails-app/conf/Config.groovy new file mode 100644 index 0000000..40fda44 --- /dev/null +++ b/BuildingQuality/sample-code/gebish/grails-app/conf/Config.groovy @@ -0,0 +1,93 @@ +// locations to search for config files that get merged into the main config +// config files can either be Java properties files or ConfigSlurper scripts + +// grails.config.locations = [ "classpath:${appName}-config.properties", +// "classpath:${appName}-config.groovy", +// "file:${userHome}/.grails/${appName}-config.properties", +// "file:${userHome}/.grails/${appName}-config.groovy"] + +// if (System.properties["${appName}.config.location"]) { +// grails.config.locations << "file:" + System.properties["${appName}.config.location"] +// } + + +grails.project.groupId = appName // change this to alter the default package name and Maven publishing destination +grails.mime.file.extensions = true // enables the parsing of file extensions from URLs into the request format +grails.mime.use.accept.header = false +grails.mime.types = [ html: ['text/html','application/xhtml+xml'], + xml: ['text/xml', 'application/xml'], + text: 'text/plain', + js: 'text/javascript', + rss: 'application/rss+xml', + atom: 'application/atom+xml', + css: 'text/css', + csv: 'text/csv', + all: '*/*', + json: ['application/json','text/json'], + form: 'application/x-www-form-urlencoded', + multipartForm: 'multipart/form-data' + ] + +// URL Mapping Cache Max Size, defaults to 5000 +//grails.urlmapping.cache.maxsize = 1000 + +// What URL patterns should be processed by the resources plugin +grails.resources.adhoc.patterns = ['/images/*', '/css/*', '/js/*', '/plugins/*'] + + +// The default codec used to encode data with ${} +grails.views.default.codec = "none" // none, html, base64 +grails.views.gsp.encoding = "UTF-8" +grails.converters.encoding = "UTF-8" +// enable Sitemesh preprocessing of GSP pages +grails.views.gsp.sitemesh.preprocess = true +// scaffolding templates configuration +grails.scaffolding.templates.domainSuffix = 'Instance' + +// Set to false to use the new Grails 1.2 JSONBuilder in the render method +grails.json.legacy.builder = false +// enabled native2ascii conversion of i18n properties files +grails.enable.native2ascii = true +// packages to include in Spring bean scanning +grails.spring.bean.packages = [] +// whether to disable processing of multi part requests +grails.web.disable.multipart=false + +// request parameters to mask when logging exceptions +grails.exceptionresolver.params.exclude = ['password'] + +// enable query caching by default +grails.hibernate.cache.queries = true + +// set per-environment serverURL stem for creating absolute links +environments { + development { + grails.logging.jul.usebridge = true + } + production { + grails.logging.jul.usebridge = false + // TODO: grails.serverURL = "http://www.changeme.com" + } +} + +// log4j configuration +log4j = { + // Example of changing the log pattern for the default console + // appender: + // + //appenders { + // console name:'stdout', layout:pattern(conversionPattern: '%c{2} %m%n') + //} + + error 'org.codehaus.groovy.grails.web.servlet', // controllers + 'org.codehaus.groovy.grails.web.pages', // GSP + 'org.codehaus.groovy.grails.web.sitemesh', // layouts + 'org.codehaus.groovy.grails.web.mapping.filter', // URL mapping + 'org.codehaus.groovy.grails.web.mapping', // URL mapping + 'org.codehaus.groovy.grails.commons', // core / classloading + 'org.codehaus.groovy.grails.plugins', // plugins + 'org.codehaus.groovy.grails.orm.hibernate', // hibernate integration + 'org.springframework', + 'org.hibernate', + 'net.sf.ehcache.hibernate' +} diff --git a/BuildingQuality/sample-code/gebish/grails-app/conf/DataSource.groovy b/BuildingQuality/sample-code/gebish/grails-app/conf/DataSource.groovy new file mode 100644 index 0000000..615600a --- /dev/null +++ b/BuildingQuality/sample-code/gebish/grails-app/conf/DataSource.groovy @@ -0,0 +1,43 @@ +dataSource { + pooled = true + driverClassName = "org.h2.Driver" + username = "sa" + password = "" +} +hibernate { + cache.use_second_level_cache = true + cache.use_query_cache = true + cache.region.factory_class = 'net.sf.ehcache.hibernate.EhCacheRegionFactory' +} +// environment specific settings +environments { + development { + dataSource { + dbCreate = "create-drop" // one of 'create', 'create-drop', 'update', 'validate', '' + url = "jdbc:h2:mem:devDb;MVCC=TRUE" + } + } + test { + dataSource { + dbCreate = "update" + url = "jdbc:h2:mem:testDb;MVCC=TRUE" + } + } + production { + dataSource { + dbCreate = "update" + url = "jdbc:h2:prodDb;MVCC=TRUE" + pooled = true + properties { + maxActive = -1 + minEvictableIdleTimeMillis=1800000 + timeBetweenEvictionRunsMillis=1800000 + numTestsPerEvictionRun=3 + testOnBorrow=true + testWhileIdle=true + testOnReturn=true + validationQuery="SELECT 1" + } + } + } +} diff --git a/BuildingQuality/sample-code/gebish/grails-app/conf/UrlMappings.groovy b/BuildingQuality/sample-code/gebish/grails-app/conf/UrlMappings.groovy new file mode 100644 index 0000000..93ee0c4 --- /dev/null +++ b/BuildingQuality/sample-code/gebish/grails-app/conf/UrlMappings.groovy @@ -0,0 +1,13 @@ +class UrlMappings { + + static mappings = { + "/$controller/$action?/$id?"{ + constraints { + // apply constraints here + } + } + + "/"(controller:"/person") + "500"(view:'/error') + } +} diff --git a/BuildingQuality/sample-code/gebish/grails-app/conf/spring/resources.groovy b/BuildingQuality/sample-code/gebish/grails-app/conf/spring/resources.groovy new file mode 100644 index 0000000..fa95006 --- /dev/null +++ b/BuildingQuality/sample-code/gebish/grails-app/conf/spring/resources.groovy @@ -0,0 +1,3 @@ +// Place your Spring DSL code here +beans = { +} diff --git a/BuildingQuality/sample-code/gebish/grails-app/controllers/gebish/PersonController.groovy b/BuildingQuality/sample-code/gebish/grails-app/controllers/gebish/PersonController.groovy new file mode 100644 index 0000000..86ecd4c --- /dev/null +++ b/BuildingQuality/sample-code/gebish/grails-app/controllers/gebish/PersonController.groovy @@ -0,0 +1,103 @@ +package gebish + +import org.springframework.dao.DataIntegrityViolationException + +class PersonController { + + static allowedMethods = [save: "POST", update: "POST", delete: "POST"] + + def index() { + redirect(action: "list", params: params) + } + + def list() { + params.max = Math.min(params.max ? params.int('max') : 10, 100) + [personInstanceList: Person.list(params), personInstanceTotal: Person.count()] + } + + def create() { + [personInstance: new Person(params)] + } + + def save() { + def personInstance = new Person(params) + if (!personInstance.save(flush: true)) { + render(view: "create", model: [personInstance: personInstance]) + return + } + + flash.message = message(code: 'default.created.message', args: [message(code: 'person.label', default: 'Person'), personInstance.id]) + redirect(action: "show", id: personInstance.id) + } + + def show() { + def personInstance = Person.get(params.id) + if (!personInstance) { + flash.message = message(code: 'default.not.found.message', args: [message(code: 'person.label', default: 'Person'), params.id]) + redirect(action: "list") + return + } + + [personInstance: personInstance] + } + + def edit() { + def personInstance = Person.get(params.id) + if (!personInstance) { + flash.message = message(code: 'default.not.found.message', args: [message(code: 'person.label', default: 'Person'), params.id]) + redirect(action: "list") + return + } + + [personInstance: personInstance] + } + + def update() { + def personInstance = Person.get(params.id) + if (!personInstance) { + flash.message = message(code: 'default.not.found.message', args: [message(code: 'person.label', default: 'Person'), params.id]) + redirect(action: "list") + return + } + + if (params.version) { + def version = params.version.toLong() + if (personInstance.version > version) { + personInstance.errors.rejectValue("version", "default.optimistic.locking.failure", + [message(code: 'person.label', default: 'Person')] as Object[], + "Another user has updated this Person while you were editing") + render(view: "edit", model: [personInstance: personInstance]) + return + } + } + + personInstance.properties = params + + if (!personInstance.save(flush: true)) { + render(view: "edit", model: [personInstance: personInstance]) + return + } + + flash.message = message(code: 'default.updated.message', args: [message(code: 'person.label', default: 'Person'), personInstance.id]) + redirect(action: "show", id: personInstance.id) + } + + def delete() { + def personInstance = Person.get(params.id) + if (!personInstance) { + flash.message = message(code: 'default.not.found.message', args: [message(code: 'person.label', default: 'Person'), params.id]) + redirect(action: "list") + return + } + + try { + personInstance.delete(flush: true) + flash.message = message(code: 'default.deleted.message', args: [message(code: 'person.label', default: 'Person'), params.id]) + redirect(action: "list") + } + catch (DataIntegrityViolationException e) { + flash.message = message(code: 'default.not.deleted.message', args: [message(code: 'person.label', default: 'Person'), params.id]) + redirect(action: "show", id: params.id) + } + } +} diff --git a/BuildingQuality/sample-code/gebish/grails-app/domain/gebish/Person.groovy b/BuildingQuality/sample-code/gebish/grails-app/domain/gebish/Person.groovy new file mode 100644 index 0000000..167cc00 --- /dev/null +++ b/BuildingQuality/sample-code/gebish/grails-app/domain/gebish/Person.groovy @@ -0,0 +1,10 @@ +package gebish + +class Person { + String firstName + String lastName + + boolean enabled + static constraints = { + } +} diff --git a/BuildingQuality/sample-code/gebish/grails-app/i18n/messages.properties b/BuildingQuality/sample-code/gebish/grails-app/i18n/messages.properties new file mode 100644 index 0000000..0c9d7ee --- /dev/null +++ b/BuildingQuality/sample-code/gebish/grails-app/i18n/messages.properties @@ -0,0 +1,55 @@ +default.doesnt.match.message=Property [{0}] of class [{1}] with value [{2}] does not match the required pattern [{3}] +default.invalid.url.message=Property [{0}] of class [{1}] with value [{2}] is not a valid URL +default.invalid.creditCard.message=Property [{0}] of class [{1}] with value [{2}] is not a valid credit card number +default.invalid.email.message=Property [{0}] of class [{1}] with value [{2}] is not a valid e-mail address +default.invalid.range.message=Property [{0}] of class [{1}] with value [{2}] does not fall within the valid range from [{3}] to [{4}] +default.invalid.size.message=Property [{0}] of class [{1}] with value [{2}] does not fall within the valid size range from [{3}] to [{4}] +default.invalid.max.message=Property [{0}] of class [{1}] with value [{2}] exceeds maximum value [{3}] +default.invalid.min.message=Property [{0}] of class [{1}] with value [{2}] is less than minimum value [{3}] +default.invalid.max.size.message=Property [{0}] of class [{1}] with value [{2}] exceeds the maximum size of [{3}] +default.invalid.min.size.message=Property [{0}] of class [{1}] with value [{2}] is less than the minimum size of [{3}] +default.invalid.validator.message=Property [{0}] of class [{1}] with value [{2}] does not pass custom validation +default.not.inlist.message=Property [{0}] of class [{1}] with value [{2}] is not contained within the list [{3}] +default.blank.message=Property [{0}] of class [{1}] cannot be blank +default.not.equal.message=Property [{0}] of class [{1}] with value [{2}] cannot equal [{3}] +default.null.message=Property [{0}] of class [{1}] cannot be null +default.not.unique.message=Property [{0}] of class [{1}] with value [{2}] must be unique + +default.paginate.prev=Previous +default.paginate.next=Next +default.boolean.true=True +default.boolean.false=False +default.date.format=yyyy-MM-dd HH:mm:ss z +default.number.format=0 + +default.created.message={0} {1} created +default.updated.message={0} {1} updated +default.deleted.message={0} {1} deleted +default.not.deleted.message={0} {1} could not be deleted +default.not.found.message={0} not found with id {1} +default.optimistic.locking.failure=Another user has updated this {0} while you were editing + +default.home.label=Home +default.list.label={0} List +default.add.label=Add {0} +default.new.label=New {0} +default.create.label=Create {0} +default.show.label=Show {0} +default.edit.label=Edit {0} + +default.button.create.label=Create +default.button.edit.label=Edit +default.button.update.label=Update +default.button.delete.label=Delete +default.button.delete.confirm.message=Are you sure? + +# Data binding errors. Use "typeMismatch.$className.$propertyName to customize (eg typeMismatch.Book.author) +typeMismatch.java.net.URL=Property {0} must be a valid URL +typeMismatch.java.net.URI=Property {0} must be a valid URI +typeMismatch.java.util.Date=Property {0} must be a valid Date +typeMismatch.java.lang.Double=Property {0} must be a valid number +typeMismatch.java.lang.Integer=Property {0} must be a valid number +typeMismatch.java.lang.Long=Property {0} must be a valid number +typeMismatch.java.lang.Short=Property {0} must be a valid number +typeMismatch.java.math.BigDecimal=Property {0} must be a valid number +typeMismatch.java.math.BigInteger=Property {0} must be a valid number diff --git a/BuildingQuality/sample-code/gebish/grails-app/i18n/messages_cs_CZ.properties b/BuildingQuality/sample-code/gebish/grails-app/i18n/messages_cs_CZ.properties new file mode 100644 index 0000000..c617dca --- /dev/null +++ b/BuildingQuality/sample-code/gebish/grails-app/i18n/messages_cs_CZ.properties @@ -0,0 +1,55 @@ +default.doesnt.match.message=Položka [{0}] třídy [{1}] o hodnotě [{2}] neodpovídá požadovanému vzoru [{3}] +default.invalid.url.message=Položka [{0}] třídy [{1}] o hodnotě [{2}] není validní URL +default.invalid.creditCard.message=Položka [{0}] třídy [{1}] o hodnotě [{2}] není validní číslo kreditní karty +default.invalid.email.message=Položka [{0}] třídy [{1}] o hodnotě [{2}] není validní emailová adresa +default.invalid.range.message=Položka [{0}] třídy [{1}] o hodnotě [{2}] není v povoleném rozmezí od [{3}] do [{4}] +default.invalid.size.message=Položka [{0}] třídy [{1}] o hodnotě [{2}] není v povoleném rozmezí od [{3}] do [{4}] +default.invalid.max.message=Položka [{0}] třídy [{1}] o hodnotě [{2}] překračuje maximální povolenou hodnotu [{3}] +default.invalid.min.message=Položka [{0}] třídy [{1}] o hodnotě [{2}] je menší než minimální povolená hodnota [{3}] +default.invalid.max.size.message=Položka [{0}] třídy [{1}] o hodnotě [{2}] překračuje maximální velikost [{3}] +default.invalid.min.size.message=Položka [{0}] třídy [{1}] o hodnotě [{2}] je menší než minimální velikost [{3}] +default.invalid.validator.message=Položka [{0}] třídy [{1}] o hodnotě [{2}] neprošla validací +default.not.inlist.message=Položka [{0}] třídy [{1}] o hodnotě [{2}] není obsažena v seznamu [{3}] +default.blank.message=Položka [{0}] třídy [{1}] nemůže být prázdná +default.not.equal.message=Položka [{0}] třídy [{1}] o hodnotě [{2}] nemůže být stejná jako [{3}] +default.null.message=Položka [{0}] třídy [{1}] nemůže být prázdná +default.not.unique.message=Položka [{0}] třídy [{1}] o hodnotě [{2}] musí být unikátní + +default.paginate.prev=Předcházející +default.paginate.next=Následující +default.boolean.true=Pravda +default.boolean.false=Nepravda +default.date.format=dd. MM. yyyy HH:mm:ss z +default.number.format=0 + +default.created.message={0} {1} vytvořeno +default.updated.message={0} {1} aktualizováno +default.deleted.message={0} {1} smazáno +default.not.deleted.message={0} {1} nelze smazat +default.not.found.message={0} nenalezen s id {1} +default.optimistic.locking.failure=Jiný uživatel aktualizoval záznam {0}, právě když byl vámi editován + +default.home.label=Domů +default.list.label={0} Seznam +default.add.label=Přidat {0} +default.new.label=Nový {0} +default.create.label=Vytvořit {0} +default.show.label=Ukázat {0} +default.edit.label=Editovat {0} + +default.button.create.label=Vytvoř +default.button.edit.label=Edituj +default.button.update.label=Aktualizuj +default.button.delete.label=Smaž +default.button.delete.confirm.message=Jste si jistý? + +# Data binding errors. Use "typeMismatch.$className.$propertyName to customize (eg typeMismatch.Book.author) +typeMismatch.java.net.URL=Položka {0} musí být validní URL +typeMismatch.java.net.URI=Položka {0} musí být validní URI +typeMismatch.java.util.Date=Položka {0} musí být validní datum +typeMismatch.java.lang.Double=Položka {0} musí být validní desetinné číslo +typeMismatch.java.lang.Integer=Položka {0} musí být validní číslo +typeMismatch.java.lang.Long=Položka {0} musí být validní číslo +typeMismatch.java.lang.Short=Položka {0} musí být validní číslo +typeMismatch.java.math.BigDecimal=Položka {0} musí být validní číslo +typeMismatch.java.math.BigInteger=Položka {0} musí být validní číslo \ No newline at end of file diff --git a/BuildingQuality/sample-code/gebish/grails-app/i18n/messages_da.properties b/BuildingQuality/sample-code/gebish/grails-app/i18n/messages_da.properties new file mode 100644 index 0000000..858b229 --- /dev/null +++ b/BuildingQuality/sample-code/gebish/grails-app/i18n/messages_da.properties @@ -0,0 +1,56 @@ +default.doesnt.match.message=Feltet [{0}] i klassen [{1}] som har værdien [{2}] overholder ikke mønsteret [{3}] +default.invalid.url.message=Feltet [{0}] i klassen [{1}] som har værdien [{2}] er ikke en gyldig URL +default.invalid.creditCard.message=Feltet [{0}] i klassen [{1}] som har værdien [{2}] er ikke et gyldigt kreditkortnummer +default.invalid.email.message=Feltet [{0}] i klassen [{1}] som har værdien [{2}] er ikke en gyldig e-mail adresse +default.invalid.range.message=Feltet [{0}] i klassen [{1}] som har værdien [{2}] ligger ikke inden for intervallet fra [{3}] til [{4}] +default.invalid.size.message=Feltet [{0}] i klassen [{1}] som har værdien [{2}] ligger ikke inden for størrelsen fra [{3}] til [{4}] +default.invalid.max.message=Feltet [{0}] i klassen [{1}] som har værdien [{2}] overstiger den maksimale værdi [{3}] +default.invalid.min.message=Feltet [{0}] i klassen [{1}] som har værdien [{2}] er under den minimale værdi [{3}] +default.invalid.max.size.message=Feltet [{0}] i klassen [{1}] som har værdien [{2}] overstiger den maksimale størrelse på [{3}] +default.invalid.min.size.message=Feltet [{0}] i klassen [{1}] som har værdien [{2}] er under den minimale størrelse på [{3}] +default.invalid.validator.message=Feltet [{0}] i klassen [{1}] som har værdien [{2}] overholder ikke den brugerdefinerede validering +default.not.inlist.message=Feltet [{0}] i klassen [{1}] som har værdien [{2}] findes ikke i listen [{3}] +default.blank.message=Feltet [{0}] i klassen [{1}] kan ikke være tom +default.not.equal.message=Feltet [{0}] i klassen [{1}] som har værdien [{2}] må ikke være [{3}] +default.null.message=Feltet [{0}] i klassen [{1}] kan ikke være null +default.not.unique.message=Feltet [{0}] i klassen [{1}] som har værdien [{2}] skal være unik + +default.paginate.prev=Forrige +default.paginate.next=Næste +default.boolean.true=Sand +default.boolean.false=Falsk +default.date.format=yyyy-MM-dd HH:mm:ss z +default.number.format=0 + +default.created.message={0} {1} oprettet +default.updated.message={0} {1} opdateret +default.deleted.message={0} {1} slettet +default.not.deleted.message={0} {1} kunne ikke slettes +default.not.found.message={0} med id {1} er ikke fundet +default.optimistic.locking.failure=En anden bruger har opdateret denne {0} imens du har lavet rettelser + +default.home.label=Hjem +default.list.label={0} Liste +default.add.label=Tilføj {0} +default.new.label=Ny {0} +default.create.label=Opret {0} +default.show.label=Vis {0} +default.edit.label=Ret {0} + +default.button.create.label=Opret +default.button.edit.label=Ret +default.button.update.label=Opdater +default.button.delete.label=Slet +default.button.delete.confirm.message=Er du sikker? + +# Databindingsfejl. Brug "typeMismatch.$className.$propertyName for at passe til en given klasse (f.eks typeMismatch.Book.author) +typeMismatch.java.net.URL=Feltet {0} skal være en valid URL +typeMismatch.java.net.URI=Feltet {0} skal være en valid URI +typeMismatch.java.util.Date=Feltet {0} skal være en valid Dato +typeMismatch.java.lang.Double=Feltet {0} skal være et valid tal +typeMismatch.java.lang.Integer=Feltet {0} skal være et valid tal +typeMismatch.java.lang.Long=Feltet {0} skal være et valid tal +typeMismatch.java.lang.Short=Feltet {0} skal være et valid tal +typeMismatch.java.math.BigDecimal=Feltet {0} skal være et valid tal +typeMismatch.java.math.BigInteger=Feltet {0} skal være et valid tal + diff --git a/BuildingQuality/sample-code/gebish/grails-app/i18n/messages_de.properties b/BuildingQuality/sample-code/gebish/grails-app/i18n/messages_de.properties new file mode 100644 index 0000000..a942358 --- /dev/null +++ b/BuildingQuality/sample-code/gebish/grails-app/i18n/messages_de.properties @@ -0,0 +1,55 @@ +default.doesnt.match.message=Die Eigenschaft [{0}] des Typs [{1}] mit dem Wert [{2}] entspricht nicht dem vorgegebenen Muster [{3}] +default.invalid.url.message=Die Eigenschaft [{0}] des Typs [{1}] mit dem Wert [{2}] ist keine gültige URL +default.invalid.creditCard.message=Das Die Eigenschaft [{0}] des Typs [{1}] mit dem Wert [{2}] ist keine gültige Kreditkartennummer +default.invalid.email.message=Die Eigenschaft [{0}] des Typs [{1}] mit dem Wert [{2}] ist keine gültige E-Mail Adresse +default.invalid.range.message=Die Eigenschaft [{0}] des Typs [{1}] mit dem Wert [{2}] ist nicht im Wertebereich von [{3}] bis [{4}] +default.invalid.size.message=Die Eigenschaft [{0}] des Typs [{1}] mit dem Wert [{2}] ist nicht im Wertebereich von [{3}] bis [{4}] +default.invalid.max.message=Die Eigenschaft [{0}] des Typs [{1}] mit dem Wert [{2}] ist größer als der Höchstwert von [{3}] +default.invalid.min.message=Die Eigenschaft [{0}] des Typs [{1}] mit dem Wert [{2}] ist kleiner als der Mindestwert von [{3}] +default.invalid.max.size.message=Die Eigenschaft [{0}] des Typs [{1}] mit dem Wert [{2}] übersteigt den Höchstwert von [{3}] +default.invalid.min.size.message=Die Eigenschaft [{0}] des Typs [{1}] mit dem Wert [{2}] unterschreitet den Mindestwert von [{3}] +default.invalid.validator.message=Die Eigenschaft [{0}] des Typs [{1}] mit dem Wert [{2}] ist ungültig +default.not.inlist.message=Die Eigenschaft [{0}] des Typs [{1}] mit dem Wert [{2}] ist nicht in der Liste [{3}] enthalten. +default.blank.message=Die Eigenschaft [{0}] des Typs [{1}] darf nicht leer sein +default.not.equal.message=Die Eigenschaft [{0}] des Typs [{1}] mit dem Wert [{2}] darf nicht gleich [{3}] sein +default.null.message=Die Eigenschaft [{0}] des Typs [{1}] darf nicht null sein +default.not.unique.message=Die Eigenschaft [{0}] des Typs [{1}] mit dem Wert [{2}] darf nur einmal vorkommen + +default.paginate.prev=Vorherige +default.paginate.next=Nächste +default.boolean.true=Wahr +default.boolean.false=Falsch +default.date.format=dd.MM.yyyy HH:mm:ss z +default.number.format=0 + +default.created.message={0} {1} wurde angelegt +default.updated.message={0} {1} wurde geändert +default.deleted.message={0} {1} wurde gelöscht +default.not.deleted.message={0} {1} konnte nicht gelöscht werden +default.not.found.message={0} mit der id {1} wurde nicht gefunden +default.optimistic.locking.failure=Ein anderer Benutzer hat das {0} Object geändert während Sie es bearbeitet haben + +default.home.label=Home +default.list.label={0} Liste +default.add.label={0} hinzufügen +default.new.label={0} anlegen +default.create.label={0} anlegen +default.show.label={0} anzeigen +default.edit.label={0} bearbeiten + +default.button.create.label=Anlegen +default.button.edit.label=Bearbeiten +default.button.update.label=Aktualisieren +default.button.delete.label=Löschen +default.button.delete.confirm.message=Sind Sie sicher? + +# Data binding errors. Use "typeMismatch.$className.$propertyName to customize (eg typeMismatch.Book.author) +typeMismatch.java.net.URL=Die Eigenschaft {0} muss eine gültige URL sein +typeMismatch.java.net.URI=Die Eigenschaft {0} muss eine gültige URI sein +typeMismatch.java.util.Date=Die Eigenschaft {0} muss ein gültiges Datum sein +typeMismatch.java.lang.Double=Die Eigenschaft {0} muss eine gültige Zahl sein +typeMismatch.java.lang.Integer=Die Eigenschaft {0} muss eine gültige Zahl sein +typeMismatch.java.lang.Long=Die Eigenschaft {0} muss eine gültige Zahl sein +typeMismatch.java.lang.Short=Die Eigenschaft {0} muss eine gültige Zahl sein +typeMismatch.java.math.BigDecimal=Die Eigenschaft {0} muss eine gültige Zahl sein +typeMismatch.java.math.BigInteger=Die Eigenschaft {0} muss eine gültige Zahl sein \ No newline at end of file diff --git a/BuildingQuality/sample-code/gebish/grails-app/i18n/messages_es.properties b/BuildingQuality/sample-code/gebish/grails-app/i18n/messages_es.properties new file mode 100644 index 0000000..915db13 --- /dev/null +++ b/BuildingQuality/sample-code/gebish/grails-app/i18n/messages_es.properties @@ -0,0 +1,55 @@ +default.doesnt.match.message=La propiedad [{0}] de la clase [{1}] con valor [{2}] no corresponde al patrón [{3}] +default.invalid.url.message=La propiedad [{0}] de la clase [{1}] con valor [{2}] no es una URL válida +default.invalid.creditCard.message=La propiedad [{0}] de la clase [{1}] con valor [{2}] no es un número de tarjeta de crédito válida +default.invalid.email.message=La propiedad [{0}] de la clase [{1}] con valor [{2}] no es una dirección de correo electrónico válida +default.invalid.range.message=La propiedad [{0}] de la clase [{1}] con valor [{2}] no entra en el rango válido de [{3}] a [{4}] +default.invalid.size.message=La propiedad [{0}] de la clase [{1}] con valor [{2}] no entra en el tamaño válido de [{3}] a [{4}] +default.invalid.max.message=La propiedad [{0}] de la clase [{1}] con valor [{2}] excede el valor máximo [{3}] +default.invalid.min.message=La propiedad [{0}] de la clase [{1}] con valor [{2}] es menos que el valor mínimo [{3}] +default.invalid.max.size.message=La propiedad [{0}] de la clase [{1}] con valor [{2}] excede el tamaño máximo de [{3}] +default.invalid.min.size.message=La propiedad [{0}] de la clase [{1}] con valor [{2}] es menor que el tamaño mínimo de [{3}] +default.invalid.validator.message=La propiedad [{0}] de la clase [{1}] con valor [{2}] no es válido +default.not.inlist.message=La propiedad [{0}] de la clase [{1}] con valor [{2}] no esta contenido dentro de la lista [{3}] +default.blank.message=La propiedad [{0}] de la clase [{1}] no puede ser vacía +default.not.equal.message=La propiedad [{0}] de la clase [{1}] con valor [{2}] no puede igualar a [{3}] +default.null.message=La propiedad [{0}] de la clase [{1}] no puede ser nulo +default.not.unique.message=La propiedad [{0}] de la clase [{1}] con valor [{2}] debe ser única + +default.paginate.prev=Anterior +default.paginate.next=Siguiente +default.boolean.true=Verdadero +default.boolean.false=Falso +default.date.format=yyyy-MM-dd HH:mm:ss z +default.number.format=0 + +default.created.message={0} {1} creado +default.updated.message={0} {1} actualizado +default.deleted.message={0} {1} eliminado +default.not.deleted.message={0} {1} no puede eliminarse +default.not.found.message=No se encuentra {0} con id {1} +default.optimistic.locking.failure=Mientras usted editaba, otro usuario ha actualizado su {0} + +default.home.label=Principal +default.list.label={0} Lista +default.add.label=Agregar {0} +default.new.label=Nuevo {0} +default.create.label=Crear {0} +default.show.label=Mostar {0} +default.edit.label=Editar {0} + +default.button.create.label=Crear +default.button.edit.label=Editar +default.button.update.label=Actualizar +default.button.delete.label=Eliminar +default.button.delete.confirm.message=¿Está usted seguro? + +# Data binding errors. Use "typeMismatch.$className.$propertyName to customize (eg typeMismatch.Book.author) +typeMismatch.java.net.URL=La propiedad {0} debe ser una URL válida +typeMismatch.java.net.URI=La propiedad {0} debe ser una URI válida +typeMismatch.java.util.Date=La propiedad {0} debe ser una fecha válida +typeMismatch.java.lang.Double=La propiedad {0} debe ser un número válido +typeMismatch.java.lang.Integer=La propiedad {0} debe ser un número válido +typeMismatch.java.lang.Long=La propiedad {0} debe ser un número válido +typeMismatch.java.lang.Short=La propiedad {0} debe ser un número válido +typeMismatch.java.math.BigDecimal=La propiedad {0} debe ser un número válido +typeMismatch.java.math.BigInteger=La propiedad {0} debe ser un número válido \ No newline at end of file diff --git a/BuildingQuality/sample-code/gebish/grails-app/i18n/messages_fr.properties b/BuildingQuality/sample-code/gebish/grails-app/i18n/messages_fr.properties new file mode 100644 index 0000000..b1d665c --- /dev/null +++ b/BuildingQuality/sample-code/gebish/grails-app/i18n/messages_fr.properties @@ -0,0 +1,19 @@ +default.doesnt.match.message=La propriété [{0}] de la classe [{1}] avec la valeur [{2}] ne correspond pas au pattern [{3}] +default.invalid.url.message=La propriété [{0}] de la classe [{1}] avec la valeur [{2}] n'est pas une URL valide +default.invalid.creditCard.message=La propriété [{0}] de la classe [{1}] avec la valeur [{2}] n'est pas un numéro de carte de crédit valide +default.invalid.email.message=La propriété [{0}] de la classe [{1}] avec la valeur [{2}] n'est pas une adresse e-mail valide +default.invalid.range.message=La propriété [{0}] de la classe [{1}] avec la valeur [{2}] n'est pas contenue dans l'intervalle [{3}] à [{4}] +default.invalid.size.message=La propriété [{0}] de la classe [{1}] avec la valeur [{2}] n'est pas contenue dans l'intervalle [{3}] à [{4}] +default.invalid.max.message=La propriété [{0}] de la classe [{1}] avec la valeur [{2}] est supérieure à la valeur maximum [{3}] +default.invalid.min.message=La propriété [{0}] de la classe [{1}] avec la valeur [{2}] est inférieure à la valeur minimum [{3}] +default.invalid.max.size.message=La propriété [{0}] de la classe [{1}] avec la valeur [{2}] est supérieure à la valeur maximum [{3}] +default.invalid.min.size.message=La propriété [{0}] de la classe [{1}] avec la valeur [{2}] est inférieure à la valeur minimum [{3}] +default.invalid.validator.message=La propriété [{0}] de la classe [{1}] avec la valeur [{2}] n'est pas valide +default.not.inlist.message=La propriété [{0}] de la classe [{1}] avec la valeur [{2}] ne fait pas partie de la liste [{3}] +default.blank.message=La propriété [{0}] de la classe [{1}] ne peut pas être vide +default.not.equal.message=La propriété [{0}] de la classe [{1}] avec la valeur [{2}] ne peut pas être égale à [{3}] +default.null.message=La propriété [{0}] de la classe [{1}] ne peut pas être nulle +default.not.unique.message=La propriété [{0}] de la classe [{1}] avec la valeur [{2}] doit être unique + +default.paginate.prev=Précédent +default.paginate.next=Suivant diff --git a/BuildingQuality/sample-code/gebish/grails-app/i18n/messages_it.properties b/BuildingQuality/sample-code/gebish/grails-app/i18n/messages_it.properties new file mode 100644 index 0000000..ea83b92 --- /dev/null +++ b/BuildingQuality/sample-code/gebish/grails-app/i18n/messages_it.properties @@ -0,0 +1,19 @@ +default.doesnt.match.message=La proprietà [{0}] della classe [{1}] con valore [{2}] non corrisponde al pattern [{3}] +default.invalid.url.message=La proprietà [{0}] della classe [{1}] con valore [{2}] non è un URL valido +default.invalid.creditCard.message=La proprietà [{0}] della classe [{1}] con valore [{2}] non è un numero di carta di credito valido +default.invalid.email.message=La proprietà [{0}] della classe [{1}] con valore [{2}] non è un indirizzo email valido +default.invalid.range.message=La proprietà [{0}] della classe [{1}] con valore [{2}] non rientra nell'intervallo valido da [{3}] a [{4}] +default.invalid.size.message=La proprietà [{0}] della classe [{1}] con valore [{2}] non rientra nell'intervallo di dimensioni valide da [{3}] a [{4}] +default.invalid.max.message=La proprietà [{0}] della classe [{1}] con valore [{2}] è maggiore di [{3}] +default.invalid.min.message=La proprietà [{0}] della classe [{1}] con valore [{2}] è minore di [{3}] +default.invalid.max.size.message=La proprietà [{0}] della classe [{1}] con valore [{2}] è maggiore di [{3}] +default.invalid.min.size.message=La proprietà [{0}] della classe [{1}] con valore [{2}] è minore di [{3}] +default.invalid.validator.message=La proprietà [{0}] della classe [{1}] con valore [{2}] non è valida +default.not.inlist.message=La proprietà [{0}] della classe [{1}] con valore [{2}] non è contenuta nella lista [{3}] +default.blank.message=La proprietà [{0}] della classe [{1}] non può essere vuota +default.not.equal.message=La proprietà [{0}] della classe [{1}] con valore [{2}] non può essere uguale a [{3}] +default.null.message=La proprietà [{0}] della classe [{1}] non può essere null +default.not.unique.message=La proprietà [{0}] della classe [{1}] con valore [{2}] deve essere unica + +default.paginate.prev=Precedente +default.paginate.next=Successivo \ No newline at end of file diff --git a/BuildingQuality/sample-code/gebish/grails-app/i18n/messages_ja.properties b/BuildingQuality/sample-code/gebish/grails-app/i18n/messages_ja.properties new file mode 100644 index 0000000..b5e4d18 --- /dev/null +++ b/BuildingQuality/sample-code/gebish/grails-app/i18n/messages_ja.properties @@ -0,0 +1,55 @@ +default.doesnt.match.message=クラス[{1}]プロパティ[{0}]の値[{2}]は、[{3}]パターンと一致していません。 +default.invalid.url.message=クラス[{1}]プロパティ[{0}]の値[{2}]は、有効なURLではありません。 +default.invalid.creditCard.message=クラス[{1}]プロパティ[{0}]の値[{2}]は、有効なクレジットカード番号ではありません。 +default.invalid.email.message=クラス[{1}]プロパティ[{0}]の値[{2}]は、有効なメールアドレスではありません。 +default.invalid.range.message=クラス[{1}]プロパティ[{0}]の値[{2}]は、[{3}]から[{4}]範囲内を指定してください。 +default.invalid.size.message=クラス[{1}]プロパティ[{0}]の値[{2}]は、[{3}]から[{4}]以内を指定してください。 +default.invalid.max.message=クラス[{1}]プロパティ[{0}]の値[{2}]は、最大値[{3}]より大きいです。 +default.invalid.min.message=クラス[{1}]プロパティ[{0}]の値[{2}]は、最小値[{3}]より小さいです。 +default.invalid.max.size.message=クラス[{1}]プロパティ[{0}]の値[{2}]は、最大値[{3}]より大きいです。 +default.invalid.min.size.message=クラス[{1}]プロパティ[{0}]の値[{2}]は、最小値[{3}]より小さいです。 +default.invalid.validator.message=クラス[{1}]プロパティ[{0}]の値[{2}]は、カスタムバリデーションを通過できません。 +default.not.inlist.message=クラス[{1}]プロパティ[{0}]の値[{2}]は、[{3}]リスト内に存在しません。 +default.blank.message=[{1}]クラスのプロパティ[{0}]の空白は許可されません。 +default.not.equal.message=クラス[{1}]プロパティ[{0}]の値[{2}]は、[{3}]と同等ではありません。 +default.null.message=[{1}]クラスのプロパティ[{0}]にnullは許可されません。 +default.not.unique.message=クラス[{1}]プロパティ[{0}]の値[{2}]は既に使用されています。 + +default.paginate.prev=戻る +default.paginate.next=次へ +default.boolean.true=はい +default.boolean.false=いいえ +default.date.format=yyyy/MM/dd HH:mm:ss z +default.number.format=0 + +default.created.message={0}(id:{1})を作成しました。 +default.updated.message={0}(id:{1})を更新しました。 +default.deleted.message={0}(id:{1})を削除しました。 +default.not.deleted.message={0}(id:{1})は削除できませんでした。 +default.not.found.message={0}(id:{1})は見つかりませんでした。 +default.optimistic.locking.failure=この{0}は編集中に他のユーザによって先に更新されています。 + +default.home.label=ホーム +default.list.label={0}リスト +default.add.label={0}を追加 +default.new.label={0}を新規作成 +default.create.label={0}を作成 +default.show.label={0}詳細 +default.edit.label={0}を編集 + +default.button.create.label=作成 +default.button.edit.label=編集 +default.button.update.label=更新 +default.button.delete.label=削除 +default.button.delete.confirm.message=本当に削除してよろしいですか? + +# Data binding errors. Use "typeMismatch.$className.$propertyName to customize (eg typeMismatch.Book.author) +typeMismatch.java.net.URL={0}は有効なURLでなければなりません。 +typeMismatch.java.net.URI={0}は有効なURIでなければなりません。 +typeMismatch.java.util.Date={0}は有効な日付でなければなりません。 +typeMismatch.java.lang.Double={0}は有効な数値でなければなりません。 +typeMismatch.java.lang.Integer={0}は有効な数値でなければなりません。 +typeMismatch.java.lang.Long={0}は有効な数値でなければなりません。 +typeMismatch.java.lang.Short={0}は有効な数値でなければなりません。 +typeMismatch.java.math.BigDecimal={0}は有効な数値でなければなりません。 +typeMismatch.java.math.BigInteger={0}は有効な数値でなければなりません。 diff --git a/BuildingQuality/sample-code/gebish/grails-app/i18n/messages_nl.properties b/BuildingQuality/sample-code/gebish/grails-app/i18n/messages_nl.properties new file mode 100644 index 0000000..cd5cc94 --- /dev/null +++ b/BuildingQuality/sample-code/gebish/grails-app/i18n/messages_nl.properties @@ -0,0 +1,55 @@ +default.doesnt.match.message=Attribuut [{0}] van entiteit [{1}] met waarde [{2}] komt niet overeen met het vereiste patroon [{3}] +default.invalid.url.message=Attribuut [{0}] van entiteit [{1}] met waarde [{2}] is geen geldige URL +default.invalid.creditCard.message=Attribuut [{0}] van entiteit [{1}] met waarde [{2}] is geen geldig credit card nummer +default.invalid.email.message=Attribuut [{0}] van entiteit [{1}] met waarde [{2}] is geen geldig e-mailadres +default.invalid.range.message=Attribuut [{0}] van entiteit [{1}] met waarde [{2}] valt niet in de geldige waardenreeks van [{3}] tot [{4}] +default.invalid.size.message=Attribuut [{0}] van entiteit [{1}] met waarde [{2}] valt niet in de geldige grootte van [{3}] tot [{4}] +default.invalid.max.message=Attribuut [{0}] van entiteit [{1}] met waarde [{2}] overschrijdt de maximumwaarde [{3}] +default.invalid.min.message=Attribuut [{0}] van entiteit [{1}] met waarde [{2}] is minder dan de minimumwaarde [{3}] +default.invalid.max.size.message=Attribuut [{0}] van entiteit [{1}] met waarde [{2}] overschrijdt de maximumgrootte van [{3}] +default.invalid.min.size.message=Attribuut [{0}] van entiteit [{1}] met waarde [{2}] is minder dan minimumgrootte van [{3}] +default.invalid.validator.message=Attribuut [{0}] van entiteit [{1}] met waarde [{2}] is niet geldig +default.not.inlist.message=Attribuut [{0}] van entiteit [{1}] met waarde [{2}] komt niet voor in de lijst [{3}] +default.blank.message=Attribuut [{0}] van entiteit [{1}] mag niet leeg zijn +default.not.equal.message=Attribuut [{0}] van entiteit [{1}] met waarde [{2}] mag niet gelijk zijn aan [{3}] +default.null.message=Attribuut [{0}] van entiteit [{1}] mag niet leeg zijn +default.not.unique.message=Attribuut [{0}] van entiteit [{1}] met waarde [{2}] moet uniek zijn + +default.paginate.prev=Vorige +default.paginate.next=Volgende +default.boolean.true=Ja +default.boolean.false=Nee +default.date.format=dd-MM-yyyy HH:mm:ss z +default.number.format=0 + +default.created.message={0} {1} ingevoerd +default.updated.message={0} {1} gewijzigd +default.deleted.message={0} {1} verwijderd +default.not.deleted.message={0} {1} kon niet worden verwijderd +default.not.found.message={0} met id {1} kon niet worden gevonden +default.optimistic.locking.failure=Een andere gebruiker heeft deze {0} al gewijzigd + +default.home.label=Home +default.list.label={0} Overzicht +default.add.label=Toevoegen {0} +default.new.label=Invoeren {0} +default.create.label=Invoeren {0} +default.show.label=Details {0} +default.edit.label=Wijzigen {0} + +default.button.create.label=Invoeren +default.button.edit.label=Wijzigen +default.button.update.label=Opslaan +default.button.delete.label=Verwijderen +default.button.delete.confirm.message=Weet je het zeker? + +# Data binding errors. Use "typeMismatch.$className.$propertyName to customize (eg typeMismatch.Book.author) +typeMismatch.java.net.URL=Attribuut {0} is geen geldige URL +typeMismatch.java.net.URI=Attribuut {0} is geen geldige URI +typeMismatch.java.util.Date=Attribuut {0} is geen geldige datum +typeMismatch.java.lang.Double=Attribuut {0} is geen geldig nummer +typeMismatch.java.lang.Integer=Attribuut {0} is geen geldig nummer +typeMismatch.java.lang.Long=Attribuut {0} is geen geldig nummer +typeMismatch.java.lang.Short=Attribuut {0} is geen geldig nummer +typeMismatch.java.math.BigDecimal=Attribuut {0} is geen geldig nummer +typeMismatch.java.math.BigInteger=Attribuut {0} is geen geldig nummer diff --git a/BuildingQuality/sample-code/gebish/grails-app/i18n/messages_pt_BR.properties b/BuildingQuality/sample-code/gebish/grails-app/i18n/messages_pt_BR.properties new file mode 100644 index 0000000..0c368f2 --- /dev/null +++ b/BuildingQuality/sample-code/gebish/grails-app/i18n/messages_pt_BR.properties @@ -0,0 +1,59 @@ +# +# Translated by Lucas Teixeira - lucastex@gmail.com +# + +default.doesnt.match.message=O campo [{0}] da classe [{1}] com o valor [{2}] não atende ao padrão definido [{3}] +default.invalid.url.message=O campo [{0}] da classe [{1}] com o valor [{2}] não é uma URL válida +default.invalid.creditCard.message=O campo [{0}] da classe [{1}] com o valor [{2}] não é um número válido de cartão de crédito +default.invalid.email.message=O campo [{0}] da classe [{1}] com o valor [{2}] não é um endereço de email válido. +default.invalid.range.message=O campo [{0}] da classe [{1}] com o valor [{2}] não está entre a faixa de valores válida de [{3}] até [{4}] +default.invalid.size.message=O campo [{0}] da classe [{1}] com o valor [{2}] não está na faixa de tamanho válida de [{3}] até [{4}] +default.invalid.max.message=O campo [{0}] da classe [{1}] com o valor [{2}] ultrapass o valor máximo [{3}] +default.invalid.min.message=O campo [{0}] da classe [{1}] com o valor [{2}] não atinge o valor mínimo [{3}] +default.invalid.max.size.message=O campo [{0}] da classe [{1}] com o valor [{2}] ultrapassa o tamanho máximo de [{3}] +default.invalid.min.size.message=O campo [{0}] da classe [{1}] com o valor [{2}] não atinge o tamanho mínimo de [{3}] +default.invalid.validator.message=O campo [{0}] da classe [{1}] com o valor [{2}] não passou na validação +default.not.inlist.message=O campo [{0}] da classe [{1}] com o valor [{2}] não é um valor dentre os permitidos na lista [{3}] +default.blank.message=O campo [{0}] da classe [{1}] não pode ficar em branco +default.not.equal.message=O campo [{0}] da classe [{1}] com o valor [{2}] não pode ser igual a [{3}] +default.null.message=O campo [{0}] da classe [{1}] não pode ser vazia +default.not.unique.message=O campo [{0}] da classe [{1}] com o valor [{2}] deve ser único + +default.paginate.prev=Anterior +default.paginate.next=Próximo +default.boolean.true=Sim +default.boolean.false=Não +default.date.format=dd/MM/yyyy HH:mm:ss z +default.number.format=0 + +default.created.message={0} {1} criado +default.updated.message={0} {1} atualizado +default.deleted.message={0} {1} removido +default.not.deleted.message={0} {1} não pode ser removido +default.not.found.message={0} não foi encontrado com id {1} +default.optimistic.locking.failure=Outro usuário atualizou este [{0}] enquanto você tentou salvá-lo + +default.home.label=Principal +default.list.label={0} Listagem +default.add.label=Adicionar {0} +default.new.label=Novo {0} +default.create.label=Criar {0} +default.show.label=Ver {0} +default.edit.label=Editar {0} + +default.button.create.label=Criar +default.button.edit.label=Editar +default.button.update.label=Alterar +default.button.delete.label=Remover +default.button.delete.confirm.message=Tem certeza? + +# Mensagens de erro em atribuição de valores. Use "typeMismatch.$className.$propertyName" para customizar (eg typeMismatch.Book.author) +typeMismatch.java.net.URL=O campo {0} deve ser uma URL válida. +typeMismatch.java.net.URI=O campo {0} deve ser uma URI válida. +typeMismatch.java.util.Date=O campo {0} deve ser uma data válida +typeMismatch.java.lang.Double=O campo {0} deve ser um número válido. +typeMismatch.java.lang.Integer=O campo {0} deve ser um número válido. +typeMismatch.java.lang.Long=O campo {0} deve ser um número válido. +typeMismatch.java.lang.Short=O campo {0} deve ser um número válido. +typeMismatch.java.math.BigDecimal=O campo {0} deve ser um número válido. +typeMismatch.java.math.BigInteger=O campo {0} deve ser um número válido. \ No newline at end of file diff --git a/BuildingQuality/sample-code/gebish/grails-app/i18n/messages_pt_PT.properties b/BuildingQuality/sample-code/gebish/grails-app/i18n/messages_pt_PT.properties new file mode 100644 index 0000000..43a6416 --- /dev/null +++ b/BuildingQuality/sample-code/gebish/grails-app/i18n/messages_pt_PT.properties @@ -0,0 +1,34 @@ +# +# translation by miguel.ping@gmail.com, based on pt_BR translation by Lucas Teixeira - lucastex@gmail.com +# + +default.doesnt.match.message=O campo [{0}] da classe [{1}] com o valor [{2}] não corresponde ao padrão definido [{3}] +default.invalid.url.message=O campo [{0}] da classe [{1}] com o valor [{2}] não é um URL válido +default.invalid.creditCard.message=O campo [{0}] da classe [{1}] com o valor [{2}] não é um número válido de cartão de crédito +default.invalid.email.message=O campo [{0}] da classe [{1}] com o valor [{2}] não é um endereço de email válido. +default.invalid.range.message=O campo [{0}] da classe [{1}] com o valor [{2}] não está dentro dos limites de valores válidos de [{3}] a [{4}] +default.invalid.size.message=O campo [{0}] da classe [{1}] com o valor [{2}] está fora dos limites de tamanho válido de [{3}] a [{4}] +default.invalid.max.message=O campo [{0}] da classe [{1}] com o valor [{2}] ultrapassa o valor máximo [{3}] +default.invalid.min.message=O campo [{0}] da classe [{1}] com o valor [{2}] não atinge o valor mínimo [{3}] +default.invalid.max.size.message=O campo [{0}] da classe [{1}] com o valor [{2}] ultrapassa o tamanho máximo de [{3}] +default.invalid.min.size.message=O campo [{0}] da classe [{1}] com o valor [{2}] não atinge o tamanho mínimo de [{3}] +default.invalid.validator.message=O campo [{0}] da classe [{1}] com o valor [{2}] não passou na validação +default.not.inlist.message=O campo [{0}] da classe [{1}] com o valor [{2}] não se encontra nos valores permitidos da lista [{3}] +default.blank.message=O campo [{0}] da classe [{1}] não pode ser vazio +default.not.equal.message=O campo [{0}] da classe [{1}] com o valor [{2}] não pode ser igual a [{3}] +default.null.message=O campo [{0}] da classe [{1}] não pode ser vazio +default.not.unique.message=O campo [{0}] da classe [{1}] com o valor [{2}] deve ser único + +default.paginate.prev=Anterior +default.paginate.next=Próximo + +# Mensagens de erro em atribuição de valores. Use "typeMismatch.$className.$propertyName" para personalizar(eg typeMismatch.Book.author) +typeMismatch.java.net.URL=O campo {0} deve ser um URL válido. +typeMismatch.java.net.URI=O campo {0} deve ser um URI válido. +typeMismatch.java.util.Date=O campo {0} deve ser uma data válida +typeMismatch.java.lang.Double=O campo {0} deve ser um número válido. +typeMismatch.java.lang.Integer=O campo {0} deve ser um número válido. +typeMismatch.java.lang.Long=O campo {0} deve ser um número valido. +typeMismatch.java.lang.Short=O campo {0} deve ser um número válido. +typeMismatch.java.math.BigDecimal=O campo {0} deve ser um número válido. +typeMismatch.java.math.BigInteger=O campo {0} deve ser um número válido. diff --git a/BuildingQuality/sample-code/gebish/grails-app/i18n/messages_ru.properties b/BuildingQuality/sample-code/gebish/grails-app/i18n/messages_ru.properties new file mode 100644 index 0000000..02239db --- /dev/null +++ b/BuildingQuality/sample-code/gebish/grails-app/i18n/messages_ru.properties @@ -0,0 +1,31 @@ +default.doesnt.match.message=Значение [{2}] поля [{0}] класса [{1}] не соответствует образцу [{3}] +default.invalid.url.message=Значение [{2}] поля [{0}] класса [{1}] не является допустимым URL-адресом +default.invalid.creditCard.message=Значение [{2}] поля [{0}] класса [{1}] не является допустимым номером кредитной карты +default.invalid.email.message=Значение [{2}] поля [{0}] класса [{1}] не является допустимым e-mail адресом +default.invalid.range.message=Значение [{2}] поля [{0}] класса [{1}] не попадает в допустимый интервал от [{3}] до [{4}] +default.invalid.size.message=Размер поля [{0}] класса [{1}] (значение: [{2}]) не попадает в допустимый интервал от [{3}] до [{4}] +default.invalid.max.message=Значение [{2}] поля [{0}] класса [{1}] больше чем максимально допустимое значение [{3}] +default.invalid.min.message=Значение [{2}] поля [{0}] класса [{1}] меньше чем минимально допустимое значение [{3}] +default.invalid.max.size.message=Размер поля [{0}] класса [{1}] (значение: [{2}]) больше чем максимально допустимый размер [{3}] +default.invalid.min.size.message=Размер поля [{0}] класса [{1}] (значение: [{2}]) меньше чем минимально допустимый размер [{3}] +default.invalid.validator.message=Значение [{2}] поля [{0}] класса [{1}] не допустимо +default.not.inlist.message=Значение [{2}] поля [{0}] класса [{1}] не попадает в список допустимых значений [{3}] +default.blank.message=Поле [{0}] класса [{1}] не может быть пустым +default.not.equal.message=Значение [{2}] поля [{0}] класса [{1}] не может быть равно [{3}] +default.null.message=Поле [{0}] класса [{1}] не может иметь значение null +default.not.unique.message=Значение [{2}] поля [{0}] класса [{1}] должно быть уникальным + +default.paginate.prev=Предыдушая страница +default.paginate.next=Следующая страница + +# Ошибки при присвоении данных. Для точной настройки для полей классов используйте +# формат "typeMismatch.$className.$propertyName" (например, typeMismatch.Book.author) +typeMismatch.java.net.URL=Значение поля {0} не является допустимым URL +typeMismatch.java.net.URI=Значение поля {0} не является допустимым URI +typeMismatch.java.util.Date=Значение поля {0} не является допустимой датой +typeMismatch.java.lang.Double=Значение поля {0} не является допустимым числом +typeMismatch.java.lang.Integer=Значение поля {0} не является допустимым числом +typeMismatch.java.lang.Long=Значение поля {0} не является допустимым числом +typeMismatch.java.lang.Short=Значение поля {0} не является допустимым числом +typeMismatch.java.math.BigDecimal=Значение поля {0} не является допустимым числом +typeMismatch.java.math.BigInteger=Значение поля {0} не является допустимым числом diff --git a/BuildingQuality/sample-code/gebish/grails-app/i18n/messages_sv.properties b/BuildingQuality/sample-code/gebish/grails-app/i18n/messages_sv.properties new file mode 100644 index 0000000..61899d7 --- /dev/null +++ b/BuildingQuality/sample-code/gebish/grails-app/i18n/messages_sv.properties @@ -0,0 +1,55 @@ +default.doesnt.match.message=Attributet [{0}] för klassen [{1}] med värde [{2}] matchar inte mot uttrycket [{3}] +default.invalid.url.message=Attributet [{0}] för klassen [{1}] med värde [{2}] är inte en giltig URL +default.invalid.creditCard.message=Attributet [{0}] för klassen [{1}] med värde [{2}] är inte ett giltigt kreditkortsnummer +default.invalid.email.message=Attributet [{0}] för klassen [{1}] med värde [{2}] är inte en giltig e-postadress +default.invalid.range.message=Attributet [{0}] för klassen [{1}] med värde [{2}] är inte inom intervallet [{3}] till [{4}] +default.invalid.size.message=Attributet [{0}] för klassen [{1}] med värde [{2}] har en storlek som inte är inom [{3}] till [{4}] +default.invalid.max.message=Attributet [{0}] för klassen [{1}] med värde [{2}] överskrider maxvärdet [{3}] +default.invalid.min.message=Attributet [{0}] för klassen [{1}] med värde [{2}] är mindre än minimivärdet [{3}] +default.invalid.max.size.message=Attributet [{0}] för klassen [{1}] med värde [{2}] överskrider maxstorleken [{3}] +default.invalid.min.size.message=Attributet [{0}] för klassen [{1}] med värde [{2}] är mindre än minimistorleken [{3}] +default.invalid.validator.message=Attributet [{0}] för klassen [{1}] med värde [{2}] är inte giltigt enligt anpassad regel +default.not.inlist.message=Attributet [{0}] för klassen [{1}] med värde [{2}] är inte giltigt, måste vara ett av [{3}] +default.blank.message=Attributet [{0}] för klassen [{1}] får inte vara tomt +default.not.equal.message=Attributet [{0}] för klassen [{1}] med värde [{2}] får inte vara lika med [{3}] +default.null.message=Attributet [{0}] för klassen [{1}] får inte vara tomt +default.not.unique.message=Attributet [{0}] för klassen [{1}] med värde [{2}] måste vara unikt + +default.paginate.prev=Föregående +default.paginate.next=Nästa +default.boolean.true=Sant +default.boolean.false=Falskt +default.date.format=yyyy-MM-dd HH:mm:ss z +default.number.format=0 + +default.created.message={0} {1} skapades +default.updated.message={0} {1} uppdaterades +default.deleted.message={0} {1} borttagen +default.not.deleted.message={0} {1} kunde inte tas bort +default.not.found.message={0} med id {1} kunde inte hittas +default.optimistic.locking.failure=En annan användare har uppdaterat det här {0} objektet medan du redigerade det + +default.home.label=Hem +default.list.label= {0} - Lista +default.add.label=Lägg till {0} +default.new.label=Skapa {0} +default.create.label=Skapa {0} +default.show.label=Visa {0} +default.edit.label=Ändra {0} + +default.button.create.label=Skapa +default.button.edit.label=Ändra +default.button.update.label=Uppdatera +default.button.delete.label=Ta bort +default.button.delete.confirm.message=Är du säker? + +# Data binding errors. Use "typeMismatch.$className.$propertyName to customize (eg typeMismatch.Book.author) +typeMismatch.java.net.URL=Värdet för {0} måste vara en giltig URL +typeMismatch.java.net.URI=Värdet för {0} måste vara en giltig URI +typeMismatch.java.util.Date=Värdet {0} måste vara ett giltigt datum +typeMismatch.java.lang.Double=Värdet {0} måste vara ett giltigt nummer +typeMismatch.java.lang.Integer=Värdet {0} måste vara ett giltigt heltal +typeMismatch.java.lang.Long=Värdet {0} måste vara ett giltigt heltal +typeMismatch.java.lang.Short=Värdet {0} måste vara ett giltigt heltal +typeMismatch.java.math.BigDecimal=Värdet {0} måste vara ett giltigt nummer +typeMismatch.java.math.BigInteger=Värdet {0} måste vara ett giltigt heltal \ No newline at end of file diff --git a/BuildingQuality/sample-code/gebish/grails-app/i18n/messages_th.properties b/BuildingQuality/sample-code/gebish/grails-app/i18n/messages_th.properties new file mode 100644 index 0000000..4f4076d --- /dev/null +++ b/BuildingQuality/sample-code/gebish/grails-app/i18n/messages_th.properties @@ -0,0 +1,55 @@ +default.doesnt.match.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] ไม่ถูกต้องตามรูปแบบที่กำหนดไว้ใน [{3}] +default.invalid.url.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] ไม่ถูกต้องตามรูปแบบ URL +default.invalid.creditCard.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] ไม่ถูกต้องตามรูปแบบหมายเลขบัตรเครดิต +default.invalid.email.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] ไม่ถูกต้องตามรูปแบบอีเมล์ +default.invalid.range.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] ไม่ได้มีค่าที่ถูกต้องในช่วงจาก [{3}] ถึง [{4}] +default.invalid.size.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] ไม่ได้มีขนาดที่ถูกต้องในช่วงจาก [{3}] ถึง [{4}] +default.invalid.max.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] มีค่าเกิดกว่าค่ามากสุด [{3}] +default.invalid.min.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] มีค่าน้อยกว่าค่าต่ำสุด [{3}] +default.invalid.max.size.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] มีขนาดเกินกว่าขนาดมากสุดของ [{3}] +default.invalid.min.size.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] มีขนาดต่ำกว่าขนาดต่ำสุดของ [{3}] +default.invalid.validator.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] ไม่ผ่านการทวนสอบค่าที่ตั้งขึ้น +default.not.inlist.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] ไม่ได้อยู่ในรายการต่อไปนี้ [{3}] +default.blank.message=คุณสมบัติ [{0}] ของคลาส [{1}] ไม่สามารถเป็นค่าว่างได้ +default.not.equal.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] ไม่สามารถเท่ากับ [{3}] ได้ +default.null.message=คุณสมบัติ [{0}] ของคลาส [{1}] ไม่สามารถเป็น null ได้ +default.not.unique.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] จะต้องไม่ซ้ำ (unique) + +default.paginate.prev=ก่อนหน้า +default.paginate.next=ถัดไป +default.boolean.true=จริง +default.boolean.false=เท็จ +default.date.format=dd-MM-yyyy HH:mm:ss z +default.number.format=0 + +default.created.message=สร้าง {0} {1} เรียบร้อยแล้ว +default.updated.message=ปรับปรุง {0} {1} เรียบร้อยแล้ว +default.deleted.message=ลบ {0} {1} เรียบร้อยแล้ว +default.not.deleted.message=ไม่สามารถลบ {0} {1} +default.not.found.message=ไม่พบ {0} ด้วย id {1} นี้ +default.optimistic.locking.failure=มีผู้ใช้ท่านอื่นปรับปรุง {0} ขณะที่คุณกำลังแก้ไขข้อมูลอยู่ + +default.home.label=หน้าแรก +default.list.label=รายการ {0} +default.add.label=เพิ่ม {0} +default.new.label=สร้าง {0} ใหม่ +default.create.label=สร้าง {0} +default.show.label=แสดง {0} +default.edit.label=แก้ไข {0} + +default.button.create.label=สร้าง +default.button.edit.label=แก้ไข +default.button.update.label=ปรับปรุง +default.button.delete.label=ลบ +default.button.delete.confirm.message=คุณแน่ใจหรือไม่ ? + +# Data binding errors. Use "typeMismatch.$className.$propertyName to customize (eg typeMismatch.Book.author) +typeMismatch.java.net.URL=คุณสมบัติ '{0}' จะต้องเป็นค่า URL ที่ถูกต้อง +typeMismatch.java.net.URI=คุณสมบัติ '{0}' จะต้องเป็นค่า URI ที่ถูกต้อง +typeMismatch.java.util.Date=คุณสมบัติ '{0}' จะต้องมีค่าเป็นวันที่ +typeMismatch.java.lang.Double=คุณสมบัติ '{0}' จะต้องมีค่าเป็นจำนวนประเภท Double +typeMismatch.java.lang.Integer=คุณสมบัติ '{0}' จะต้องมีค่าเป็นจำนวนประเภท Integer +typeMismatch.java.lang.Long=คุณสมบัติ '{0}' จะต้องมีค่าเป็นจำนวนประเภท Long +typeMismatch.java.lang.Short=คุณสมบัติ '{0}' จะต้องมีค่าเป็นจำนวนประเภท Short +typeMismatch.java.math.BigDecimal=คุณสมบัติ '{0}' จะต้องมีค่าเป็นจำนวนประเภท BigDecimal +typeMismatch.java.math.BigInteger=คุณสมบัติ '{0}' จะต้องมีค่าเป็นจำนวนประเภท BigInteger diff --git a/BuildingQuality/sample-code/gebish/grails-app/i18n/messages_zh_CN.properties b/BuildingQuality/sample-code/gebish/grails-app/i18n/messages_zh_CN.properties new file mode 100644 index 0000000..782580b --- /dev/null +++ b/BuildingQuality/sample-code/gebish/grails-app/i18n/messages_zh_CN.properties @@ -0,0 +1,18 @@ +default.blank.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u4E0D\u80FD\u4E3A\u7A7A +default.doesnt.match.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u4E0E\u5B9A\u4E49\u7684\u6A21\u5F0F [{3}]\u4E0D\u5339\u914D +default.invalid.creditCard.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u4E0D\u662F\u4E00\u4E2A\u6709\u6548\u7684\u4FE1\u7528\u5361\u53F7 +default.invalid.email.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u4E0D\u662F\u4E00\u4E2A\u5408\u6CD5\u7684\u7535\u5B50\u90AE\u4EF6\u5730\u5740 +default.invalid.max.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u6BD4\u6700\u5927\u503C [{3}]\u8FD8\u5927 +default.invalid.max.size.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u7684\u5927\u5C0F\u6BD4\u6700\u5927\u503C [{3}]\u8FD8\u5927 +default.invalid.min.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u6BD4\u6700\u5C0F\u503C [{3}]\u8FD8\u5C0F +default.invalid.min.size.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u7684\u5927\u5C0F\u6BD4\u6700\u5C0F\u503C [{3}]\u8FD8\u5C0F +default.invalid.range.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u4E0D\u5728\u5408\u6CD5\u7684\u8303\u56F4\u5185( [{3}] \uFF5E [{4}] ) +default.invalid.size.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u7684\u5927\u5C0F\u4E0D\u5728\u5408\u6CD5\u7684\u8303\u56F4\u5185( [{3}] \uFF5E [{4}] ) +default.invalid.url.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u4E0D\u662F\u4E00\u4E2A\u5408\u6CD5\u7684URL +default.invalid.validator.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u672A\u80FD\u901A\u8FC7\u81EA\u5B9A\u4E49\u7684\u9A8C\u8BC1 +default.not.equal.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u4E0E[{3}]\u4E0D\u76F8\u7B49 +default.not.inlist.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u4E0D\u5728\u5217\u8868\u7684\u53D6\u503C\u8303\u56F4\u5185 +default.not.unique.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u5FC5\u987B\u662F\u552F\u4E00\u7684 +default.null.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u4E0D\u80FD\u4E3Anull +default.paginate.next=\u4E0B\u9875 +default.paginate.prev=\u4E0A\u9875 diff --git a/BuildingQuality/sample-code/gebish/grails-app/views/error.gsp b/BuildingQuality/sample-code/gebish/grails-app/views/error.gsp new file mode 100644 index 0000000..64a0b08 --- /dev/null +++ b/BuildingQuality/sample-code/gebish/grails-app/views/error.gsp @@ -0,0 +1,11 @@ + + + + Grails Runtime Exception + + + + + + + \ No newline at end of file diff --git a/BuildingQuality/sample-code/gebish/grails-app/views/index.gsp b/BuildingQuality/sample-code/gebish/grails-app/views/index.gsp new file mode 100644 index 0000000..11e2838 --- /dev/null +++ b/BuildingQuality/sample-code/gebish/grails-app/views/index.gsp @@ -0,0 +1,122 @@ + + + + + Welcome to Grails + + + + + +
+

Welcome to Grails

+

Congratulations, you have successfully started your first Grails application! At the moment + this is the default page, feel free to modify it to either redirect to a controller or display whatever + content you may choose. Below is a list of controllers that are currently deployed in this application, + click on each to execute its default action:

+ + +
+ + diff --git a/BuildingQuality/sample-code/gebish/grails-app/views/layouts/main.gsp b/BuildingQuality/sample-code/gebish/grails-app/views/layouts/main.gsp new file mode 100644 index 0000000..cebc5b1 --- /dev/null +++ b/BuildingQuality/sample-code/gebish/grails-app/views/layouts/main.gsp @@ -0,0 +1,28 @@ + + + + + + + + + + <g:layoutTitle default="Grails"/> + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/BuildingQuality/sample-code/gebish/grails-app/views/person/_form.gsp b/BuildingQuality/sample-code/gebish/grails-app/views/person/_form.gsp new file mode 100644 index 0000000..176070e --- /dev/null +++ b/BuildingQuality/sample-code/gebish/grails-app/views/person/_form.gsp @@ -0,0 +1,28 @@ +<%@ page import="gebish.Person" %> + + + +
+ + +
+ +
+ + +
+ +
+ + +
+ diff --git a/BuildingQuality/sample-code/gebish/grails-app/views/person/create.gsp b/BuildingQuality/sample-code/gebish/grails-app/views/person/create.gsp new file mode 100644 index 0000000..6a3970b --- /dev/null +++ b/BuildingQuality/sample-code/gebish/grails-app/views/person/create.gsp @@ -0,0 +1,39 @@ +<%@ page import="gebish.Person" %> + + + + + + <g:message code="default.create.label" args="[entityName]" /> + + + + +
+

+ +
${flash.message}
+
+ + + + +
+ +
+
+ +
+
+
+ + diff --git a/BuildingQuality/sample-code/gebish/grails-app/views/person/edit.gsp b/BuildingQuality/sample-code/gebish/grails-app/views/person/edit.gsp new file mode 100644 index 0000000..f30d2ff --- /dev/null +++ b/BuildingQuality/sample-code/gebish/grails-app/views/person/edit.gsp @@ -0,0 +1,43 @@ +<%@ page import="gebish.Person" %> + + + + + + <g:message code="default.edit.label" args="[entityName]" /> + + + + +
+

+ +
${flash.message}
+
+ + + + + + +
+ +
+
+ + +
+
+
+ + diff --git a/BuildingQuality/sample-code/gebish/grails-app/views/person/list.gsp b/BuildingQuality/sample-code/gebish/grails-app/views/person/list.gsp new file mode 100644 index 0000000..7aec8f8 --- /dev/null +++ b/BuildingQuality/sample-code/gebish/grails-app/views/person/list.gsp @@ -0,0 +1,54 @@ + +<%@ page import="gebish.Person" %> + + + + + + <g:message code="default.list.label" args="[entityName]" /> + + + + +
+

+ +
${flash.message}
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
${fieldValue(bean: personInstance, field: "enabled")}${fieldValue(bean: personInstance, field: "firstName")}${fieldValue(bean: personInstance, field: "lastName")}
+ +
+ + diff --git a/BuildingQuality/sample-code/gebish/grails-app/views/person/show.gsp b/BuildingQuality/sample-code/gebish/grails-app/views/person/show.gsp new file mode 100644 index 0000000..d486148 --- /dev/null +++ b/BuildingQuality/sample-code/gebish/grails-app/views/person/show.gsp @@ -0,0 +1,63 @@ + +<%@ page import="gebish.Person" %> + + + + + + <g:message code="default.show.label" args="[entityName]" /> + + + + +
+

+ +
${flash.message}
+
+
    + + +
  1. + + + + +
  2. +
    + + +
  3. + + + + +
  4. +
    + + +
  5. + + + + +
  6. +
    + +
+ +
+ + + +
+
+
+ + diff --git a/BuildingQuality/sample-code/gebish/projectFilesBackup/gebish.ipr b/BuildingQuality/sample-code/gebish/projectFilesBackup/gebish.ipr new file mode 100644 index 0000000..00ea9cf --- /dev/null +++ b/BuildingQuality/sample-code/gebish/projectFilesBackup/gebish.ipr @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/BuildingQuality/sample-code/gebish/test/functional/GebConfig.groovy b/BuildingQuality/sample-code/gebish/test/functional/GebConfig.groovy new file mode 100644 index 0000000..f349b03 --- /dev/null +++ b/BuildingQuality/sample-code/gebish/test/functional/GebConfig.groovy @@ -0,0 +1,43 @@ +/* + This is the Geb configuration file. + + See: http://www.gebish.org/manual/current/configuration.html +*/ + +import org.openqa.selenium.htmlunit.HtmlUnitDriver +import org.openqa.selenium.firefox.FirefoxDriver +import org.openqa.selenium.chrome.ChromeDriver +import org.openqa.selenium.ie.InternetExplorerDriver + +// Use htmlunit as the default +// See: http://code.google.com/p/selenium/wiki/HtmlUnitDriver +driver = { + def driver = new HtmlUnitDriver() + driver.javascriptEnabled = true + driver +} + +environments { + + // run as “grails -Dgeb.env=chrome test-app” + // See: http://code.google.com/p/selenium/wiki/ChromeDriver + // to run with chrome, download server per instructions on wiki link above + // then run with webdriver.chrome.driver set + // e.g. -Dwebdriver.chrome.driver="/Users/mjhugo/Downloads/chromedriver" + chrome { + driver = { new ChromeDriver() } + } + + // run as “grails -Dgeb.env=firefox test-app” + // See: http://code.google.com/p/selenium/wiki/FirefoxDriver + firefox { + driver = { new FirefoxDriver() } + } + + // run as “grails -Dgeb.env=ie test-app” + // See: http://code.google.com/p/selenium/wiki/InternetExplorerDriver + ie { + driver = { new InternetExplorerDriver() } + } + +} \ No newline at end of file diff --git a/BuildingQuality/sample-code/gebish/test/functional/geb/PersonCRUDTests.groovy b/BuildingQuality/sample-code/gebish/test/functional/geb/PersonCRUDTests.groovy new file mode 100644 index 0000000..7de8f29 --- /dev/null +++ b/BuildingQuality/sample-code/gebish/test/functional/geb/PersonCRUDTests.groovy @@ -0,0 +1,49 @@ +package geb + +import geb.junit4.GebReportingTest + +import pages.* +import org.junit.Test + +class PersonCRUDTests extends GebReportingTest { + + @Test + void doSomeCrud() { + to ListPage + int initialRowSize = personRows.size() + newPersonButton.click() + + assert at(CreatePage) + enabled = true + firstName = "Luke" + lastName = "Daley" + createButton.click() + + assert at(ShowPage) + assert enabled == true + assert firstName == "Luke" + assert lastName == "Daley" + editButton.click() + + assert at(EditPage) + enabled = false + updateButton.click() + + assert at(ShowPage) + + to ListPage + assert personRows.size() == initialRowSize + 1 + def row = personRow(0) + assert row.firstName == "Luke" + assert row.lastName == "Daley" + row.showLink.click() + + assert at(ShowPage) + def deletedId = id + withConfirm { deleteButton.click() } + + assert at(ListPage) + assert message == "Person $deletedId deleted" + assert personRows.size() == initialRowSize + } +} \ No newline at end of file diff --git a/BuildingQuality/sample-code/gebish/test/functional/pages/CreatePage.groovy b/BuildingQuality/sample-code/gebish/test/functional/pages/CreatePage.groovy new file mode 100644 index 0000000..fa5e3fc --- /dev/null +++ b/BuildingQuality/sample-code/gebish/test/functional/pages/CreatePage.groovy @@ -0,0 +1,15 @@ +package pages + +import pages.modules.* + +class CreatePage extends ScaffoldPage { + + static at = { + heading.text() ==~ /Create.+/ + } + + static content = { + createButton(to: ShowPage) { create() } + } + +} \ No newline at end of file diff --git a/BuildingQuality/sample-code/gebish/test/functional/pages/EditPage.groovy b/BuildingQuality/sample-code/gebish/test/functional/pages/EditPage.groovy new file mode 100644 index 0000000..712cb07 --- /dev/null +++ b/BuildingQuality/sample-code/gebish/test/functional/pages/EditPage.groovy @@ -0,0 +1,16 @@ +package pages + +import pages.modules.* + +class EditPage extends ScaffoldPage { + + static at = { + heading.text() ==~ /Edit.+/ + } + + static content = { + updateButton(to: ShowPage) { $("input", value: "Update") } + deleteButton(to: ListPage) { $("input", value: "Delete") } + } + +} \ No newline at end of file diff --git a/BuildingQuality/sample-code/gebish/test/functional/pages/ListPage.groovy b/BuildingQuality/sample-code/gebish/test/functional/pages/ListPage.groovy new file mode 100644 index 0000000..5e39041 --- /dev/null +++ b/BuildingQuality/sample-code/gebish/test/functional/pages/ListPage.groovy @@ -0,0 +1,29 @@ +package pages + +import geb.Module + +class ListPage extends ScaffoldPage { + static url = "person/list" + + static at = { + heading.text() ==~ /Person List/ + } + + static content = { + newPersonButton(to: CreatePage) { $("a", text: "New Person") } + peopleTable { $("div.scaffold-list table", 0) } + personRow { module PersonRow, personRows[it] } + personRows(required: false) { peopleTable.find("tbody").find("tr") } + } +} + +class PersonRow extends Module { + static content = { + cell { $("td", it) } + cellText { cell(it).text() } + enabled { Boolean.valueOf(cellText(0)) } + firstName { cellText(1) } + lastName { cellText(2) } + showLink(to: ShowPage) { cell(0).find("a") } + } +} \ No newline at end of file diff --git a/BuildingQuality/sample-code/gebish/test/functional/pages/ScaffoldPage.groovy b/BuildingQuality/sample-code/gebish/test/functional/pages/ScaffoldPage.groovy new file mode 100644 index 0000000..c617cc1 --- /dev/null +++ b/BuildingQuality/sample-code/gebish/test/functional/pages/ScaffoldPage.groovy @@ -0,0 +1,10 @@ +package pages + +import geb.Page + +class ScaffoldPage extends Page { + static content = { + heading { $("h1") } + message { $("div.message").text() } + } +} \ No newline at end of file diff --git a/BuildingQuality/sample-code/gebish/test/functional/pages/ShowPage.groovy b/BuildingQuality/sample-code/gebish/test/functional/pages/ShowPage.groovy new file mode 100644 index 0000000..8e5087e --- /dev/null +++ b/BuildingQuality/sample-code/gebish/test/functional/pages/ShowPage.groovy @@ -0,0 +1,18 @@ +package pages + +class ShowPage extends ScaffoldPage { + + static at = { + heading.text() ==~ /Show Person/ + } + + static content = { + editButton(to: EditPage) { $("a", text: "Edit") } + deleteButton(to: ListPage) { $("input", value: "Delete") } + row { $("span", text: it).parent() } + value { row(it).find("span.property-value").text() } + enabled { Boolean.valueOf(value("Enabled")) } + firstName { value("First Name") } + lastName { value("Last Name") } + } +} diff --git a/BuildingQuality/sample-code/gebish/web-app/WEB-INF/applicationContext.xml b/BuildingQuality/sample-code/gebish/web-app/WEB-INF/applicationContext.xml new file mode 100644 index 0000000..69fbef3 --- /dev/null +++ b/BuildingQuality/sample-code/gebish/web-app/WEB-INF/applicationContext.xml @@ -0,0 +1,33 @@ + + + + + Grails application factory bean + + + + + + A bean that manages Grails plugins + + + + + + + + + + + + + + + + utf-8 + + + \ No newline at end of file diff --git a/BuildingQuality/sample-code/gebish/web-app/WEB-INF/sitemesh.xml b/BuildingQuality/sample-code/gebish/web-app/WEB-INF/sitemesh.xml new file mode 100644 index 0000000..72399ce --- /dev/null +++ b/BuildingQuality/sample-code/gebish/web-app/WEB-INF/sitemesh.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/BuildingQuality/sample-code/gebish/web-app/WEB-INF/tld/c.tld b/BuildingQuality/sample-code/gebish/web-app/WEB-INF/tld/c.tld new file mode 100644 index 0000000..5e18236 --- /dev/null +++ b/BuildingQuality/sample-code/gebish/web-app/WEB-INF/tld/c.tld @@ -0,0 +1,572 @@ + + + + + JSTL 1.2 core library + JSTL core + 1.2 + c + http://java.sun.com/jsp/jstl/core + + + + Provides core validation features for JSTL tags. + + + org.apache.taglibs.standard.tlv.JstlCoreTLV + + + + + + Catches any Throwable that occurs in its body and optionally + exposes it. + + catch + org.apache.taglibs.standard.tag.common.core.CatchTag + JSP + + +Name of the exported scoped variable for the +exception thrown from a nested action. The type of the +scoped variable is the type of the exception thrown. + + var + false + false + + + + + + Simple conditional tag that establishes a context for + mutually exclusive conditional operations, marked by + <when> and <otherwise> + + choose + org.apache.taglibs.standard.tag.common.core.ChooseTag + JSP + + + + + Simple conditional tag, which evalutes its body if the + supplied condition is true and optionally exposes a Boolean + scripting variable representing the evaluation of this condition + + if + org.apache.taglibs.standard.tag.rt.core.IfTag + JSP + + +The test condition that determines whether or +not the body content should be processed. + + test + true + true + boolean + + + +Name of the exported scoped variable for the +resulting value of the test condition. The type +of the scoped variable is Boolean. + + var + false + false + + + +Scope for var. + + scope + false + false + + + + + + Retrieves an absolute or relative URL and exposes its contents + to either the page, a String in 'var', or a Reader in 'varReader'. + + import + org.apache.taglibs.standard.tag.rt.core.ImportTag + org.apache.taglibs.standard.tei.ImportTEI + JSP + + +The URL of the resource to import. + + url + true + true + + + +Name of the exported scoped variable for the +resource's content. The type of the scoped +variable is String. + + var + false + false + + + +Scope for var. + + scope + false + false + + + +Name of the exported scoped variable for the +resource's content. The type of the scoped +variable is Reader. + + varReader + false + false + + + +Name of the context when accessing a relative +URL resource that belongs to a foreign +context. + + context + false + true + + + +Character encoding of the content at the input +resource. + + charEncoding + false + true + + + + + + The basic iteration tag, accepting many different + collection types and supporting subsetting and other + functionality + + forEach + org.apache.taglibs.standard.tag.rt.core.ForEachTag + org.apache.taglibs.standard.tei.ForEachTEI + JSP + + +Collection of items to iterate over. + + items + false + true + java.lang.Object + + java.lang.Object + + + + +If items specified: +Iteration begins at the item located at the +specified index. First item of the collection has +index 0. +If items not specified: +Iteration begins with index set at the value +specified. + + begin + false + true + int + + + +If items specified: +Iteration ends at the item located at the +specified index (inclusive). +If items not specified: +Iteration ends when index reaches the value +specified. + + end + false + true + int + + + +Iteration will only process every step items of +the collection, starting with the first one. + + step + false + true + int + + + +Name of the exported scoped variable for the +current item of the iteration. This scoped +variable has nested visibility. Its type depends +on the object of the underlying collection. + + var + false + false + + + +Name of the exported scoped variable for the +status of the iteration. Object exported is of type +javax.servlet.jsp.jstl.core.LoopTagStatus. This scoped variable has nested +visibility. + + varStatus + false + false + + + + + + Iterates over tokens, separated by the supplied delimeters + + forTokens + org.apache.taglibs.standard.tag.rt.core.ForTokensTag + JSP + + +String of tokens to iterate over. + + items + true + true + java.lang.String + + java.lang.String + + + + +The set of delimiters (the characters that +separate the tokens in the string). + + delims + true + true + java.lang.String + + + +Iteration begins at the token located at the +specified index. First token has index 0. + + begin + false + true + int + + + +Iteration ends at the token located at the +specified index (inclusive). + + end + false + true + int + + + +Iteration will only process every step tokens +of the string, starting with the first one. + + step + false + true + int + + + +Name of the exported scoped variable for the +current item of the iteration. This scoped +variable has nested visibility. + + var + false + false + + + +Name of the exported scoped variable for the +status of the iteration. Object exported is of +type +javax.servlet.jsp.jstl.core.LoopTag +Status. This scoped variable has nested +visibility. + + varStatus + false + false + + + + + + Like <%= ... >, but for expressions. + + out + org.apache.taglibs.standard.tag.rt.core.OutTag + JSP + + +Expression to be evaluated. + + value + true + true + + + +Default value if the resulting value is null. + + default + false + true + + + +Determines whether characters <,>,&,'," in the +resulting string should be converted to their +corresponding character entity codes. Default value is +true. + + escapeXml + false + true + + + + + + + Subtag of <choose> that follows <when> tags + and runs only if all of the prior conditions evaluated to + 'false' + + otherwise + org.apache.taglibs.standard.tag.common.core.OtherwiseTag + JSP + + + + + Adds a parameter to a containing 'import' tag's URL. + + param + org.apache.taglibs.standard.tag.rt.core.ParamTag + JSP + + +Name of the query string parameter. + + name + true + true + + + +Value of the parameter. + + value + false + true + + + + + + Redirects to a new URL. + + redirect + org.apache.taglibs.standard.tag.rt.core.RedirectTag + JSP + + +The URL of the resource to redirect to. + + url + false + true + + + +Name of the context when redirecting to a relative URL +resource that belongs to a foreign context. + + context + false + true + + + + + + Removes a scoped variable (from a particular scope, if specified). + + remove + org.apache.taglibs.standard.tag.common.core.RemoveTag + empty + + +Name of the scoped variable to be removed. + + var + true + false + + + +Scope for var. + + scope + false + false + + + + + + Sets the result of an expression evaluation in a 'scope' + + set + org.apache.taglibs.standard.tag.rt.core.SetTag + JSP + + +Name of the exported scoped variable to hold the value +specified in the action. The type of the scoped variable is +whatever type the value expression evaluates to. + + var + false + false + + + +Expression to be evaluated. + + value + false + true + + java.lang.Object + + + + +Target object whose property will be set. Must evaluate to +a JavaBeans object with setter property property, or to a +java.util.Map object. + + target + false + true + + + +Name of the property to be set in the target object. + + property + false + true + + + +Scope for var. + + scope + false + false + + + + + + Creates a URL with optional query parameters. + + url + org.apache.taglibs.standard.tag.rt.core.UrlTag + JSP + + +Name of the exported scoped variable for the +processed url. The type of the scoped variable is +String. + + var + false + false + + + +Scope for var. + + scope + false + false + + + +URL to be processed. + + value + false + true + + + +Name of the context when specifying a relative URL +resource that belongs to a foreign context. + + context + false + true + + + + + + Subtag of <choose> that includes its body if its + condition evalutes to 'true' + + when + org.apache.taglibs.standard.tag.rt.core.WhenTag + JSP + + +The test condition that determines whether or not the +body content should be processed. + + test + true + true + boolean + + + + diff --git a/BuildingQuality/sample-code/gebish/web-app/WEB-INF/tld/fmt.tld b/BuildingQuality/sample-code/gebish/web-app/WEB-INF/tld/fmt.tld new file mode 100644 index 0000000..2ae4776 --- /dev/null +++ b/BuildingQuality/sample-code/gebish/web-app/WEB-INF/tld/fmt.tld @@ -0,0 +1,671 @@ + + + + + JSTL 1.2 i18n-capable formatting library + JSTL fmt + 1.2 + fmt + http://java.sun.com/jsp/jstl/fmt + + + + Provides core validation features for JSTL tags. + + + org.apache.taglibs.standard.tlv.JstlFmtTLV + + + + + + Sets the request character encoding + + requestEncoding + org.apache.taglibs.standard.tag.rt.fmt.RequestEncodingTag + empty + + +Name of character encoding to be applied when +decoding request parameters. + + value + false + true + + + + + + Stores the given locale in the locale configuration variable + + setLocale + org.apache.taglibs.standard.tag.rt.fmt.SetLocaleTag + empty + + +A String value is interpreted as the +printable representation of a locale, which +must contain a two-letter (lower-case) +language code (as defined by ISO-639), +and may contain a two-letter (upper-case) +country code (as defined by ISO-3166). +Language and country codes must be +separated by hyphen (-) or underscore +(_). + + value + true + true + + + +Vendor- or browser-specific variant. +See the java.util.Locale javadocs for +more information on variants. + + variant + false + true + + + +Scope of the locale configuration variable. + + scope + false + false + + + + + + Specifies the time zone for any time formatting or parsing actions + nested in its body + + timeZone + org.apache.taglibs.standard.tag.rt.fmt.TimeZoneTag + JSP + + +The time zone. A String value is interpreted as +a time zone ID. This may be one of the time zone +IDs supported by the Java platform (such as +"America/Los_Angeles") or a custom time zone +ID (such as "GMT-8"). See +java.util.TimeZone for more information on +supported time zone formats. + + value + true + true + + + + + + Stores the given time zone in the time zone configuration variable + + setTimeZone + org.apache.taglibs.standard.tag.rt.fmt.SetTimeZoneTag + empty + + +The time zone. A String value is interpreted as +a time zone ID. This may be one of the time zone +IDs supported by the Java platform (such as +"America/Los_Angeles") or a custom time zone +ID (such as "GMT-8"). See java.util.TimeZone for +more information on supported time zone +formats. + + value + true + true + + + +Name of the exported scoped variable which +stores the time zone of type +java.util.TimeZone. + + var + false + false + + + +Scope of var or the time zone configuration +variable. + + scope + false + false + + + + + + Loads a resource bundle to be used by its tag body + + bundle + org.apache.taglibs.standard.tag.rt.fmt.BundleTag + JSP + + +Resource bundle base name. This is the bundle's +fully-qualified resource name, which has the same +form as a fully-qualified class name, that is, it uses +"." as the package component separator and does not +have any file type (such as ".class" or ".properties") +suffix. + + basename + true + true + + + +Prefix to be prepended to the value of the message +key of any nested <fmt:message> action. + + prefix + false + true + + + + + + Loads a resource bundle and stores it in the named scoped variable or + the bundle configuration variable + + setBundle + org.apache.taglibs.standard.tag.rt.fmt.SetBundleTag + empty + + +Resource bundle base name. This is the bundle's +fully-qualified resource name, which has the same +form as a fully-qualified class name, that is, it uses +"." as the package component separator and does not +have any file type (such as ".class" or ".properties") +suffix. + + basename + true + true + + + +Name of the exported scoped variable which stores +the i18n localization context of type +javax.servlet.jsp.jstl.fmt.LocalizationC +ontext. + + var + false + false + + + +Scope of var or the localization context +configuration variable. + + scope + false + false + + + + + + Maps key to localized message and performs parametric replacement + + message + org.apache.taglibs.standard.tag.rt.fmt.MessageTag + JSP + + +Message key to be looked up. + + key + false + true + + + +Localization context in whose resource +bundle the message key is looked up. + + bundle + false + true + + + +Name of the exported scoped variable +which stores the localized message. + + var + false + false + + + +Scope of var. + + scope + false + false + + + + + + Supplies an argument for parametric replacement to a containing + <message> tag + + param + org.apache.taglibs.standard.tag.rt.fmt.ParamTag + JSP + + +Argument used for parametric replacement. + + value + false + true + + + + + + Formats a numeric value as a number, currency, or percentage + + formatNumber + org.apache.taglibs.standard.tag.rt.fmt.FormatNumberTag + JSP + + +Numeric value to be formatted. + + value + false + true + + + +Specifies whether the value is to be +formatted as number, currency, or +percentage. + + type + false + true + + + +Custom formatting pattern. + + pattern + false + true + + + +ISO 4217 currency code. Applied only +when formatting currencies (i.e. if type is +equal to "currency"); ignored otherwise. + + currencyCode + false + true + + + +Currency symbol. Applied only when +formatting currencies (i.e. if type is equal +to "currency"); ignored otherwise. + + currencySymbol + false + true + + + +Specifies whether the formatted output +will contain any grouping separators. + + groupingUsed + false + true + + + +Maximum number of digits in the integer +portion of the formatted output. + + maxIntegerDigits + false + true + + + +Minimum number of digits in the integer +portion of the formatted output. + + minIntegerDigits + false + true + + + +Maximum number of digits in the +fractional portion of the formatted output. + + maxFractionDigits + false + true + + + +Minimum number of digits in the +fractional portion of the formatted output. + + minFractionDigits + false + true + + + +Name of the exported scoped variable +which stores the formatted result as a +String. + + var + false + false + + + +Scope of var. + + scope + false + false + + + + + + Parses the string representation of a number, currency, or percentage + + parseNumber + org.apache.taglibs.standard.tag.rt.fmt.ParseNumberTag + JSP + + +String to be parsed. + + value + false + true + + + +Specifies whether the string in the value +attribute should be parsed as a number, +currency, or percentage. + + type + false + true + + + +Custom formatting pattern that determines +how the string in the value attribute is to be +parsed. + + pattern + false + true + + + +Locale whose default formatting pattern (for +numbers, currencies, or percentages, +respectively) is to be used during the parse +operation, or to which the pattern specified +via the pattern attribute (if present) is +applied. + + parseLocale + false + true + + + +Specifies whether just the integer portion of +the given value should be parsed. + + integerOnly + false + true + + + +Name of the exported scoped variable which +stores the parsed result (of type +java.lang.Number). + + var + false + false + + + +Scope of var. + + scope + false + false + + + + + + Formats a date and/or time using the supplied styles and pattern + + formatDate + org.apache.taglibs.standard.tag.rt.fmt.FormatDateTag + empty + + +Date and/or time to be formatted. + + value + true + true + + + +Specifies whether the time, the date, or both +the time and date components of the given +date are to be formatted. + + type + false + true + + + +Predefined formatting style for dates. Follows +the semantics defined in class +java.text.DateFormat. Applied only +when formatting a date or both a date and +time (i.e. if type is missing or is equal to +"date" or "both"); ignored otherwise. + + dateStyle + false + true + + + +Predefined formatting style for times. Follows +the semantics defined in class +java.text.DateFormat. Applied only +when formatting a time or both a date and +time (i.e. if type is equal to "time" or "both"); +ignored otherwise. + + timeStyle + false + true + + + +Custom formatting style for dates and times. + + pattern + false + true + + + +Time zone in which to represent the formatted +time. + + timeZone + false + true + + + +Name of the exported scoped variable which +stores the formatted result as a String. + + var + false + false + + + +Scope of var. + + scope + false + false + + + + + + Parses the string representation of a date and/or time + + parseDate + org.apache.taglibs.standard.tag.rt.fmt.ParseDateTag + JSP + + +Date string to be parsed. + + value + false + true + + + +Specifies whether the date string in the +value attribute is supposed to contain a +time, a date, or both. + + type + false + true + + + +Predefined formatting style for days +which determines how the date +component of the date string is to be +parsed. Applied only when formatting a +date or both a date and time (i.e. if type +is missing or is equal to "date" or "both"); +ignored otherwise. + + dateStyle + false + true + + + +Predefined formatting styles for times +which determines how the time +component in the date string is to be +parsed. Applied only when formatting a +time or both a date and time (i.e. if type +is equal to "time" or "both"); ignored +otherwise. + + timeStyle + false + true + + + +Custom formatting pattern which +determines how the date string is to be +parsed. + + pattern + false + true + + + +Time zone in which to interpret any time +information in the date string. + + timeZone + false + true + + + +Locale whose predefined formatting styles +for dates and times are to be used during +the parse operation, or to which the +pattern specified via the pattern +attribute (if present) is applied. + + parseLocale + false + true + + + +Name of the exported scoped variable in +which the parsing result (of type +java.util.Date) is stored. + + var + false + false + + + +Scope of var. + + scope + false + false + + + + diff --git a/BuildingQuality/sample-code/gebish/web-app/WEB-INF/tld/grails.tld b/BuildingQuality/sample-code/gebish/web-app/WEB-INF/tld/grails.tld new file mode 100644 index 0000000..9bd036b --- /dev/null +++ b/BuildingQuality/sample-code/gebish/web-app/WEB-INF/tld/grails.tld @@ -0,0 +1,550 @@ + + + The Grails custom tag library + 0.2 + grails + http://grails.codehaus.org/tags + + + link + org.codehaus.groovy.grails.web.taglib.jsp.JspLinkTag + JSP + + action + false + true + + + controller + false + true + + + id + false + true + + + url + false + true + + + params + false + true + + true + + + form + org.codehaus.groovy.grails.web.taglib.jsp.JspFormTag + JSP + + action + false + true + + + controller + false + true + + + id + false + true + + + url + false + true + + + method + true + true + + true + + + select + org.codehaus.groovy.grails.web.taglib.jsp.JspSelectTag + JSP + + name + true + true + + + value + false + true + + + optionKey + false + true + + + optionValue + false + true + + true + + + datePicker + org.codehaus.groovy.grails.web.taglib.jsp.JspDatePickerTag + empty + + name + true + true + + + value + false + true + + + precision + false + true + + false + + + currencySelect + org.codehaus.groovy.grails.web.taglib.jsp.JspCurrencySelectTag + empty + + name + true + true + + + value + false + true + + true + + + localeSelect + org.codehaus.groovy.grails.web.taglib.jsp.JspLocaleSelectTag + empty + + name + true + true + + + value + false + true + + true + + + timeZoneSelect + org.codehaus.groovy.grails.web.taglib.jsp.JspTimeZoneSelectTag + empty + + name + true + true + + + value + false + true + + true + + + checkBox + org.codehaus.groovy.grails.web.taglib.jsp.JspCheckboxTag + empty + + name + true + true + + + value + true + true + + true + + + hasErrors + org.codehaus.groovy.grails.web.taglib.jsp.JspHasErrorsTag + JSP + + model + false + true + + + bean + false + true + + + field + false + true + + false + + + eachError + org.codehaus.groovy.grails.web.taglib.jsp.JspEachErrorTag + JSP + + model + false + true + + + bean + false + true + + + field + false + true + + false + + + renderErrors + org.codehaus.groovy.grails.web.taglib.jsp.JspEachErrorTag + JSP + + model + false + true + + + bean + false + true + + + field + false + true + + + as + true + true + + false + + + message + org.codehaus.groovy.grails.web.taglib.jsp.JspMessageTag + JSP + + code + false + true + + + error + false + true + + + default + false + true + + false + + + remoteFunction + org.codehaus.groovy.grails.web.taglib.jsp.JspRemoteFunctionTag + empty + + before + false + true + + + after + false + true + + + action + false + true + + + controller + false + true + + + id + false + true + + + url + false + true + + + params + false + true + + + asynchronous + false + true + + + method + false + true + + + update + false + true + + + onSuccess + false + true + + + onFailure + false + true + + + onComplete + false + true + + + onLoading + false + true + + + onLoaded + false + true + + + onInteractive + false + true + + true + + + remoteLink + org.codehaus.groovy.grails.web.taglib.jsp.JspRemoteLinkTag + JSP + + before + false + true + + + after + false + true + + + action + false + true + + + controller + false + true + + + id + false + true + + + url + false + true + + + params + false + true + + + asynchronous + false + true + + + method + false + true + + + update + false + true + + + onSuccess + false + true + + + onFailure + false + true + + + onComplete + false + true + + + onLoading + false + true + + + onLoaded + false + true + + + onInteractive + false + true + + true + + + formRemote + org.codehaus.groovy.grails.web.taglib.jsp.JspFormRemoteTag + JSP + + before + false + true + + + after + false + true + + + action + false + true + + + controller + false + true + + + id + false + true + + + url + false + true + + + params + false + true + + + asynchronous + false + true + + + method + false + true + + + update + false + true + + + onSuccess + false + true + + + onFailure + false + true + + + onComplete + false + true + + + onLoading + false + true + + + onLoaded + false + true + + + onInteractive + false + true + + true + + + invokeTag + org.codehaus.groovy.grails.web.taglib.jsp.JspInvokeGrailsTagLibTag + JSP + + it + java.lang.Object + true + NESTED + + + tagName + true + true + + true + + + diff --git a/BuildingQuality/sample-code/gebish/web-app/WEB-INF/tld/spring.tld b/BuildingQuality/sample-code/gebish/web-app/WEB-INF/tld/spring.tld new file mode 100644 index 0000000..1bc7091 --- /dev/null +++ b/BuildingQuality/sample-code/gebish/web-app/WEB-INF/tld/spring.tld @@ -0,0 +1,311 @@ + + + + + + 1.1.1 + + 1.2 + + Spring + + http://www.springframework.org/tags + + Spring Framework JSP Tag Library. Authors: Rod Johnson, Juergen Hoeller + + + + + htmlEscape + org.springframework.web.servlet.tags.HtmlEscapeTag + JSP + + + Sets default HTML escape value for the current page. + Overrides a "defaultHtmlEscape" context-param in web.xml, if any. + + + + defaultHtmlEscape + true + true + + + + + + + + escapeBody + org.springframework.web.servlet.tags.EscapeBodyTag + JSP + + + Escapes its enclosed body content, applying HTML escaping and/or JavaScript escaping. + The HTML escaping flag participates in a page-wide or application-wide setting + (i.e. by HtmlEscapeTag or a "defaultHtmlEscape" context-param in web.xml). + + + + htmlEscape + false + true + + + + javaScriptEscape + false + true + + + + + + + + message + org.springframework.web.servlet.tags.MessageTag + JSP + + + Retrieves the message with the given code, or text if code isn't resolvable. + The HTML escaping flag participates in a page-wide or application-wide setting + (i.e. by HtmlEscapeTag or a "defaultHtmlEscape" context-param in web.xml). + + + + code + false + true + + + + arguments + false + true + + + + text + false + true + + + + var + false + true + + + + scope + false + true + + + + htmlEscape + false + true + + + + javaScriptEscape + false + true + + + + + + + + theme + org.springframework.web.servlet.tags.ThemeTag + JSP + + + Retrieves the theme message with the given code, or text if code isn't resolvable. + The HTML escaping flag participates in a page-wide or application-wide setting + (i.e. by HtmlEscapeTag or a "defaultHtmlEscape" context-param in web.xml). + + + + code + false + true + + + + arguments + false + true + + + + text + false + true + + + + var + false + true + + + + scope + false + true + + + + htmlEscape + false + true + + + + javaScriptEscape + false + true + + + + + + + + hasBindErrors + org.springframework.web.servlet.tags.BindErrorsTag + JSP + + + Provides Errors instance in case of bind errors. + The HTML escaping flag participates in a page-wide or application-wide setting + (i.e. by HtmlEscapeTag or a "defaultHtmlEscape" context-param in web.xml). + + + + errors + org.springframework.validation.Errors + + + + name + true + true + + + + htmlEscape + false + true + + + + + + + + nestedPath + org.springframework.web.servlet.tags.NestedPathTag + JSP + + + Sets a nested path to be used by the bind tag's path. + + + + nestedPath + java.lang.String + + + + path + true + true + + + + + + + + bind + org.springframework.web.servlet.tags.BindTag + JSP + + + Provides BindStatus object for the given bind path. + The HTML escaping flag participates in a page-wide or application-wide setting + (i.e. by HtmlEscapeTag or a "defaultHtmlEscape" context-param in web.xml). + + + + status + org.springframework.web.servlet.support.BindStatus + + + + path + true + true + + + + ignoreNestedPath + false + true + + + + htmlEscape + false + true + + + + + + + + transform + org.springframework.web.servlet.tags.TransformTag + JSP + + + Provides transformation of variables to Strings, using an appropriate + custom PropertyEditor from BindTag (can only be used inside BindTag). + The HTML escaping flag participates in a page-wide or application-wide setting + (i.e. by HtmlEscapeTag or a "defaultHtmlEscape" context-param in web.xml). + + + + value + true + true + + + + var + false + true + + + + scope + false + true + + + + htmlEscape + false + true + + + + + diff --git a/BuildingQuality/sample-code/gebish/web-app/css/errors.css b/BuildingQuality/sample-code/gebish/web-app/css/errors.css new file mode 100644 index 0000000..bdb58bc --- /dev/null +++ b/BuildingQuality/sample-code/gebish/web-app/css/errors.css @@ -0,0 +1,109 @@ +h1, h2 { + margin: 10px 25px 5px; +} + +h2 { + font-size: 1.1em; +} + +.filename { + font-style: italic; +} + +.exceptionMessage { + margin: 10px; + border: 1px solid #000; + padding: 5px; + background-color: #E9E9E9; +} + +.stack, +.snippet { + margin: 0 25px 10px; +} + +.stack, +.snippet { + border: 1px solid #ccc; + -mox-box-shadow: 0 0 2px rgba(0,0,0,0.2); + -webkit-box-shadow: 0 0 2px rgba(0,0,0,0.2); + box-shadow: 0 0 2px rgba(0,0,0,0.2); +} + +/* error details */ +.error-details { + border-top: 1px solid #FFAAAA; + -mox-box-shadow: 0 0 2px rgba(0,0,0,0.2); + -webkit-box-shadow: 0 0 2px rgba(0,0,0,0.2); + box-shadow: 0 0 2px rgba(0,0,0,0.2); + border-bottom: 1px solid #FFAAAA; + -mox-box-shadow: 0 0 2px rgba(0,0,0,0.2); + -webkit-box-shadow: 0 0 2px rgba(0,0,0,0.2); + box-shadow: 0 0 2px rgba(0,0,0,0.2); + background-color:#FFF3F3; + line-height: 1.5; + overflow: hidden; + padding: 5px; + padding-left:25px; +} + +.error-details dt { + clear: left; + float: left; + font-weight: bold; + margin-right: 5px; +} + +.error-details dt:after { + content: ":"; +} + +.error-details dd { + display: block; +} + +/* stack trace */ +.stack { + padding: 5px; + overflow: auto; + height: 150px; +} + +/* code snippet */ +.snippet { + background-color: #fff; + font-family: monospace; +} + +.snippet .line { + display: block; +} + +.snippet .lineNumber { + background-color: #ddd; + color: #999; + display: inline-block; + margin-right: 5px; + padding: 0 3px; + text-align: right; + width: 3em; +} + +.snippet .error { + background-color: #fff3f3; + font-weight: bold; +} + +.snippet .error .lineNumber { + background-color: #faa; + color: #333; + font-weight: bold; +} + +.snippet .line:first-child .lineNumber { + padding-top: 5px; +} + +.snippet .line:last-child .lineNumber { + padding-bottom: 5px; +} \ No newline at end of file diff --git a/BuildingQuality/sample-code/gebish/web-app/css/main.css b/BuildingQuality/sample-code/gebish/web-app/css/main.css new file mode 100644 index 0000000..fcdc5eb --- /dev/null +++ b/BuildingQuality/sample-code/gebish/web-app/css/main.css @@ -0,0 +1,591 @@ +/* FONT STACK */ +body, +input, select, textarea { + font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; +} + +h1, h2, h3, h4, h5, h6 { + line-height: 1.1; +} + +/* BASE LAYOUT */ + +html { + background-color: #ddd; + background-image: -moz-linear-gradient(center top, #aaa, #ddd); + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #aaa), color-stop(1, #ddd)); + background-image: linear-gradient(top, #aaa, #ddd); + filter: progid:DXImageTransform.Microsoft.gradient(startColorStr = '#aaaaaa', EndColorStr = '#dddddd'); + background-repeat: no-repeat; + height: 100%; + /* change the box model to exclude the padding from the calculation of 100% height (IE8+) */ + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +html.no-cssgradients { + background-color: #aaa; +} + +.ie6 html { + height: 100%; +} + +html * { + margin: 0; +} + +body { + background: #ffffff; + color: #333333; + margin: 0 auto; + max-width: 960px; + overflow-x: hidden; /* prevents box-shadow causing a horizontal scrollbar in firefox when viewport < 960px wide */ + -moz-box-shadow: 0 0 0.3em #255b17; + -webkit-box-shadow: 0 0 0.3em #255b17; + box-shadow: 0 0 0.3em #255b17; +} + +#grailsLogo { + background-color: #abbf78; +} + +/* replace with .no-boxshadow body if you have modernizr available */ +.ie6 body, +.ie7 body, +.ie8 body { + border-color: #255b17; + border-style: solid; + border-width: 0 1px; +} + +.ie6 body { + height: 100%; +} + +a:link, a:visited, a:hover { + color: #48802c; +} + +a:hover, a:active { + outline: none; /* prevents outline in webkit on active links but retains it for tab focus */ +} + +h1 { + color: #48802c; + font-weight: normal; + font-size: 1.25em; + margin: 0.8em 0 0.3em 0; +} + +ul { + padding: 0; +} + +img { + border: 0; +} + +/* GENERAL */ + +#grailsLogo a { + display: inline-block; + margin: 1em; +} + +.content { +} + +.content h1 { + border-bottom: 1px solid #CCCCCC; + margin: 0.8em 1em 0.3em; + padding: 0 0.25em; +} + +.scaffold-list h1 { + border: none; +} + +.footer { + background: #abbf78; + color: #000; + clear: both; + font-size: 0.8em; + margin-top: 1.5em; + padding: 1em; + min-height: 1em; +} + +.footer a { + color: #255b17; +} + +.spinner { + background: url(../images/spinner.gif) 50% 50% no-repeat transparent; + height: 16px; + width: 16px; + padding: 0.5em; + position: absolute; + right: 0; + top: 0; + text-indent: -9999px; +} + +/* NAVIGATION MENU */ + +.nav { + background-color: #efefef; + padding: 0.5em 0.75em; + -moz-box-shadow: 0 0 3px 1px #aaaaaa; + -webkit-box-shadow: 0 0 3px 1px #aaaaaa; + box-shadow: 0 0 3px 1px #aaaaaa; + zoom: 1; +} + +.nav ul { + overflow: hidden; + padding-left: 0; + zoom: 1; +} + +.nav li { + display: block; + float: left; + list-style-type: none; + margin-right: 0.5em; + padding: 0; +} + +.nav a { + color: #666666; + display: block; + padding: 0.25em 0.7em; + text-decoration: none; + -moz-border-radius: 0.3em; + -webkit-border-radius: 0.3em; + border-radius: 0.3em; +} + +.nav a:active, .nav a:visited { + color: #666666; +} + +.nav a:focus, .nav a:hover { + background-color: #999999; + color: #ffffff; + outline: none; + text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.8); +} + +.no-borderradius .nav a:focus, .no-borderradius .nav a:hover { + background-color: transparent; + color: #444444; + text-decoration: underline; +} + +.nav a.home, .nav a.list, .nav a.create { + background-position: 0.7em center; + background-repeat: no-repeat; + text-indent: 25px; +} + +.nav a.home { + background-image: url(../images/skin/house.png); +} + +.nav a.list { + background-image: url(../images/skin/database_table.png); +} + +.nav a.create { + background-image: url(../images/skin/database_add.png); +} + +/* CREATE/EDIT FORMS AND SHOW PAGES */ + +fieldset, +.property-list { + margin: 0.6em 1.25em 0 1.25em; + padding: 0.3em 1.8em 1.25em; + position: relative; + zoom: 1; + border: none; +} + +.property-list .fieldcontain { + list-style: none; + overflow: hidden; + zoom: 1; +} + +.fieldcontain { + margin-top: 1em; +} + +.fieldcontain label, +.fieldcontain .property-label { + color: #666666; + text-align: right; + width: 25%; +} + +.fieldcontain .property-label { + float: left; +} + +.fieldcontain .property-value { + display: block; + margin-left: 27%; +} + +label { + cursor: pointer; + display: inline-block; + margin: 0 0.25em 0 0; +} + +input, select, textarea { + background-color: #fcfcfc; + border: 1px solid #cccccc; + font-size: 1em; + padding: 0.2em 0.4em; +} + +select { + padding: 0.2em 0.2em 0.2em 0; +} + +select[multiple] { + vertical-align: top; +} + +textarea { + width: 250px; + height: 150px; + overflow: auto; /* IE always renders vertical scrollbar without this */ + vertical-align: top; +} + +input[type=checkbox], input[type=radio] { + background-color: transparent; + border: 0; + padding: 0; +} + +input:focus, select:focus, textarea:focus { + background-color: #ffffff; + border: 1px solid #eeeeee; + outline: 0; + -moz-box-shadow: 0 0 0.5em #ffffff; + -webkit-box-shadow: 0 0 0.5em #ffffff; + box-shadow: 0 0 0.5em #ffffff; +} + +.required-indicator { + color: #48802C; + display: inline-block; + font-weight: bold; + margin-left: 0.3em; + position: relative; + top: 0.1em; +} + +ul.one-to-many { + display: inline-block; + list-style-position: inside; + vertical-align: top; +} + +.ie6 ul.one-to-many, .ie7 ul.one-to-many { + display: inline; + zoom: 1; +} + +ul.one-to-many li.add { + list-style-type: none; +} + +/* EMBEDDED PROPERTIES */ + +fieldset.embedded { + background-color: transparent; + border: 1px solid #CCCCCC; + margin-left: 0; + margin-right: 0; + padding-left: 0; + padding-right: 0; + -moz-box-shadow: none; + -webkit-box-shadow: none; + box-shadow: none; +} + +fieldset.embedded legend { + margin: 0 1em; +} + +/* MESSAGES AND ERRORS */ + +.errors, +.message { + font-size: 0.8em; + line-height: 2; + margin: 1em 2em; + padding: 0.25em; +} + +.message { + background: #f3f3ff; + border: 1px solid #b2d1ff; + color: #006dba; + -moz-box-shadow: 0 0 0.25em #b2d1ff; + -webkit-box-shadow: 0 0 0.25em #b2d1ff; + box-shadow: 0 0 0.25em #b2d1ff; +} + +.errors { + background: #fff3f3; + border: 1px solid #ffaaaa; + color: #cc0000; + -moz-box-shadow: 0 0 0.25em #ff8888; + -webkit-box-shadow: 0 0 0.25em #ff8888; + box-shadow: 0 0 0.25em #ff8888; +} + +.errors ul, +.message { + padding: 0; +} + +.errors li { + list-style: none; + background: transparent url(../images/skin/exclamation.png) 0.5em 50% no-repeat; + text-indent: 2.2em; +} + +.message { + background: transparent url(../images/skin/information.png) 0.5em 50% no-repeat; + text-indent: 2.2em; +} + +/* form fields with errors */ + +.error input, .error select, .error textarea { + background: #fff3f3; + border-color: #ffaaaa; + color: #cc0000; +} + +.error input:focus, .error select:focus, .error textarea:focus { + -moz-box-shadow: 0 0 0.5em #ffaaaa; + -webkit-box-shadow: 0 0 0.5em #ffaaaa; + box-shadow: 0 0 0.5em #ffaaaa; +} + +/* same effects for browsers that support HTML5 client-side validation (these have to be specified separately or IE will ignore the entire rule) */ + +input:invalid, select:invalid, textarea:invalid { + background: #fff3f3; + border-color: #ffaaaa; + color: #cc0000; +} + +input:invalid:focus, select:invalid:focus, textarea:invalid:focus { + -moz-box-shadow: 0 0 0.5em #ffaaaa; + -webkit-box-shadow: 0 0 0.5em #ffaaaa; + box-shadow: 0 0 0.5em #ffaaaa; +} + +/* TABLES */ + +table { + border-top: 1px solid #DFDFDF; + border-collapse: collapse; + width: 100%; + margin-bottom: 1em; +} + +tr { + border: 0; +} + +tr>td:first-child, tr>th:first-child { + padding-left: 1.25em; +} + +tr>td:last-child, tr>th:last-child { + padding-right: 1.25em; +} + +td, th { + line-height: 1.5em; + padding: 0.5em 0.6em; + text-align: left; + vertical-align: top; +} + +th { + background-color: #efefef; + background-image: -moz-linear-gradient(top, #ffffff, #eaeaea); + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #ffffff), color-stop(1, #eaeaea)); + filter: progid:DXImageTransform.Microsoft.gradient(startColorStr = '#ffffff', EndColorStr = '#eaeaea'); + -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#ffffff', EndColorStr='#eaeaea')"; + color: #666666; + font-weight: bold; + line-height: 1.7em; + padding: 0.2em 0.6em; +} + +thead th { + white-space: nowrap; +} + +th a { + display: block; + text-decoration: none; +} + +th a:link, th a:visited { + color: #666666; +} + +th a:hover, th a:focus { + color: #333333; +} + +th.sortable a { + background-position: right; + background-repeat: no-repeat; + padding-right: 1.1em; +} + +th.asc a { + background-image: url(../images/skin/sorted_asc.gif); +} + +th.desc a { + background-image: url(../images/skin/sorted_desc.gif); +} + +.odd { + background: #f7f7f7; +} + +.even { + background: #ffffff; +} + +th:hover, tr:hover { + background: #E1F2B6; +} + +/* PAGINATION */ + +.pagination { + border-top: 0; + margin: 0; + padding: 0.3em 0.2em; + text-align: center; + -moz-box-shadow: 0 0 3px 1px #AAAAAA; + -webkit-box-shadow: 0 0 3px 1px #AAAAAA; + box-shadow: 0 0 3px 1px #AAAAAA; + background-color: #EFEFEF; +} + +.pagination a, +.pagination .currentStep { + color: #666666; + display: inline-block; + margin: 0 0.1em; + padding: 0.25em 0.7em; + text-decoration: none; + -moz-border-radius: 0.3em; + -webkit-border-radius: 0.3em; + border-radius: 0.3em; +} + +.pagination a:hover, .pagination a:focus, +.pagination .currentStep { + background-color: #999999; + color: #ffffff; + outline: none; + text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.8); +} + +.no-borderradius .pagination a:hover, .no-borderradius .pagination a:focus, +.no-borderradius .pagination .currentStep { + background-color: transparent; + color: #444444; + text-decoration: underline; +} + +/* ACTION BUTTONS */ + +.buttons { + background-color: #efefef; + overflow: hidden; + padding: 0.3em; + -moz-box-shadow: 0 0 3px 1px #aaaaaa; + -webkit-box-shadow: 0 0 3px 1px #aaaaaa; + box-shadow: 0 0 3px 1px #aaaaaa; + margin: 0.1em 0 0 0; + border: none; +} + +.buttons input, +.buttons a { + background-color: transparent; + border: 0; + color: #666666; + cursor: pointer; + display: inline-block; + margin: 0 0.25em 0; + overflow: visible; + padding: 0.25em 0.7em; + text-decoration: none; + + -moz-border-radius: 0.3em; + -webkit-border-radius: 0.3em; + border-radius: 0.3em; +} + +.buttons input:hover, .buttons input:focus, +.buttons a:hover, .buttons a:focus { + background-color: #999999; + color: #ffffff; + outline: none; + text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.8); + -moz-box-shadow: none; + -webkit-box-shadow: none; + box-shadow: none; +} + +.no-borderradius .buttons input:hover, .no-borderradius .buttons input:focus, +.no-borderradius .buttons a:hover, .no-borderradius .buttons a:focus { + background-color: transparent; + color: #444444; + text-decoration: underline; +} + +.buttons .delete, .buttons .edit, .buttons .save { + background-position: 0.7em center; + background-repeat: no-repeat; + text-indent: 25px; +} + +.buttons .delete { + background-image: url(../images/skin/database_delete.png); +} + +.buttons .edit { + background-image: url(../images/skin/database_edit.png); +} + +.buttons .save { + background-image: url(../images/skin/database_save.png); +} + +a.skip { + position: absolute; + left: -9999px; +} diff --git a/BuildingQuality/sample-code/gebish/web-app/css/mobile.css b/BuildingQuality/sample-code/gebish/web-app/css/mobile.css new file mode 100644 index 0000000..167f502 --- /dev/null +++ b/BuildingQuality/sample-code/gebish/web-app/css/mobile.css @@ -0,0 +1,82 @@ +/* Styles for mobile devices */ + +@media screen and (max-width: 480px) { + .nav { + padding: 0.5em; + } + + .nav li { + margin: 0 0.5em 0 0; + padding: 0.25em; + } + + /* Hide individual steps in pagination, just have next & previous */ + .pagination .step, .pagination .currentStep { + display: none; + } + + .pagination .prevLink { + float: left; + } + + .pagination .nextLink { + float: right; + } + + /* pagination needs to wrap around floated buttons */ + .pagination { + overflow: hidden; + } + + /* slightly smaller margin around content body */ + fieldset, + .property-list { + padding: 0.3em 1em 1em; + } + + input, textarea { + width: 100%; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + -ms-box-sizing: border-box; + box-sizing: border-box; + } + + select, input[type=checkbox], input[type=radio], input[type=submit], input[type=button], input[type=reset] { + width: auto; + } + + /* hide all but the first column of list tables */ + .scaffold-list td:not(:first-child), + .scaffold-list th:not(:first-child) { + display: none; + } + + .scaffold-list thead th { + text-align: center; + } + + /* stack form elements */ + .fieldcontain { + margin-top: 0.6em; + } + + .fieldcontain label, + .fieldcontain .property-label, + .fieldcontain .property-value { + display: block; + float: none; + margin: 0 0 0.25em 0; + text-align: left; + width: auto; + } + + .errors ul, + .message p { + margin: 0.5em; + } + + .error ul { + margin-left: 0; + } +} diff --git a/BuildingQuality/sample-code/gebish/web-app/images/apple-touch-icon-retina.png b/BuildingQuality/sample-code/gebish/web-app/images/apple-touch-icon-retina.png new file mode 100644 index 0000000000000000000000000000000000000000..5cc83edbe69203eaaf7d64e5b2596de6e01fff29 GIT binary patch literal 14986 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 literal 0 HcmV?d00001 diff --git a/BuildingQuality/sample-code/gebish/web-app/images/favicon.ico b/BuildingQuality/sample-code/gebish/web-app/images/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..3dfcb9279f60f2396a8f19fb6607ff281800c905 GIT binary patch literal 10134 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 HxB~wLBPRzvo?bs5u)ML^KP)Z7$c zVPOGoFb{x%1AMMT`}+WZxw#U+4FCW;Ai=@`urO;zOp^SMx+$}MnuYCO?X1kY1`8`7 z$h=xH>2JBgq`&X{->c0{|KPi-R#zNk?`f&3>jI2f;1a;b%KG>Nip zIF5+$^YV-Qj|-y%5aI?LSj5>_P6Dh#ENnt7jBWtTWS@g6mA``dkHW&r&q2muqJ4IOcPJU5G>YgoZKaG25G5C&NTEA7qzu%bC=D0ojca
v zCmi7s6%#)$p>Rs^^ckgd+UIq2_4F@YzG4bBGq&j)%imN~R=urnXl(k>-16~LXIFPmZ(skw;P}M% z$tleA3>Jr9T3-3Ny0-p{xU;*rPx?bXIQ)x?1z`I(tp7yz|KSp1;$mfIXJhC3i;IOd zib-rj>>MXFIE9UExo(CXJE{4ATf`*0wC>9hIW0Q^=vMd`kEr}PoC5JLw0|M{?*U8r zUm^QXVE=^+3-GbAFei^q2!H@I`&VhovdSLwU0!UXVVcG~d=34x4gysu-ASY$?8uDg zfUkGhsp_!fU5_0H1;}C+JCIqJ<9ED~^u(hwh4zdKt)oG~v!2&IjlI?k^__Cy+8@3f zL{#_iXR4^YuZ!oJUySIeU9+`Py7pywSGR2AF(l1(tG;w^o3FKd2D>wqwX9r1`@v9%0(5F^<-5yMRww`TS_d zS%muu-p%R6Q&}8ySgsd|FgRR(GDI7l{K;^0AHOhq)`fDh*CRaCP5hv4s;)>I^!0K2 z*6(``c05|n1&^FO*^A?jpJ2L`Zv}w^8&4lyv){@9Iw(&1OG*50NX1f9j9NV z0Zd9|-hgD`Rg_4xV5)ZcdLF4+Xu)d!cFe=8JFgzuc#XQhSk3IfNE1$CyT0h?s|?QP z>$v#83vS@>-F+Z_3Wjc@l6subzR0C)mD&yxM4LU2QlZBt%3dMA@Zuip^&^_S<% zY|HKq+IphP<=3#;Z6MZn!(DpgYI%UQlv3}Qc>IwerM=a?w|NZU*j8lW z&}miduIa}{O>Q+|Ypo0YDs3@2TzYgz#A>(wLV&RL-g=Z~rGPpR0`MKn+?!vPnZO~F zF*0% zQdM%lmMWxn93&p?(}QHduTl)x+YN}AbZP3jr=G4oJkvjpJ-BfI>BMV^(* zb&{NbReeCT*f4IL*t_1E+BR@XEM018TXZniH+#Nm+5XRM=!MKWh)E;lFF}l_KET(`Y{?W9oa`CEZ|@zqF_8exsiZ^vhpc*_8hjGS|{~Z8x#_dChzB>07?PzrTyPRTmlh zZMEKyX3GE`G5})+P=aFsh*|2H3OqRZdqgD*1Guw5RVH3x0D&dxbuVNa@cG6M**J`k7%5$W-B+8_vllc~W^ zqGvA$=MN$mRp=n{z#GJ53CKBP-e5{V>gQs?#<^{57T#?sDpT7ecB`eD0XX?mHx3Vk zXlG?oPaB(~6qBY+2Hl46b7&eqJ8FQ1Mlw|{nTH1!T|ERcFrYw z)GNv$AzKAxB_x)&k6-RIk*|x3>{foUM5Zk)bWtreILlxYKH+ZYLM#8n06GLV$w*}* zy2NnV-NL$gk+Dl-60I@7|@ z)(6%f3t@Gh%>aV)2|3?NIv7gZ3EVy0UV>&irZAPJ&}NBVfN$_7&n+d%>!j_o?|mhg z(LAcD{gCEGQtF}X{F!k~%{MmM1YM+rkmnEECH-4+eUM(XWO1?j_lV61N3kWREH?!> ztg3l@aZ**fl8!w#$`t$BR5ekot3bLL8_Dk~c_H+o=7`11(Q7&C$}!_VmHUOG70gSs zFTG9)e%~P>A%;9zihubQ zdwDm*)6F~Xu|3`N^zq7Vf>J1vh@ESQ<^G%VJ*Fn>7X*r>oB>0oUgc z4nJbse+b6~t_zS)H+NTODB}$Z`0V~s!>v334B02V8Gwd3h!Ds&q8}qclRQ1-f0gg8 zqtj1lr%&`@wJ^>S+gE-(sLj6o_xt-buhK3pTNs6$Exu=_zi$|jP1sJ|Jel3ol>6Q9 zq9*T?7R5R~7OrXh#}a-r%9ikMXW-UY)&-ecS0(yuGG9pSs|mOTBF+#RHe4fXUgyP_ z`PZ612$R$bYw^l1e!gC?6Cu@v12<-MjykbqIhXe@w1o=$>2H3`AeH+1w2Vx@IlA!1 zpL7okOTIi%`Rjzmr_^l3{Y+Enpgx~(L1GVGXR=M6l=q=`%qI>bIS#s^8CLvaPZy=p z@?G&0I(DYyYsTwl-R=53|03VdY_>q^N@7-}wy}23?vB zGVgnBdiJ^{mNYsFD602#WluoM;acRYk;GWMXfn=2(=jv1YVop9Shh%<$7rnxxDP}^ zXTd!vhKOFVJUVAHIgSAw8BMLhWm=ltw>y7Vwe&%bxz?`wi4T>FLKA5R41mPNhi(!} z%B_b)g{3n9jFv58iZ1<~>Ot|0rkIa44i&jM6qAJbYhIX|--dWUeDYS$fQM8U>ijO` zef6oAWpUD3a{P*qzEA?ftSo0gZomlhFfM&$=fh@jMl%BtvO{)7!DVjtb-0C*XOYBD z2hR{+VWQ}@=h4j7mcx#@fLov&)OvDz5fagr$RA2DLe*iO8xoIP?mGMlp)>hkt|)~A zWaSF_6tYn#MKzC;u$_1#YBEHn^oES?^E&BI*&Xt$FG58y9|ISf1UkS;1)HNua1FvM zupridBxu2AMp!;ajlZ$Q2NAI=<@1sOBn0^VDG)^wqpZ*#4Muz*j1?{Q)&qJM4Rq5dsDG4hdNKKi_q&sB8SL9jisW$H= z-bAj4=hUxdCqRpFQRne`N}RgV=CuoS2}xX2<0EM`9Q!fn6Wy9W3^ZC%x10jK4DX*S zVQY-tgppKRQrJVs=yaEJ#vC?g|otyu5QBt?ncR+DkZ#25$r*X6A;0UYfH@$9BAp?=Gl>_!u{u ze3mNUMHK7EB$5MdWZX&C*`z2vmVacN_;>0_hRUOh0dD{Qbn@J^O9J0Oj6Hp1Z3_Rrlr!KJO`|SKq?v;%^43 zNWb$zjLC?MH^SJc8Z8rzvw>$&LhTds8cCY;Ev;Q4Ociw<5+K04?kP!hO1d@PNQpDj zYkZUA*qknV?`Vsn^nrF0#lnjY+U^Wq_!L3|ffP4`jw8j$mu8_zns`$tYk1`QKXKj% z1xq(U7ESqP#TvIhimwGs{s1c){^FGtivLq{q{DAx3!ar8^P_tLu5}-e7VX%^0N1@E?ry8hw*{hlBtCCWju|(;@Bi_Yn|&W!9k2YA zF10}_79B{t(v&!qds8j<&ap(jseW# zN&I!|nS33<9auX$rU^DXxd0y2&^LEqRu&;|oYOd)cu7d5IT z8K9&8Z89WyHMY7nTfV{i1jp-$9OtF)1vGwIV(-EXw1aJY7`=DC79nfz9Nv>p)E+hE!S;f#TBs|N7LGm58rWFM=)i0= zZ_W~qt}c~)iG5J^WtCiF5>dH6Rykz(fYP7bs%9OkOx(h5k7ng+45r(e{kWOk$6@x{ z7&Q@o);$0>DY~C}K#xeuRoZ&%s!7)V!}Z&3alnA-{8JrMZH}wHbS_i*5&sq9?$n1B z>lzh_j=y~8+=caV`-jLA2_@ZWG$Yy*1C2LuWim&Vb@g1&k)p?QoHzfmiRa7gd+M^< zlA_P^!eef@{+hw0uie$F;5@YCxzxs>2+K6@GqR1-gRz>e!Su)hvS+9A&_{{8^L4cs z|7h=HHo*ifNAi2wDLBV%y4?Btfu9O_64qxj!<{PEAo>TNW;<|96IzY+eD5A;VScVj`qNFs}e3L=!G zY~r)MCmY}7;o&ciuz%6ryI@vT!`wAJysi>9+nezhD3&}^-oiC)?>uqe)6-@5#Wy^0 zc$lpB6>tVV6=$!y%ig<(#1VI9eoEtXa7;-Hi=y$PGCQG0ikfU96(alR{< zGdi&I4OL;~3nyR6+|wbM=ciiFjh}SjmEit<*HIi*)`q0;NB1pa5>HLuZmq{O4gsF` zH#Kuk`fiIDUL4g$iCF5vB;Abq5@F^Ks!VE(0#sK=md;F;+xEV#TW0`us?Su={#iUj z4~p{HAf%Dkw3k%#YN`>f0q%{j;W5Kco<%MBdHVgSgm|Y~K@rNli`(fioOSmcTMs|) zCajpS}fI7FWzB`qr>( zh+y<6{%6D81igLb=-TITyaub_WY%`ur^dU*K0Cd9s99Q>>kY!WYJ9*YA;}r&jv^?% z3Mz2KCbxEGi#Z7#V#FnN2qE3ix7c)D5A2Sq*qB#uqSYgPXt6eFXZ9e1WWT1R8K{Q3 zxxAk{8*Rm#>-btAzUnTUj75TB^{?&eUbY}Y1^(CjFXvHY22f@g^lW8M{hu<=^q|v? z-tm3cdmQdoU+6V21UDq7qo~Rhndq+Wn9EflTG8_O7rELM`;h`pi|^+p6OHMD=@_-Hnf;)L*?6nrojNj1Q%F< zE<`Cqu2nLFvdt^Os&H?dH~qvbJsAej<~m5Lm`UzJKAhziST=Jg?i)zYTK72netn^_ zIoSYGwHEXF!}BFe(I2yO{(pRFx1Q**>MtpA-zkRTg8rTR|as|*C+=~cCsey;(VS{lsy7qg6$`wb4ENIgXVep^}p_q+PvKP9TTd40h9eW z&rQklW?6)O<=u?J9_;@Do8$?^-t@gBqjde^%eiYi$IHAj*2 zqEiAU41YRXD8=qm5*1bsCp|sTi^bblM4Y~uQPlqitT)*b*I{B*1Q|pq#BKNLwx66^ zKl-T_C6c9D#46BW8P0tw{8`77<>fyH`vVX^5=xdgzgl zVyX@gG2T2mc`P9O162VL5y;VUfnW-V7se#R22jC6o7_p6s_ox!J(kbmD zp5l?QEw`TJ*y(ZG#r0i+83!(K8Tc;tQcis=dq+G4EsVU?d>YyqAI!Ek`P1lpGKEDh z5GJs`JGlBY_P(muEHh1`B{VwT>ftC?l3lhIGL5(z!V=KTiFYb?>lSM5kBP-#W%P{1 z3p+7^_}usTmkZ=p70C9IwOV7J4w*?E>qVppdF0oA=|oUP!;K2x=}Qe;zcr&`F)eUC zS|MGI>hWE+g&5iU`jeG$M3u!x?&!rMqstH>=kLow<`b_I3^?HqCxLQaF=3XP62fU)z0 z3i^>n27p%*MVhGo%0!g55vRsf;eOs7o-rg_#U; z+rF58RxadiVj?+hb<4o_WrEpcP@*pcfxZDFg^=wP=gA?s>xb)tU|LQoqygM{N)N&Z zm$$AOV>(>qwB&9FOqUtz_mL+5@6*)edUAEyjG4%<_d%mJlM^#=k8kqvP+GHC?)Oe# zBbaAvMAkUkewG9yUz|gTkuTHkx*_Q&lW6&LK{e|nx)9h>l$oDQse+r96YbDn$8JkC zuT&!Zrs3BJD}x!>->PB{T~v8F_B#|a6U&`LWTJzXo#>dRU9qiCLyy2FdZ0sxk_Jep zGkvwonn#WD$*_e1%qSUCbf{;fjijQTkv~of&`;GGTryXVRqG#K)((lZ--T!|;7_Gp z98EpSRsOq#>gdo$eq44I8j|`9Y#XP@06?%eC4>kXsHYI0w9!mOuq~NE;@Bd|FdS3!LjQ{BMN1mL zi`}=dexIT_59@w!a&5Dlmo;earDqMTRMngTw73f~4mb5$sxGR!9Z>Nw&F<)u(#=GuJqeq`+ku%je z?bie6ApGz%B9&iqC!o#jLf^7-K8uQbHK%%|it2vjaIlRB)&P{E<}d=y-IX_GD1}xz zOn>na6>f3*Rr@_?%ioZRL&VlK9+Tm1S6lkeKKpIQBW-%+?ovZ+UzFpp literal 0 HcmV?d00001 diff --git a/BuildingQuality/sample-code/gebish/web-app/images/grails_logo.png b/BuildingQuality/sample-code/gebish/web-app/images/grails_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..9836b93d2cbdee17ee3c18329bef39ec724dcf97 GIT binary patch literal 10172 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 Vd*l#Wn-~B9002ovPDHLkV1nEVK@R`` literal 0 HcmV?d00001 diff --git a/BuildingQuality/sample-code/gebish/web-app/images/leftnav_midstretch.png b/BuildingQuality/sample-code/gebish/web-app/images/leftnav_midstretch.png new file mode 100644 index 0000000000000000000000000000000000000000..3cb8a51559b4bd4ed79fba033b4274b33e5cdd2c GIT binary patch literal 2883 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 literal 0 HcmV?d00001 diff --git a/BuildingQuality/sample-code/gebish/web-app/images/leftnav_top.png b/BuildingQuality/sample-code/gebish/web-app/images/leftnav_top.png new file mode 100644 index 0000000000000000000000000000000000000000..6afec7d32f3163446829de0ed38099021fc7b0d6 GIT binary patch literal 3317 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 literal 0 HcmV?d00001 diff --git a/BuildingQuality/sample-code/gebish/web-app/images/skin/database_delete.png b/BuildingQuality/sample-code/gebish/web-app/images/skin/database_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..cce652e845cde732ac3ce9a4132b597301ad660e GIT binary patch literal 659 zcmV;E0&M+>P)ps_J1 zHhTmGl@tMUh=_=a3Fb%)BqZVTW3s!xH?UsxE?7A5@n+t<@6Gq#%m~l(@IOPFT;%il z03|#}Sa4nU2-$-Kn!4}FekQv@$S0FY$L9!N0g;c={9!m8K4zLG48uSu6aw$J+ii5a zT~sO+G#ZW9!I0fqFSvY9*@h|sR=YqL#x%oU@(yD@pz0* zr-R{eDEHX6V*RaK<|4rWl@GKt@8COeKZT>%ICBq4+h_I-+?Y*V28oxmqBc+Oz5 zc>4@kzJgDe<1lkKXYEtktsNC`FoTI)4qLaF!_1E&4qv>EKx`iUcee83)!MzalltZ# z3K)~8`*H_w9^uf5^9X)<39-6>(AOuJvu0IKc#FRkFoCa%ULtC>8v6bIR-H|{S~CWm zy|LB2yL+L!Vs5g8ONBz=aUzj0EX$JbfSV}a#vT*B_2)32Uc<0oLyzLS9V$=7hM4?~ znM@`|iEa~8)bZW?7q}d~l*7K(I`+@}grT|_=WaH**u tj~DMRZZpzVy^OjT85Vq(G=8XD@S91FH}kp`d7hyPh1 z5CCa%X>*RH50W(1GMNlqE*ChCgTvu4bCM)M5Co)BDTG2HvvyYjmSvI4<)A2v`CcxU zQ79BpEEdf*P56K_c;lUWy=bic9s#4IZm`yWps?HR<^;5uf_%3rLf1Uy7}ym7{u3SG zgQxL#;V@<+y-&7GK#MIB!!Xb^&5SuEhPoOV9{wDJpWonQN~qlHho`!h-y&cUDCjiw zot3{JSR;b3Z$U9V2&bDtVsaL$Qu?FFtIb;kXm<)qqyl<=9Kq@&_)r^^)N|OJWjH)_ za7i;6X_aj`duRB^h5&`toyKA^3V-E1_yb`=eg>PPj8Y+p^vFkpk)_tg?(s>=HO~R< zNVkfdL~{$}rBQI|9QHR{MrpYhcBg@2p$?h%pAnUsbBDUeKUv#oTc6-&EEZdf$Kwze zM&QwZLDd6D&pd?=1#1F{N2f6?Hf8gwvt`>|pf)ft5F|nm_AI~XywcT&?}K--v^WN? z_7vo-s3)9F{TXfF{hpqll^q2vdwBb}datvKg-yfc+gC^|#8-K5)%lB$rlxi}-rEGO xUZ|2A>wRp~(I5;*aZFyx-fDe3J-^%i_y?+(!m^mX(n$aS002ovPDHLkV1gwlT*CkW literal 0 HcmV?d00001 diff --git a/BuildingQuality/sample-code/gebish/web-app/images/skin/database_save.png b/BuildingQuality/sample-code/gebish/web-app/images/skin/database_save.png new file mode 100644 index 0000000000000000000000000000000000000000..44c06dddf19fbda14efe428b9b1793c13f46b2cf GIT binary patch literal 755 zcmV3^_07cLZBR}_>&jXObH zw2it@svr%qE?kJ(Xuudu+DSW|WWK!jNvbU^UO02#+Tt zYOko4%Vx8c4Gh!M(=Qem7g;XcE?n0Qi^XD?&*vX7@xPFCIh;%;@xMr?(;$(vo9j9i z6;riZMJyIWG#Z6r7^-I5HtO{{DwPWQ`}>&y+Y;!yjz*&a$8prX=XtO!3$0d5J>%Mz z1f8>Jnx-7^X2#7Yb#zC2VYfZ>c17@L{s)8{OuWBa3WHFfVXfhLv2t?V0V~q5R2D*D z&315l_#iF}b>Zoo?-;+7*`WOJWsMw(x3WXv`@U*s@Y-&edFEYpz0skP)dFfu zZ4wIp&Vbb!+|0+3Qa}p<*AH-eY>3q8s6?RA)zqP8W39IT5HLFG9m1F);gE|P`L7@@ zctjKsn1rA6!ZZR%R^(SjU!r=2o$yGp<$KViK~{B;AIcgvN+J+&Nvur+W(Sw&=H?z} zGMRW^U!Nl3AvWzQ3~C%Z*G*(?qLfNCq;tpg2yRW4@yl9;p3CK)O-@c8Sy))OUMiKc zQp#QYFZe-*@LZDInR^#F=Bm=!vA2i6tkEJ#i0aggzp2D%3!>h~r~3uLt(-IMoyFAT&uF!>{(iS?1OX-eX zKw9bunxR5FrF6QaYs~9>A4#zW^dwIvCpq(+cfR?U`T6-{9LHUqo16RKcDwUVr?cX4 zIN~hJDs48~aRAJ}U_2g=KAB9SP$;0;Y@*$6Ly{z<(`i^NmbL#1W@l#$wOS3;YPBOE zJ;7`?L*?Ga6XzC292wl75}>gDz`(>h?is$JPxm#0jGnotoK|nAVM5$DQ z!C*kO-aeF@+Ejy?nVHEp8V&F~k7BWicsx!aH9kHLRpcQ?L&JFBAB4i&kAaVUxVvzh z3a-EY0%m%8nhI7|SE(QpiBL#sG#VUMM9}*(0mg2(Q$Zq;z|PJNd_Euiem@;jtJN@i za|c2MmsL?PR;yKNwOUA}QuO=7;V@#c7!{~gs?J7hAlsE7U#g?$aRkhSTqLq6iuCu9 z10_j_=;?Dc?4cZ386qH0HkgHTDT|HmGR`W4V2noNQJqfLJEot)q{V_UtsW+m31cP~ zDwWEi3HYBSoF4M;T?VaIdqinn1HZ9}32qs-PdwPbCf+WI6n9jl0-8cjV3%1FB%B&r z+`mzSliyLSH0dxYE}rk&=!uCa*V>()2znj`_XYjtbt>@4FLHnJE|G`xv)Ba@oLBny z1%3K7c4fiB^4{k6E8Pif0kNy62}b@9+N#0$9Ug7g~-`rQ^qx~m@y2OU8A z#zh~=7n#Z$Z*fx-GOtDf07cgx0suCz_W(2~Y(0tf@FX@P6EPuM_dgn$vj9LucO)%W zw%HgMW>=#oL>nZ>M&NEf08>)#)k<{$fCT_r>rPi=BV=hFh6WS^qqze>C6Ek}o{M5% za|@JGowu0t{&hgNzySHZxy@LTNh);YzZ2zSp_ zl$^T&Dnc|NLb&RD_!4>pt@VHdP)ZGER%5ZmWEe$lryR&y;2u^3cOkO4#6c%-(EY6a{600000NkvXXu0mjfxS2AI literal 0 HcmV?d00001 diff --git a/BuildingQuality/sample-code/gebish/web-app/images/skin/house.png b/BuildingQuality/sample-code/gebish/web-app/images/skin/house.png new file mode 100644 index 0000000000000000000000000000000000000000..fed62219f57cdfb854782dbadf5123c44d056bd4 GIT binary patch literal 806 zcmV+>1KIqEP)v;U&v3%|^C`Ga3?LtY&4dQB4Oz;1v;J%z!D&%WRH@BZ?x; z3)8@IUIv@hG|@IwyHLC`l{1<4BK>wam95g|i|?Cfzt876&-Zx_0f5*l-9`IJI&mHu zE6$@xB)6N}7VeR;!X8D!TAw;;&0Bsj?A071cO>X3K0wl7WZ1;Tg!4LHyNcnzoeQ7t zNW`aSlm8WXYkek&ir$13=ngczvf zV0vnjNpCF&K8px}dunv+`LIb-sOC$_jD(;IBI$xC|7`(+9cA>Vir_V#z{?k7SX^Ah z^71m~W@q439Ycqfhi7+gp#A14n1n1!e>$EdeATG|f798Y=ggzwEKH2Q!qU2QA(Se?dwqG69%>n$6rtE z%F(845Az8c{w(XgimJg96!jLMz?zS6I1HUm2baqQx7&@nx;lhHA!r6vs2|fqJETOu zLxeu2OQ(3(au%dg>AcZsWI(zXn9XJg1cLe8k~0h0wOL=&HK}7X k{AKr*U4z7Szv)i%9gTgghwgU$Q~&?~07*qoM6N<$g31kYk^lez literal 0 HcmV?d00001 diff --git a/BuildingQuality/sample-code/gebish/web-app/images/skin/information.png b/BuildingQuality/sample-code/gebish/web-app/images/skin/information.png new file mode 100644 index 0000000000000000000000000000000000000000..12cd1aef900803abba99b26920337ec01ad5c267 GIT binary patch literal 778 zcmV+l1NHogP)BVme|mWaqy4$_pJm?y9KM{-*hp?1+Ey3e-CEDooTa!B;e(Q>TSF?bj>5At13y1p zriN3w3x~5SfZj{@J4M{kp{?=M_Lh2bV+5LH)Q)5W!-ePA$RgE1@5f1cyHki0Y}JyVEYZF(LD$xXlt$7A5CgE@ zpV-&l%vf;=5kZ2-2gi@Y6J&=cuwt>!vJ^#(&n|LcZyUzi6Duj$$hJ1s*HD-#;k-w@ zpdrwAuoDG_N2bvb07G$Zk*?Hc)JLtW4yqOnic_$zO7NZ#l>Fm){;fE?b$IbOaX2fe z0la4g0Dfw2xk7Wi7NapVD8YMPCZu?A1QCK*67dgsvRKBLFtrM>?$%&_lD1882mzdO zWPdw5KWw6IT`m1b_8=lS5jt8D3=RDa=&jWzR-)S@56WMslZ~mKu1)-wpXB>rNBQ>N zU#K`#1B&v|_AQK;7I~B}OdGiUT9LX>f0xm6<;LeP!=vFjPsUQF*wCJ*dO)4YBypgdiuF!=i@6Zyi7F|q#K zz?tlSZULa@t1D?$e;f@b36&N!V2mjOHw|*FMR=dr@6o0ZXGBB_+=zx3%$`cG63Jm-*84Da1I50Ew7%?y?G#+5$ UVU>wEFhP-tNtBU=gM+~u00(^_>i_@% literal 0 HcmV?d00001 diff --git a/BuildingQuality/sample-code/gebish/web-app/images/skin/sorted_desc.gif b/BuildingQuality/sample-code/gebish/web-app/images/skin/sorted_desc.gif new file mode 100644 index 0000000000000000000000000000000000000000..38b3a01d078418d3afcdb2765251a9f21b7995be GIT binary patch literal 834 zcmZ?wbhEHbWMg1s_|Cu}C@83_tE;D{=jG+)?d|RKCt}{bc?%XSShQ%-?%lih?%lh8 z|9*y1Fd72GGz1iXvM@3*urla?{0GVt3>@+doD32i4hNW;7z9Kl3=A9^nYh^GDt25@ NJj%i*$Hu~74FL5|8=3$B literal 0 HcmV?d00001 diff --git a/BuildingQuality/sample-code/gebish/web-app/images/spinner.gif b/BuildingQuality/sample-code/gebish/web-app/images/spinner.gif new file mode 100644 index 0000000000000000000000000000000000000000..1ed786f2ece49ec5db07dee13a56ef38025b628c GIT binary patch literal 2037 zcmY*ZcTf|19{+AO8xjIZfItFCFrkL3BodGwflvety+|>T03uy{D35o<4X`9Q3=bSU zojZMs3Qw_)j=f_!)B!!mUKqwc>ezd^4c;H{$Ifr|uTTHRC8&buXgI)uM*u&6{`~Rd zM}L3+_wV1IK7G1x-@ebEKY#i1<^B8j-@bj@wr$&s7cWknII(;8?sMnPJ$(4^-Me>t z_wN1p@#D#pCr3v|A3b`6qUeJM5ANT;KRi7A^5x65YuBDSb?WNXs}mCwVPRo|gM+(v z?RxX(&Gzlv_w3no`}XavTesf4dGq@9>xT~?_VDnybm`KK8#fLfJh*P%x(gRB?AWp6 z>({T(pFdAaOMCY0SzBA%hYueT6BF;;xnpHzb@}q;O`A4(d3im4{J5Z?;ONn#0|NsW zFJ9cgfB);(ugAv5a&vP_OG`&aMz(C(^6J&A@$vBk2M!!Re*DRkCvV@rJ%9duQ&ZFC z&6|%MJC>4?a{Bb?vuDqqIdg`~z*4Ws1>(;I2=4ORL zQCC-|R4OYgD_5;rwQSk44I4IW+_=%t&(GD>Rj=1yxpHM_Xh`ytnG&0k9<5Zz%KT@c z2mnYvQ>hsF`jQ_R5(mKIydH2saldkg!Gzlvi9nFeu<gyfnCs8|SGO1R0M3N~Sp zx@MoynP5Rh(303ldPHFemMT%$+lXy}A1JR?IwL6=E`apW=@Z-0R!QO^@j_&{6#;i|5R1o$ zJ1J~xCDQ$1cs9`DW9Z!)D)^+%&Ug81908UkMXX;jkp>#b+SE}d{`0S>>Ef(`Ns6oa zB~H-LX25y1!BDgW%?nC0$RettYz8zsuz>9Z!g8TH$kU;rwYWrSTkjuYCH9utgFU6b z*wzBKaG6IjEXYSpAo5j4&c(t zwi-c(Q6YX2N-v2q(mgN`>wuCTV&XSRUA4h-f8g+uV2k_=o;2wb`7N)&+7T-C+CT_Bu4KrjWmK>x0AbH2rmR&7+q6fX+R0o&}V!t?TP+g0{x`8PSP{7CvnEPL^Hzx^T2Eus2 zi$U6ZM7}+l%$}afWn#%|+MPTsC236GKi9-ad*Z9;Ymg?jSO$L1s$w4BvDzu_kH9>z zTWC{K?jx4~H3oGGt3}I}LWNw@H)C>9GF4^|x(5n#+Va}kr_cb>{a+K%>B+@JNrC8? zJOUkD3fe*NdA-rJupqo?FfRK}k zOm!l7Dj$dsL|kS`3FL3^@^7axrU9d*@79yf!+bu3kXbziU!v&TO3p#w{y_lYG5ZPzDh;giB_lkGp((nqZ12&%LTrgm4vY= z{ffd0B$DiUKReJ9>?{#_KVrMyhiu_A8fNd!&DWTZ4+9S|1lJHkLv-^}a0IC{WI9N! zQTY-}db!%OH^;l2ZeajnA&Q6Uv=#0KZB9;^^lzMOi^0~bS~m!&K#e6hia79(ItV9M SXP~*+AU!zMlD%~Wg#Hic*k=_0 literal 0 HcmV?d00001 diff --git a/BuildingQuality/sample-code/gebish/web-app/images/springsource.png b/BuildingQuality/sample-code/gebish/web-app/images/springsource.png new file mode 100644 index 0000000000000000000000000000000000000000..e806d001151dd0c5dfbb2d24e9255e7b1f3c1cc3 GIT binary patch literal 9109 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 literal 0 HcmV?d00001 diff --git a/BuildingQuality/sample-code/gebish/web-app/js/application.js b/BuildingQuality/sample-code/gebish/web-app/js/application.js new file mode 100644 index 0000000..b2adb96 --- /dev/null +++ b/BuildingQuality/sample-code/gebish/web-app/js/application.js @@ -0,0 +1,9 @@ +if (typeof jQuery !== 'undefined') { + (function($) { + $('#spinner').ajaxStart(function() { + $(this).fadeIn(); + }).ajaxStop(function() { + $(this).fadeOut(); + }); + })(jQuery); +} diff --git a/BuildingQuality/sample-code/metrics/.classpath b/BuildingQuality/sample-code/metrics/.classpath new file mode 100644 index 0000000..ebd5145 --- /dev/null +++ b/BuildingQuality/sample-code/metrics/.classpath @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/BuildingQuality/sample-code/metrics/.gitignore b/BuildingQuality/sample-code/metrics/.gitignore new file mode 100644 index 0000000..398559c --- /dev/null +++ b/BuildingQuality/sample-code/metrics/.gitignore @@ -0,0 +1,15 @@ +*.iws +*Db.properties +*Db.script +.settings +stacktrace.log +/*.zip +/plugin.xml +/*.log +/*DB.* +/cobertura.ser +.DS_Store +/target/ +/out/ +/web-app/plugins +/web-app/WEB-INF/classes \ No newline at end of file diff --git a/BuildingQuality/sample-code/metrics/.project b/BuildingQuality/sample-code/metrics/.project new file mode 100644 index 0000000..7cacb91 --- /dev/null +++ b/BuildingQuality/sample-code/metrics/.project @@ -0,0 +1,19 @@ + + + metrics + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + com.springsource.sts.grails.core.nature + org.eclipse.jdt.groovy.core.groovyNature + org.eclipse.jdt.core.javanature + + diff --git a/BuildingQuality/sample-code/metrics/application.properties b/BuildingQuality/sample-code/metrics/application.properties new file mode 100644 index 0000000..cb6e3a8 --- /dev/null +++ b/BuildingQuality/sample-code/metrics/application.properties @@ -0,0 +1,9 @@ +#Grails Metadata file +#Fri Mar 30 07:10:18 CDT 2012 +app.grails.version=2.0.1 +app.name=metrics +app.servlet.version=2.5 +app.version=0.1 +plugins.code-coverage=1.2.5 +plugins.codenarc=0.16.1 +plugins.jslint=0.3 diff --git a/BuildingQuality/sample-code/metrics/grails-app/conf/ApplicationResources.groovy b/BuildingQuality/sample-code/metrics/grails-app/conf/ApplicationResources.groovy new file mode 100644 index 0000000..06b60c7 --- /dev/null +++ b/BuildingQuality/sample-code/metrics/grails-app/conf/ApplicationResources.groovy @@ -0,0 +1,5 @@ +modules = { + application { + resource url:'js/application.js' + } +} \ No newline at end of file diff --git a/BuildingQuality/sample-code/metrics/grails-app/conf/BootStrap.groovy b/BuildingQuality/sample-code/metrics/grails-app/conf/BootStrap.groovy new file mode 100644 index 0000000..1287dae --- /dev/null +++ b/BuildingQuality/sample-code/metrics/grails-app/conf/BootStrap.groovy @@ -0,0 +1,7 @@ +class BootStrap { + + def init = { servletContext -> + } + def destroy = { + } +} diff --git a/BuildingQuality/sample-code/metrics/grails-app/conf/BuildConfig.groovy b/BuildingQuality/sample-code/metrics/grails-app/conf/BuildConfig.groovy new file mode 100644 index 0000000..4c34978 --- /dev/null +++ b/BuildingQuality/sample-code/metrics/grails-app/conf/BuildConfig.groovy @@ -0,0 +1,51 @@ +grails.servlet.version = "2.5" // Change depending on target container compliance (2.5 or 3.0) +grails.project.class.dir = "target/classes" +grails.project.test.class.dir = "target/test-classes" +grails.project.test.reports.dir = "target/test-reports" +grails.project.target.level = 1.6 +grails.project.source.level = 1.6 +//grails.project.war.file = "target/${appName}-${appVersion}.war" + +grails.project.dependency.resolution = { + // inherit Grails' default dependencies + inherits("global") { + // uncomment to disable ehcache + // excludes 'ehcache' + } + log "error" // log level of Ivy resolver, either 'error', 'warn', 'info', 'debug' or 'verbose' + checksums true // Whether to verify checksums on resolve + + repositories { + inherits true // Whether to inherit repository definitions from plugins + grailsPlugins() + grailsHome() + grailsCentral() + mavenCentral() + + // uncomment these to enable remote dependency resolution from public Maven repositories + //mavenCentral() + //mavenLocal() + //mavenRepo "http://snapshots.repository.codehaus.org" + //mavenRepo "http://repository.codehaus.org" + //mavenRepo "http://download.java.net/maven/2/" + //mavenRepo "http://repository.jboss.com/maven2/" + } + dependencies { + // specify dependencies here under either 'build', 'compile', 'runtime', 'test' or 'provided' scopes eg. + + // runtime 'mysql:mysql-connector-java:5.1.16' + } + + plugins { + runtime ":hibernate:$grailsVersion" + runtime ":jquery:1.7.1" + runtime ":resources:1.1.6" + + // Uncomment these (or add new ones) to enable additional resources capabilities + //runtime ":zipped-resources:1.0" + //runtime ":cached-resources:1.0" + //runtime ":yui-minify-resources:0.1.4" + + build ":tomcat:$grailsVersion" + } +} diff --git a/BuildingQuality/sample-code/metrics/grails-app/conf/Config.groovy b/BuildingQuality/sample-code/metrics/grails-app/conf/Config.groovy new file mode 100644 index 0000000..40fda44 --- /dev/null +++ b/BuildingQuality/sample-code/metrics/grails-app/conf/Config.groovy @@ -0,0 +1,93 @@ +// locations to search for config files that get merged into the main config +// config files can either be Java properties files or ConfigSlurper scripts + +// grails.config.locations = [ "classpath:${appName}-config.properties", +// "classpath:${appName}-config.groovy", +// "file:${userHome}/.grails/${appName}-config.properties", +// "file:${userHome}/.grails/${appName}-config.groovy"] + +// if (System.properties["${appName}.config.location"]) { +// grails.config.locations << "file:" + System.properties["${appName}.config.location"] +// } + + +grails.project.groupId = appName // change this to alter the default package name and Maven publishing destination +grails.mime.file.extensions = true // enables the parsing of file extensions from URLs into the request format +grails.mime.use.accept.header = false +grails.mime.types = [ html: ['text/html','application/xhtml+xml'], + xml: ['text/xml', 'application/xml'], + text: 'text/plain', + js: 'text/javascript', + rss: 'application/rss+xml', + atom: 'application/atom+xml', + css: 'text/css', + csv: 'text/csv', + all: '*/*', + json: ['application/json','text/json'], + form: 'application/x-www-form-urlencoded', + multipartForm: 'multipart/form-data' + ] + +// URL Mapping Cache Max Size, defaults to 5000 +//grails.urlmapping.cache.maxsize = 1000 + +// What URL patterns should be processed by the resources plugin +grails.resources.adhoc.patterns = ['/images/*', '/css/*', '/js/*', '/plugins/*'] + + +// The default codec used to encode data with ${} +grails.views.default.codec = "none" // none, html, base64 +grails.views.gsp.encoding = "UTF-8" +grails.converters.encoding = "UTF-8" +// enable Sitemesh preprocessing of GSP pages +grails.views.gsp.sitemesh.preprocess = true +// scaffolding templates configuration +grails.scaffolding.templates.domainSuffix = 'Instance' + +// Set to false to use the new Grails 1.2 JSONBuilder in the render method +grails.json.legacy.builder = false +// enabled native2ascii conversion of i18n properties files +grails.enable.native2ascii = true +// packages to include in Spring bean scanning +grails.spring.bean.packages = [] +// whether to disable processing of multi part requests +grails.web.disable.multipart=false + +// request parameters to mask when logging exceptions +grails.exceptionresolver.params.exclude = ['password'] + +// enable query caching by default +grails.hibernate.cache.queries = true + +// set per-environment serverURL stem for creating absolute links +environments { + development { + grails.logging.jul.usebridge = true + } + production { + grails.logging.jul.usebridge = false + // TODO: grails.serverURL = "http://www.changeme.com" + } +} + +// log4j configuration +log4j = { + // Example of changing the log pattern for the default console + // appender: + // + //appenders { + // console name:'stdout', layout:pattern(conversionPattern: '%c{2} %m%n') + //} + + error 'org.codehaus.groovy.grails.web.servlet', // controllers + 'org.codehaus.groovy.grails.web.pages', // GSP + 'org.codehaus.groovy.grails.web.sitemesh', // layouts + 'org.codehaus.groovy.grails.web.mapping.filter', // URL mapping + 'org.codehaus.groovy.grails.web.mapping', // URL mapping + 'org.codehaus.groovy.grails.commons', // core / classloading + 'org.codehaus.groovy.grails.plugins', // plugins + 'org.codehaus.groovy.grails.orm.hibernate', // hibernate integration + 'org.springframework', + 'org.hibernate', + 'net.sf.ehcache.hibernate' +} diff --git a/BuildingQuality/sample-code/metrics/grails-app/conf/DataSource.groovy b/BuildingQuality/sample-code/metrics/grails-app/conf/DataSource.groovy new file mode 100644 index 0000000..615600a --- /dev/null +++ b/BuildingQuality/sample-code/metrics/grails-app/conf/DataSource.groovy @@ -0,0 +1,43 @@ +dataSource { + pooled = true + driverClassName = "org.h2.Driver" + username = "sa" + password = "" +} +hibernate { + cache.use_second_level_cache = true + cache.use_query_cache = true + cache.region.factory_class = 'net.sf.ehcache.hibernate.EhCacheRegionFactory' +} +// environment specific settings +environments { + development { + dataSource { + dbCreate = "create-drop" // one of 'create', 'create-drop', 'update', 'validate', '' + url = "jdbc:h2:mem:devDb;MVCC=TRUE" + } + } + test { + dataSource { + dbCreate = "update" + url = "jdbc:h2:mem:testDb;MVCC=TRUE" + } + } + production { + dataSource { + dbCreate = "update" + url = "jdbc:h2:prodDb;MVCC=TRUE" + pooled = true + properties { + maxActive = -1 + minEvictableIdleTimeMillis=1800000 + timeBetweenEvictionRunsMillis=1800000 + numTestsPerEvictionRun=3 + testOnBorrow=true + testWhileIdle=true + testOnReturn=true + validationQuery="SELECT 1" + } + } + } +} diff --git a/BuildingQuality/sample-code/metrics/grails-app/conf/UrlMappings.groovy b/BuildingQuality/sample-code/metrics/grails-app/conf/UrlMappings.groovy new file mode 100644 index 0000000..8c597d6 --- /dev/null +++ b/BuildingQuality/sample-code/metrics/grails-app/conf/UrlMappings.groovy @@ -0,0 +1,13 @@ +class UrlMappings { + + static mappings = { + "/$controller/$action?/$id?"{ + constraints { + // apply constraints here + } + } + + "/"(view:"/index") + "500"(view:'/error') + } +} diff --git a/BuildingQuality/sample-code/metrics/grails-app/conf/spring/resources.groovy b/BuildingQuality/sample-code/metrics/grails-app/conf/spring/resources.groovy new file mode 100644 index 0000000..fa95006 --- /dev/null +++ b/BuildingQuality/sample-code/metrics/grails-app/conf/spring/resources.groovy @@ -0,0 +1,3 @@ +// Place your Spring DSL code here +beans = { +} diff --git a/BuildingQuality/sample-code/metrics/grails-app/controllers/metrics/BookController.groovy b/BuildingQuality/sample-code/metrics/grails-app/controllers/metrics/BookController.groovy new file mode 100644 index 0000000..cb88e2a --- /dev/null +++ b/BuildingQuality/sample-code/metrics/grails-app/controllers/metrics/BookController.groovy @@ -0,0 +1,103 @@ +package metrics + +import org.springframework.dao.DataIntegrityViolationException + +class BookController { + + static allowedMethods = [save: "POST", update: "POST", delete: "POST"] + + def index() { + redirect(action: "list", params: params) + } + + def list() { + params.max = Math.min(params.max ? params.int('max') : 10, 100) + [bookInstanceList: Book.list(params), bookInstanceTotal: Book.count()] + } + + def create() { + [bookInstance: new Book(params)] + } + + def save() { + def bookInstance = new Book(params) + if (!bookInstance.save(flush: true)) { + render(view: "create", model: [bookInstance: bookInstance]) + return + } + + flash.message = message(code: 'default.created.message', args: [message(code: 'book.label', default: 'Book'), bookInstance.id]) + redirect(action: "show", id: bookInstance.id) + } + + def show() { + def bookInstance = Book.get(params.id) + if (!bookInstance) { + flash.message = message(code: 'default.not.found.message', args: [message(code: 'book.label', default: 'Book'), params.id]) + redirect(action: "list") + return + } + + [bookInstance: bookInstance] + } + + def edit() { + def bookInstance = Book.get(params.id) + if (!bookInstance) { + flash.message = message(code: 'default.not.found.message', args: [message(code: 'book.label', default: 'Book'), params.id]) + redirect(action: "list") + return + } + + [bookInstance: bookInstance] + } + + def update() { + def bookInstance = Book.get(params.id) + if (!bookInstance) { + flash.message = message(code: 'default.not.found.message', args: [message(code: 'book.label', default: 'Book'), params.id]) + redirect(action: "list") + return + } + + if (params.version) { + def version = params.version.toLong() + if (bookInstance.version > version) { + bookInstance.errors.rejectValue("version", "default.optimistic.locking.failure", + [message(code: 'book.label', default: 'Book')] as Object[], + "Another user has updated this Book while you were editing") + render(view: "edit", model: [bookInstance: bookInstance]) + return + } + } + + bookInstance.properties = params + + if (!bookInstance.save(flush: true)) { + render(view: "edit", model: [bookInstance: bookInstance]) + return + } + + flash.message = message(code: 'default.updated.message', args: [message(code: 'book.label', default: 'Book'), bookInstance.id]) + redirect(action: "show", id: bookInstance.id) + } + + def delete() { + def bookInstance = Book.get(params.id) + if (!bookInstance) { + flash.message = message(code: 'default.not.found.message', args: [message(code: 'book.label', default: 'Book'), params.id]) + redirect(action: "list") + return + } + + try { + bookInstance.delete(flush: true) + flash.message = message(code: 'default.deleted.message', args: [message(code: 'book.label', default: 'Book'), params.id]) + redirect(action: "list") + } + catch (DataIntegrityViolationException e) { + flash.message = message(code: 'default.not.deleted.message', args: [message(code: 'book.label', default: 'Book'), params.id]) + redirect(action: "show", id: params.id) + } + } +} diff --git a/BuildingQuality/sample-code/metrics/grails-app/domain/metrics/Book.groovy b/BuildingQuality/sample-code/metrics/grails-app/domain/metrics/Book.groovy new file mode 100644 index 0000000..3e03780 --- /dev/null +++ b/BuildingQuality/sample-code/metrics/grails-app/domain/metrics/Book.groovy @@ -0,0 +1,7 @@ +package metrics + +class Book { + + static constraints = { + } +} diff --git a/BuildingQuality/sample-code/metrics/grails-app/i18n/messages.properties b/BuildingQuality/sample-code/metrics/grails-app/i18n/messages.properties new file mode 100644 index 0000000..0c9d7ee --- /dev/null +++ b/BuildingQuality/sample-code/metrics/grails-app/i18n/messages.properties @@ -0,0 +1,55 @@ +default.doesnt.match.message=Property [{0}] of class [{1}] with value [{2}] does not match the required pattern [{3}] +default.invalid.url.message=Property [{0}] of class [{1}] with value [{2}] is not a valid URL +default.invalid.creditCard.message=Property [{0}] of class [{1}] with value [{2}] is not a valid credit card number +default.invalid.email.message=Property [{0}] of class [{1}] with value [{2}] is not a valid e-mail address +default.invalid.range.message=Property [{0}] of class [{1}] with value [{2}] does not fall within the valid range from [{3}] to [{4}] +default.invalid.size.message=Property [{0}] of class [{1}] with value [{2}] does not fall within the valid size range from [{3}] to [{4}] +default.invalid.max.message=Property [{0}] of class [{1}] with value [{2}] exceeds maximum value [{3}] +default.invalid.min.message=Property [{0}] of class [{1}] with value [{2}] is less than minimum value [{3}] +default.invalid.max.size.message=Property [{0}] of class [{1}] with value [{2}] exceeds the maximum size of [{3}] +default.invalid.min.size.message=Property [{0}] of class [{1}] with value [{2}] is less than the minimum size of [{3}] +default.invalid.validator.message=Property [{0}] of class [{1}] with value [{2}] does not pass custom validation +default.not.inlist.message=Property [{0}] of class [{1}] with value [{2}] is not contained within the list [{3}] +default.blank.message=Property [{0}] of class [{1}] cannot be blank +default.not.equal.message=Property [{0}] of class [{1}] with value [{2}] cannot equal [{3}] +default.null.message=Property [{0}] of class [{1}] cannot be null +default.not.unique.message=Property [{0}] of class [{1}] with value [{2}] must be unique + +default.paginate.prev=Previous +default.paginate.next=Next +default.boolean.true=True +default.boolean.false=False +default.date.format=yyyy-MM-dd HH:mm:ss z +default.number.format=0 + +default.created.message={0} {1} created +default.updated.message={0} {1} updated +default.deleted.message={0} {1} deleted +default.not.deleted.message={0} {1} could not be deleted +default.not.found.message={0} not found with id {1} +default.optimistic.locking.failure=Another user has updated this {0} while you were editing + +default.home.label=Home +default.list.label={0} List +default.add.label=Add {0} +default.new.label=New {0} +default.create.label=Create {0} +default.show.label=Show {0} +default.edit.label=Edit {0} + +default.button.create.label=Create +default.button.edit.label=Edit +default.button.update.label=Update +default.button.delete.label=Delete +default.button.delete.confirm.message=Are you sure? + +# Data binding errors. Use "typeMismatch.$className.$propertyName to customize (eg typeMismatch.Book.author) +typeMismatch.java.net.URL=Property {0} must be a valid URL +typeMismatch.java.net.URI=Property {0} must be a valid URI +typeMismatch.java.util.Date=Property {0} must be a valid Date +typeMismatch.java.lang.Double=Property {0} must be a valid number +typeMismatch.java.lang.Integer=Property {0} must be a valid number +typeMismatch.java.lang.Long=Property {0} must be a valid number +typeMismatch.java.lang.Short=Property {0} must be a valid number +typeMismatch.java.math.BigDecimal=Property {0} must be a valid number +typeMismatch.java.math.BigInteger=Property {0} must be a valid number diff --git a/BuildingQuality/sample-code/metrics/grails-app/i18n/messages_cs_CZ.properties b/BuildingQuality/sample-code/metrics/grails-app/i18n/messages_cs_CZ.properties new file mode 100644 index 0000000..c617dca --- /dev/null +++ b/BuildingQuality/sample-code/metrics/grails-app/i18n/messages_cs_CZ.properties @@ -0,0 +1,55 @@ +default.doesnt.match.message=Položka [{0}] třídy [{1}] o hodnotě [{2}] neodpovídá požadovanému vzoru [{3}] +default.invalid.url.message=Položka [{0}] třídy [{1}] o hodnotě [{2}] není validní URL +default.invalid.creditCard.message=Položka [{0}] třídy [{1}] o hodnotě [{2}] není validní číslo kreditní karty +default.invalid.email.message=Položka [{0}] třídy [{1}] o hodnotě [{2}] není validní emailová adresa +default.invalid.range.message=Položka [{0}] třídy [{1}] o hodnotě [{2}] není v povoleném rozmezí od [{3}] do [{4}] +default.invalid.size.message=Položka [{0}] třídy [{1}] o hodnotě [{2}] není v povoleném rozmezí od [{3}] do [{4}] +default.invalid.max.message=Položka [{0}] třídy [{1}] o hodnotě [{2}] překračuje maximální povolenou hodnotu [{3}] +default.invalid.min.message=Položka [{0}] třídy [{1}] o hodnotě [{2}] je menší než minimální povolená hodnota [{3}] +default.invalid.max.size.message=Položka [{0}] třídy [{1}] o hodnotě [{2}] překračuje maximální velikost [{3}] +default.invalid.min.size.message=Položka [{0}] třídy [{1}] o hodnotě [{2}] je menší než minimální velikost [{3}] +default.invalid.validator.message=Položka [{0}] třídy [{1}] o hodnotě [{2}] neprošla validací +default.not.inlist.message=Položka [{0}] třídy [{1}] o hodnotě [{2}] není obsažena v seznamu [{3}] +default.blank.message=Položka [{0}] třídy [{1}] nemůže být prázdná +default.not.equal.message=Položka [{0}] třídy [{1}] o hodnotě [{2}] nemůže být stejná jako [{3}] +default.null.message=Položka [{0}] třídy [{1}] nemůže být prázdná +default.not.unique.message=Položka [{0}] třídy [{1}] o hodnotě [{2}] musí být unikátní + +default.paginate.prev=Předcházející +default.paginate.next=Následující +default.boolean.true=Pravda +default.boolean.false=Nepravda +default.date.format=dd. MM. yyyy HH:mm:ss z +default.number.format=0 + +default.created.message={0} {1} vytvořeno +default.updated.message={0} {1} aktualizováno +default.deleted.message={0} {1} smazáno +default.not.deleted.message={0} {1} nelze smazat +default.not.found.message={0} nenalezen s id {1} +default.optimistic.locking.failure=Jiný uživatel aktualizoval záznam {0}, právě když byl vámi editován + +default.home.label=Domů +default.list.label={0} Seznam +default.add.label=Přidat {0} +default.new.label=Nový {0} +default.create.label=Vytvořit {0} +default.show.label=Ukázat {0} +default.edit.label=Editovat {0} + +default.button.create.label=Vytvoř +default.button.edit.label=Edituj +default.button.update.label=Aktualizuj +default.button.delete.label=Smaž +default.button.delete.confirm.message=Jste si jistý? + +# Data binding errors. Use "typeMismatch.$className.$propertyName to customize (eg typeMismatch.Book.author) +typeMismatch.java.net.URL=Položka {0} musí být validní URL +typeMismatch.java.net.URI=Položka {0} musí být validní URI +typeMismatch.java.util.Date=Položka {0} musí být validní datum +typeMismatch.java.lang.Double=Položka {0} musí být validní desetinné číslo +typeMismatch.java.lang.Integer=Položka {0} musí být validní číslo +typeMismatch.java.lang.Long=Položka {0} musí být validní číslo +typeMismatch.java.lang.Short=Položka {0} musí být validní číslo +typeMismatch.java.math.BigDecimal=Položka {0} musí být validní číslo +typeMismatch.java.math.BigInteger=Položka {0} musí být validní číslo \ No newline at end of file diff --git a/BuildingQuality/sample-code/metrics/grails-app/i18n/messages_da.properties b/BuildingQuality/sample-code/metrics/grails-app/i18n/messages_da.properties new file mode 100644 index 0000000..858b229 --- /dev/null +++ b/BuildingQuality/sample-code/metrics/grails-app/i18n/messages_da.properties @@ -0,0 +1,56 @@ +default.doesnt.match.message=Feltet [{0}] i klassen [{1}] som har værdien [{2}] overholder ikke mønsteret [{3}] +default.invalid.url.message=Feltet [{0}] i klassen [{1}] som har værdien [{2}] er ikke en gyldig URL +default.invalid.creditCard.message=Feltet [{0}] i klassen [{1}] som har værdien [{2}] er ikke et gyldigt kreditkortnummer +default.invalid.email.message=Feltet [{0}] i klassen [{1}] som har værdien [{2}] er ikke en gyldig e-mail adresse +default.invalid.range.message=Feltet [{0}] i klassen [{1}] som har værdien [{2}] ligger ikke inden for intervallet fra [{3}] til [{4}] +default.invalid.size.message=Feltet [{0}] i klassen [{1}] som har værdien [{2}] ligger ikke inden for størrelsen fra [{3}] til [{4}] +default.invalid.max.message=Feltet [{0}] i klassen [{1}] som har værdien [{2}] overstiger den maksimale værdi [{3}] +default.invalid.min.message=Feltet [{0}] i klassen [{1}] som har værdien [{2}] er under den minimale værdi [{3}] +default.invalid.max.size.message=Feltet [{0}] i klassen [{1}] som har værdien [{2}] overstiger den maksimale størrelse på [{3}] +default.invalid.min.size.message=Feltet [{0}] i klassen [{1}] som har værdien [{2}] er under den minimale størrelse på [{3}] +default.invalid.validator.message=Feltet [{0}] i klassen [{1}] som har værdien [{2}] overholder ikke den brugerdefinerede validering +default.not.inlist.message=Feltet [{0}] i klassen [{1}] som har værdien [{2}] findes ikke i listen [{3}] +default.blank.message=Feltet [{0}] i klassen [{1}] kan ikke være tom +default.not.equal.message=Feltet [{0}] i klassen [{1}] som har værdien [{2}] må ikke være [{3}] +default.null.message=Feltet [{0}] i klassen [{1}] kan ikke være null +default.not.unique.message=Feltet [{0}] i klassen [{1}] som har værdien [{2}] skal være unik + +default.paginate.prev=Forrige +default.paginate.next=Næste +default.boolean.true=Sand +default.boolean.false=Falsk +default.date.format=yyyy-MM-dd HH:mm:ss z +default.number.format=0 + +default.created.message={0} {1} oprettet +default.updated.message={0} {1} opdateret +default.deleted.message={0} {1} slettet +default.not.deleted.message={0} {1} kunne ikke slettes +default.not.found.message={0} med id {1} er ikke fundet +default.optimistic.locking.failure=En anden bruger har opdateret denne {0} imens du har lavet rettelser + +default.home.label=Hjem +default.list.label={0} Liste +default.add.label=Tilføj {0} +default.new.label=Ny {0} +default.create.label=Opret {0} +default.show.label=Vis {0} +default.edit.label=Ret {0} + +default.button.create.label=Opret +default.button.edit.label=Ret +default.button.update.label=Opdater +default.button.delete.label=Slet +default.button.delete.confirm.message=Er du sikker? + +# Databindingsfejl. Brug "typeMismatch.$className.$propertyName for at passe til en given klasse (f.eks typeMismatch.Book.author) +typeMismatch.java.net.URL=Feltet {0} skal være en valid URL +typeMismatch.java.net.URI=Feltet {0} skal være en valid URI +typeMismatch.java.util.Date=Feltet {0} skal være en valid Dato +typeMismatch.java.lang.Double=Feltet {0} skal være et valid tal +typeMismatch.java.lang.Integer=Feltet {0} skal være et valid tal +typeMismatch.java.lang.Long=Feltet {0} skal være et valid tal +typeMismatch.java.lang.Short=Feltet {0} skal være et valid tal +typeMismatch.java.math.BigDecimal=Feltet {0} skal være et valid tal +typeMismatch.java.math.BigInteger=Feltet {0} skal være et valid tal + diff --git a/BuildingQuality/sample-code/metrics/grails-app/i18n/messages_de.properties b/BuildingQuality/sample-code/metrics/grails-app/i18n/messages_de.properties new file mode 100644 index 0000000..a942358 --- /dev/null +++ b/BuildingQuality/sample-code/metrics/grails-app/i18n/messages_de.properties @@ -0,0 +1,55 @@ +default.doesnt.match.message=Die Eigenschaft [{0}] des Typs [{1}] mit dem Wert [{2}] entspricht nicht dem vorgegebenen Muster [{3}] +default.invalid.url.message=Die Eigenschaft [{0}] des Typs [{1}] mit dem Wert [{2}] ist keine gültige URL +default.invalid.creditCard.message=Das Die Eigenschaft [{0}] des Typs [{1}] mit dem Wert [{2}] ist keine gültige Kreditkartennummer +default.invalid.email.message=Die Eigenschaft [{0}] des Typs [{1}] mit dem Wert [{2}] ist keine gültige E-Mail Adresse +default.invalid.range.message=Die Eigenschaft [{0}] des Typs [{1}] mit dem Wert [{2}] ist nicht im Wertebereich von [{3}] bis [{4}] +default.invalid.size.message=Die Eigenschaft [{0}] des Typs [{1}] mit dem Wert [{2}] ist nicht im Wertebereich von [{3}] bis [{4}] +default.invalid.max.message=Die Eigenschaft [{0}] des Typs [{1}] mit dem Wert [{2}] ist größer als der Höchstwert von [{3}] +default.invalid.min.message=Die Eigenschaft [{0}] des Typs [{1}] mit dem Wert [{2}] ist kleiner als der Mindestwert von [{3}] +default.invalid.max.size.message=Die Eigenschaft [{0}] des Typs [{1}] mit dem Wert [{2}] übersteigt den Höchstwert von [{3}] +default.invalid.min.size.message=Die Eigenschaft [{0}] des Typs [{1}] mit dem Wert [{2}] unterschreitet den Mindestwert von [{3}] +default.invalid.validator.message=Die Eigenschaft [{0}] des Typs [{1}] mit dem Wert [{2}] ist ungültig +default.not.inlist.message=Die Eigenschaft [{0}] des Typs [{1}] mit dem Wert [{2}] ist nicht in der Liste [{3}] enthalten. +default.blank.message=Die Eigenschaft [{0}] des Typs [{1}] darf nicht leer sein +default.not.equal.message=Die Eigenschaft [{0}] des Typs [{1}] mit dem Wert [{2}] darf nicht gleich [{3}] sein +default.null.message=Die Eigenschaft [{0}] des Typs [{1}] darf nicht null sein +default.not.unique.message=Die Eigenschaft [{0}] des Typs [{1}] mit dem Wert [{2}] darf nur einmal vorkommen + +default.paginate.prev=Vorherige +default.paginate.next=Nächste +default.boolean.true=Wahr +default.boolean.false=Falsch +default.date.format=dd.MM.yyyy HH:mm:ss z +default.number.format=0 + +default.created.message={0} {1} wurde angelegt +default.updated.message={0} {1} wurde geändert +default.deleted.message={0} {1} wurde gelöscht +default.not.deleted.message={0} {1} konnte nicht gelöscht werden +default.not.found.message={0} mit der id {1} wurde nicht gefunden +default.optimistic.locking.failure=Ein anderer Benutzer hat das {0} Object geändert während Sie es bearbeitet haben + +default.home.label=Home +default.list.label={0} Liste +default.add.label={0} hinzufügen +default.new.label={0} anlegen +default.create.label={0} anlegen +default.show.label={0} anzeigen +default.edit.label={0} bearbeiten + +default.button.create.label=Anlegen +default.button.edit.label=Bearbeiten +default.button.update.label=Aktualisieren +default.button.delete.label=Löschen +default.button.delete.confirm.message=Sind Sie sicher? + +# Data binding errors. Use "typeMismatch.$className.$propertyName to customize (eg typeMismatch.Book.author) +typeMismatch.java.net.URL=Die Eigenschaft {0} muss eine gültige URL sein +typeMismatch.java.net.URI=Die Eigenschaft {0} muss eine gültige URI sein +typeMismatch.java.util.Date=Die Eigenschaft {0} muss ein gültiges Datum sein +typeMismatch.java.lang.Double=Die Eigenschaft {0} muss eine gültige Zahl sein +typeMismatch.java.lang.Integer=Die Eigenschaft {0} muss eine gültige Zahl sein +typeMismatch.java.lang.Long=Die Eigenschaft {0} muss eine gültige Zahl sein +typeMismatch.java.lang.Short=Die Eigenschaft {0} muss eine gültige Zahl sein +typeMismatch.java.math.BigDecimal=Die Eigenschaft {0} muss eine gültige Zahl sein +typeMismatch.java.math.BigInteger=Die Eigenschaft {0} muss eine gültige Zahl sein \ No newline at end of file diff --git a/BuildingQuality/sample-code/metrics/grails-app/i18n/messages_es.properties b/BuildingQuality/sample-code/metrics/grails-app/i18n/messages_es.properties new file mode 100644 index 0000000..915db13 --- /dev/null +++ b/BuildingQuality/sample-code/metrics/grails-app/i18n/messages_es.properties @@ -0,0 +1,55 @@ +default.doesnt.match.message=La propiedad [{0}] de la clase [{1}] con valor [{2}] no corresponde al patrón [{3}] +default.invalid.url.message=La propiedad [{0}] de la clase [{1}] con valor [{2}] no es una URL válida +default.invalid.creditCard.message=La propiedad [{0}] de la clase [{1}] con valor [{2}] no es un número de tarjeta de crédito válida +default.invalid.email.message=La propiedad [{0}] de la clase [{1}] con valor [{2}] no es una dirección de correo electrónico válida +default.invalid.range.message=La propiedad [{0}] de la clase [{1}] con valor [{2}] no entra en el rango válido de [{3}] a [{4}] +default.invalid.size.message=La propiedad [{0}] de la clase [{1}] con valor [{2}] no entra en el tamaño válido de [{3}] a [{4}] +default.invalid.max.message=La propiedad [{0}] de la clase [{1}] con valor [{2}] excede el valor máximo [{3}] +default.invalid.min.message=La propiedad [{0}] de la clase [{1}] con valor [{2}] es menos que el valor mínimo [{3}] +default.invalid.max.size.message=La propiedad [{0}] de la clase [{1}] con valor [{2}] excede el tamaño máximo de [{3}] +default.invalid.min.size.message=La propiedad [{0}] de la clase [{1}] con valor [{2}] es menor que el tamaño mínimo de [{3}] +default.invalid.validator.message=La propiedad [{0}] de la clase [{1}] con valor [{2}] no es válido +default.not.inlist.message=La propiedad [{0}] de la clase [{1}] con valor [{2}] no esta contenido dentro de la lista [{3}] +default.blank.message=La propiedad [{0}] de la clase [{1}] no puede ser vacía +default.not.equal.message=La propiedad [{0}] de la clase [{1}] con valor [{2}] no puede igualar a [{3}] +default.null.message=La propiedad [{0}] de la clase [{1}] no puede ser nulo +default.not.unique.message=La propiedad [{0}] de la clase [{1}] con valor [{2}] debe ser única + +default.paginate.prev=Anterior +default.paginate.next=Siguiente +default.boolean.true=Verdadero +default.boolean.false=Falso +default.date.format=yyyy-MM-dd HH:mm:ss z +default.number.format=0 + +default.created.message={0} {1} creado +default.updated.message={0} {1} actualizado +default.deleted.message={0} {1} eliminado +default.not.deleted.message={0} {1} no puede eliminarse +default.not.found.message=No se encuentra {0} con id {1} +default.optimistic.locking.failure=Mientras usted editaba, otro usuario ha actualizado su {0} + +default.home.label=Principal +default.list.label={0} Lista +default.add.label=Agregar {0} +default.new.label=Nuevo {0} +default.create.label=Crear {0} +default.show.label=Mostar {0} +default.edit.label=Editar {0} + +default.button.create.label=Crear +default.button.edit.label=Editar +default.button.update.label=Actualizar +default.button.delete.label=Eliminar +default.button.delete.confirm.message=¿Está usted seguro? + +# Data binding errors. Use "typeMismatch.$className.$propertyName to customize (eg typeMismatch.Book.author) +typeMismatch.java.net.URL=La propiedad {0} debe ser una URL válida +typeMismatch.java.net.URI=La propiedad {0} debe ser una URI válida +typeMismatch.java.util.Date=La propiedad {0} debe ser una fecha válida +typeMismatch.java.lang.Double=La propiedad {0} debe ser un número válido +typeMismatch.java.lang.Integer=La propiedad {0} debe ser un número válido +typeMismatch.java.lang.Long=La propiedad {0} debe ser un número válido +typeMismatch.java.lang.Short=La propiedad {0} debe ser un número válido +typeMismatch.java.math.BigDecimal=La propiedad {0} debe ser un número válido +typeMismatch.java.math.BigInteger=La propiedad {0} debe ser un número válido \ No newline at end of file diff --git a/BuildingQuality/sample-code/metrics/grails-app/i18n/messages_fr.properties b/BuildingQuality/sample-code/metrics/grails-app/i18n/messages_fr.properties new file mode 100644 index 0000000..b1d665c --- /dev/null +++ b/BuildingQuality/sample-code/metrics/grails-app/i18n/messages_fr.properties @@ -0,0 +1,19 @@ +default.doesnt.match.message=La propriété [{0}] de la classe [{1}] avec la valeur [{2}] ne correspond pas au pattern [{3}] +default.invalid.url.message=La propriété [{0}] de la classe [{1}] avec la valeur [{2}] n'est pas une URL valide +default.invalid.creditCard.message=La propriété [{0}] de la classe [{1}] avec la valeur [{2}] n'est pas un numéro de carte de crédit valide +default.invalid.email.message=La propriété [{0}] de la classe [{1}] avec la valeur [{2}] n'est pas une adresse e-mail valide +default.invalid.range.message=La propriété [{0}] de la classe [{1}] avec la valeur [{2}] n'est pas contenue dans l'intervalle [{3}] à [{4}] +default.invalid.size.message=La propriété [{0}] de la classe [{1}] avec la valeur [{2}] n'est pas contenue dans l'intervalle [{3}] à [{4}] +default.invalid.max.message=La propriété [{0}] de la classe [{1}] avec la valeur [{2}] est supérieure à la valeur maximum [{3}] +default.invalid.min.message=La propriété [{0}] de la classe [{1}] avec la valeur [{2}] est inférieure à la valeur minimum [{3}] +default.invalid.max.size.message=La propriété [{0}] de la classe [{1}] avec la valeur [{2}] est supérieure à la valeur maximum [{3}] +default.invalid.min.size.message=La propriété [{0}] de la classe [{1}] avec la valeur [{2}] est inférieure à la valeur minimum [{3}] +default.invalid.validator.message=La propriété [{0}] de la classe [{1}] avec la valeur [{2}] n'est pas valide +default.not.inlist.message=La propriété [{0}] de la classe [{1}] avec la valeur [{2}] ne fait pas partie de la liste [{3}] +default.blank.message=La propriété [{0}] de la classe [{1}] ne peut pas être vide +default.not.equal.message=La propriété [{0}] de la classe [{1}] avec la valeur [{2}] ne peut pas être égale à [{3}] +default.null.message=La propriété [{0}] de la classe [{1}] ne peut pas être nulle +default.not.unique.message=La propriété [{0}] de la classe [{1}] avec la valeur [{2}] doit être unique + +default.paginate.prev=Précédent +default.paginate.next=Suivant diff --git a/BuildingQuality/sample-code/metrics/grails-app/i18n/messages_it.properties b/BuildingQuality/sample-code/metrics/grails-app/i18n/messages_it.properties new file mode 100644 index 0000000..ea83b92 --- /dev/null +++ b/BuildingQuality/sample-code/metrics/grails-app/i18n/messages_it.properties @@ -0,0 +1,19 @@ +default.doesnt.match.message=La proprietà [{0}] della classe [{1}] con valore [{2}] non corrisponde al pattern [{3}] +default.invalid.url.message=La proprietà [{0}] della classe [{1}] con valore [{2}] non è un URL valido +default.invalid.creditCard.message=La proprietà [{0}] della classe [{1}] con valore [{2}] non è un numero di carta di credito valido +default.invalid.email.message=La proprietà [{0}] della classe [{1}] con valore [{2}] non è un indirizzo email valido +default.invalid.range.message=La proprietà [{0}] della classe [{1}] con valore [{2}] non rientra nell'intervallo valido da [{3}] a [{4}] +default.invalid.size.message=La proprietà [{0}] della classe [{1}] con valore [{2}] non rientra nell'intervallo di dimensioni valide da [{3}] a [{4}] +default.invalid.max.message=La proprietà [{0}] della classe [{1}] con valore [{2}] è maggiore di [{3}] +default.invalid.min.message=La proprietà [{0}] della classe [{1}] con valore [{2}] è minore di [{3}] +default.invalid.max.size.message=La proprietà [{0}] della classe [{1}] con valore [{2}] è maggiore di [{3}] +default.invalid.min.size.message=La proprietà [{0}] della classe [{1}] con valore [{2}] è minore di [{3}] +default.invalid.validator.message=La proprietà [{0}] della classe [{1}] con valore [{2}] non è valida +default.not.inlist.message=La proprietà [{0}] della classe [{1}] con valore [{2}] non è contenuta nella lista [{3}] +default.blank.message=La proprietà [{0}] della classe [{1}] non può essere vuota +default.not.equal.message=La proprietà [{0}] della classe [{1}] con valore [{2}] non può essere uguale a [{3}] +default.null.message=La proprietà [{0}] della classe [{1}] non può essere null +default.not.unique.message=La proprietà [{0}] della classe [{1}] con valore [{2}] deve essere unica + +default.paginate.prev=Precedente +default.paginate.next=Successivo \ No newline at end of file diff --git a/BuildingQuality/sample-code/metrics/grails-app/i18n/messages_ja.properties b/BuildingQuality/sample-code/metrics/grails-app/i18n/messages_ja.properties new file mode 100644 index 0000000..b5e4d18 --- /dev/null +++ b/BuildingQuality/sample-code/metrics/grails-app/i18n/messages_ja.properties @@ -0,0 +1,55 @@ +default.doesnt.match.message=クラス[{1}]プロパティ[{0}]の値[{2}]は、[{3}]パターンと一致していません。 +default.invalid.url.message=クラス[{1}]プロパティ[{0}]の値[{2}]は、有効なURLではありません。 +default.invalid.creditCard.message=クラス[{1}]プロパティ[{0}]の値[{2}]は、有効なクレジットカード番号ではありません。 +default.invalid.email.message=クラス[{1}]プロパティ[{0}]の値[{2}]は、有効なメールアドレスではありません。 +default.invalid.range.message=クラス[{1}]プロパティ[{0}]の値[{2}]は、[{3}]から[{4}]範囲内を指定してください。 +default.invalid.size.message=クラス[{1}]プロパティ[{0}]の値[{2}]は、[{3}]から[{4}]以内を指定してください。 +default.invalid.max.message=クラス[{1}]プロパティ[{0}]の値[{2}]は、最大値[{3}]より大きいです。 +default.invalid.min.message=クラス[{1}]プロパティ[{0}]の値[{2}]は、最小値[{3}]より小さいです。 +default.invalid.max.size.message=クラス[{1}]プロパティ[{0}]の値[{2}]は、最大値[{3}]より大きいです。 +default.invalid.min.size.message=クラス[{1}]プロパティ[{0}]の値[{2}]は、最小値[{3}]より小さいです。 +default.invalid.validator.message=クラス[{1}]プロパティ[{0}]の値[{2}]は、カスタムバリデーションを通過できません。 +default.not.inlist.message=クラス[{1}]プロパティ[{0}]の値[{2}]は、[{3}]リスト内に存在しません。 +default.blank.message=[{1}]クラスのプロパティ[{0}]の空白は許可されません。 +default.not.equal.message=クラス[{1}]プロパティ[{0}]の値[{2}]は、[{3}]と同等ではありません。 +default.null.message=[{1}]クラスのプロパティ[{0}]にnullは許可されません。 +default.not.unique.message=クラス[{1}]プロパティ[{0}]の値[{2}]は既に使用されています。 + +default.paginate.prev=戻る +default.paginate.next=次へ +default.boolean.true=はい +default.boolean.false=いいえ +default.date.format=yyyy/MM/dd HH:mm:ss z +default.number.format=0 + +default.created.message={0}(id:{1})を作成しました。 +default.updated.message={0}(id:{1})を更新しました。 +default.deleted.message={0}(id:{1})を削除しました。 +default.not.deleted.message={0}(id:{1})は削除できませんでした。 +default.not.found.message={0}(id:{1})は見つかりませんでした。 +default.optimistic.locking.failure=この{0}は編集中に他のユーザによって先に更新されています。 + +default.home.label=ホーム +default.list.label={0}リスト +default.add.label={0}を追加 +default.new.label={0}を新規作成 +default.create.label={0}を作成 +default.show.label={0}詳細 +default.edit.label={0}を編集 + +default.button.create.label=作成 +default.button.edit.label=編集 +default.button.update.label=更新 +default.button.delete.label=削除 +default.button.delete.confirm.message=本当に削除してよろしいですか? + +# Data binding errors. Use "typeMismatch.$className.$propertyName to customize (eg typeMismatch.Book.author) +typeMismatch.java.net.URL={0}は有効なURLでなければなりません。 +typeMismatch.java.net.URI={0}は有効なURIでなければなりません。 +typeMismatch.java.util.Date={0}は有効な日付でなければなりません。 +typeMismatch.java.lang.Double={0}は有効な数値でなければなりません。 +typeMismatch.java.lang.Integer={0}は有効な数値でなければなりません。 +typeMismatch.java.lang.Long={0}は有効な数値でなければなりません。 +typeMismatch.java.lang.Short={0}は有効な数値でなければなりません。 +typeMismatch.java.math.BigDecimal={0}は有効な数値でなければなりません。 +typeMismatch.java.math.BigInteger={0}は有効な数値でなければなりません。 diff --git a/BuildingQuality/sample-code/metrics/grails-app/i18n/messages_nl.properties b/BuildingQuality/sample-code/metrics/grails-app/i18n/messages_nl.properties new file mode 100644 index 0000000..cd5cc94 --- /dev/null +++ b/BuildingQuality/sample-code/metrics/grails-app/i18n/messages_nl.properties @@ -0,0 +1,55 @@ +default.doesnt.match.message=Attribuut [{0}] van entiteit [{1}] met waarde [{2}] komt niet overeen met het vereiste patroon [{3}] +default.invalid.url.message=Attribuut [{0}] van entiteit [{1}] met waarde [{2}] is geen geldige URL +default.invalid.creditCard.message=Attribuut [{0}] van entiteit [{1}] met waarde [{2}] is geen geldig credit card nummer +default.invalid.email.message=Attribuut [{0}] van entiteit [{1}] met waarde [{2}] is geen geldig e-mailadres +default.invalid.range.message=Attribuut [{0}] van entiteit [{1}] met waarde [{2}] valt niet in de geldige waardenreeks van [{3}] tot [{4}] +default.invalid.size.message=Attribuut [{0}] van entiteit [{1}] met waarde [{2}] valt niet in de geldige grootte van [{3}] tot [{4}] +default.invalid.max.message=Attribuut [{0}] van entiteit [{1}] met waarde [{2}] overschrijdt de maximumwaarde [{3}] +default.invalid.min.message=Attribuut [{0}] van entiteit [{1}] met waarde [{2}] is minder dan de minimumwaarde [{3}] +default.invalid.max.size.message=Attribuut [{0}] van entiteit [{1}] met waarde [{2}] overschrijdt de maximumgrootte van [{3}] +default.invalid.min.size.message=Attribuut [{0}] van entiteit [{1}] met waarde [{2}] is minder dan minimumgrootte van [{3}] +default.invalid.validator.message=Attribuut [{0}] van entiteit [{1}] met waarde [{2}] is niet geldig +default.not.inlist.message=Attribuut [{0}] van entiteit [{1}] met waarde [{2}] komt niet voor in de lijst [{3}] +default.blank.message=Attribuut [{0}] van entiteit [{1}] mag niet leeg zijn +default.not.equal.message=Attribuut [{0}] van entiteit [{1}] met waarde [{2}] mag niet gelijk zijn aan [{3}] +default.null.message=Attribuut [{0}] van entiteit [{1}] mag niet leeg zijn +default.not.unique.message=Attribuut [{0}] van entiteit [{1}] met waarde [{2}] moet uniek zijn + +default.paginate.prev=Vorige +default.paginate.next=Volgende +default.boolean.true=Ja +default.boolean.false=Nee +default.date.format=dd-MM-yyyy HH:mm:ss z +default.number.format=0 + +default.created.message={0} {1} ingevoerd +default.updated.message={0} {1} gewijzigd +default.deleted.message={0} {1} verwijderd +default.not.deleted.message={0} {1} kon niet worden verwijderd +default.not.found.message={0} met id {1} kon niet worden gevonden +default.optimistic.locking.failure=Een andere gebruiker heeft deze {0} al gewijzigd + +default.home.label=Home +default.list.label={0} Overzicht +default.add.label=Toevoegen {0} +default.new.label=Invoeren {0} +default.create.label=Invoeren {0} +default.show.label=Details {0} +default.edit.label=Wijzigen {0} + +default.button.create.label=Invoeren +default.button.edit.label=Wijzigen +default.button.update.label=Opslaan +default.button.delete.label=Verwijderen +default.button.delete.confirm.message=Weet je het zeker? + +# Data binding errors. Use "typeMismatch.$className.$propertyName to customize (eg typeMismatch.Book.author) +typeMismatch.java.net.URL=Attribuut {0} is geen geldige URL +typeMismatch.java.net.URI=Attribuut {0} is geen geldige URI +typeMismatch.java.util.Date=Attribuut {0} is geen geldige datum +typeMismatch.java.lang.Double=Attribuut {0} is geen geldig nummer +typeMismatch.java.lang.Integer=Attribuut {0} is geen geldig nummer +typeMismatch.java.lang.Long=Attribuut {0} is geen geldig nummer +typeMismatch.java.lang.Short=Attribuut {0} is geen geldig nummer +typeMismatch.java.math.BigDecimal=Attribuut {0} is geen geldig nummer +typeMismatch.java.math.BigInteger=Attribuut {0} is geen geldig nummer diff --git a/BuildingQuality/sample-code/metrics/grails-app/i18n/messages_pt_BR.properties b/BuildingQuality/sample-code/metrics/grails-app/i18n/messages_pt_BR.properties new file mode 100644 index 0000000..0c368f2 --- /dev/null +++ b/BuildingQuality/sample-code/metrics/grails-app/i18n/messages_pt_BR.properties @@ -0,0 +1,59 @@ +# +# Translated by Lucas Teixeira - lucastex@gmail.com +# + +default.doesnt.match.message=O campo [{0}] da classe [{1}] com o valor [{2}] não atende ao padrão definido [{3}] +default.invalid.url.message=O campo [{0}] da classe [{1}] com o valor [{2}] não é uma URL válida +default.invalid.creditCard.message=O campo [{0}] da classe [{1}] com o valor [{2}] não é um número válido de cartão de crédito +default.invalid.email.message=O campo [{0}] da classe [{1}] com o valor [{2}] não é um endereço de email válido. +default.invalid.range.message=O campo [{0}] da classe [{1}] com o valor [{2}] não está entre a faixa de valores válida de [{3}] até [{4}] +default.invalid.size.message=O campo [{0}] da classe [{1}] com o valor [{2}] não está na faixa de tamanho válida de [{3}] até [{4}] +default.invalid.max.message=O campo [{0}] da classe [{1}] com o valor [{2}] ultrapass o valor máximo [{3}] +default.invalid.min.message=O campo [{0}] da classe [{1}] com o valor [{2}] não atinge o valor mínimo [{3}] +default.invalid.max.size.message=O campo [{0}] da classe [{1}] com o valor [{2}] ultrapassa o tamanho máximo de [{3}] +default.invalid.min.size.message=O campo [{0}] da classe [{1}] com o valor [{2}] não atinge o tamanho mínimo de [{3}] +default.invalid.validator.message=O campo [{0}] da classe [{1}] com o valor [{2}] não passou na validação +default.not.inlist.message=O campo [{0}] da classe [{1}] com o valor [{2}] não é um valor dentre os permitidos na lista [{3}] +default.blank.message=O campo [{0}] da classe [{1}] não pode ficar em branco +default.not.equal.message=O campo [{0}] da classe [{1}] com o valor [{2}] não pode ser igual a [{3}] +default.null.message=O campo [{0}] da classe [{1}] não pode ser vazia +default.not.unique.message=O campo [{0}] da classe [{1}] com o valor [{2}] deve ser único + +default.paginate.prev=Anterior +default.paginate.next=Próximo +default.boolean.true=Sim +default.boolean.false=Não +default.date.format=dd/MM/yyyy HH:mm:ss z +default.number.format=0 + +default.created.message={0} {1} criado +default.updated.message={0} {1} atualizado +default.deleted.message={0} {1} removido +default.not.deleted.message={0} {1} não pode ser removido +default.not.found.message={0} não foi encontrado com id {1} +default.optimistic.locking.failure=Outro usuário atualizou este [{0}] enquanto você tentou salvá-lo + +default.home.label=Principal +default.list.label={0} Listagem +default.add.label=Adicionar {0} +default.new.label=Novo {0} +default.create.label=Criar {0} +default.show.label=Ver {0} +default.edit.label=Editar {0} + +default.button.create.label=Criar +default.button.edit.label=Editar +default.button.update.label=Alterar +default.button.delete.label=Remover +default.button.delete.confirm.message=Tem certeza? + +# Mensagens de erro em atribuição de valores. Use "typeMismatch.$className.$propertyName" para customizar (eg typeMismatch.Book.author) +typeMismatch.java.net.URL=O campo {0} deve ser uma URL válida. +typeMismatch.java.net.URI=O campo {0} deve ser uma URI válida. +typeMismatch.java.util.Date=O campo {0} deve ser uma data válida +typeMismatch.java.lang.Double=O campo {0} deve ser um número válido. +typeMismatch.java.lang.Integer=O campo {0} deve ser um número válido. +typeMismatch.java.lang.Long=O campo {0} deve ser um número válido. +typeMismatch.java.lang.Short=O campo {0} deve ser um número válido. +typeMismatch.java.math.BigDecimal=O campo {0} deve ser um número válido. +typeMismatch.java.math.BigInteger=O campo {0} deve ser um número válido. \ No newline at end of file diff --git a/BuildingQuality/sample-code/metrics/grails-app/i18n/messages_pt_PT.properties b/BuildingQuality/sample-code/metrics/grails-app/i18n/messages_pt_PT.properties new file mode 100644 index 0000000..43a6416 --- /dev/null +++ b/BuildingQuality/sample-code/metrics/grails-app/i18n/messages_pt_PT.properties @@ -0,0 +1,34 @@ +# +# translation by miguel.ping@gmail.com, based on pt_BR translation by Lucas Teixeira - lucastex@gmail.com +# + +default.doesnt.match.message=O campo [{0}] da classe [{1}] com o valor [{2}] não corresponde ao padrão definido [{3}] +default.invalid.url.message=O campo [{0}] da classe [{1}] com o valor [{2}] não é um URL válido +default.invalid.creditCard.message=O campo [{0}] da classe [{1}] com o valor [{2}] não é um número válido de cartão de crédito +default.invalid.email.message=O campo [{0}] da classe [{1}] com o valor [{2}] não é um endereço de email válido. +default.invalid.range.message=O campo [{0}] da classe [{1}] com o valor [{2}] não está dentro dos limites de valores válidos de [{3}] a [{4}] +default.invalid.size.message=O campo [{0}] da classe [{1}] com o valor [{2}] está fora dos limites de tamanho válido de [{3}] a [{4}] +default.invalid.max.message=O campo [{0}] da classe [{1}] com o valor [{2}] ultrapassa o valor máximo [{3}] +default.invalid.min.message=O campo [{0}] da classe [{1}] com o valor [{2}] não atinge o valor mínimo [{3}] +default.invalid.max.size.message=O campo [{0}] da classe [{1}] com o valor [{2}] ultrapassa o tamanho máximo de [{3}] +default.invalid.min.size.message=O campo [{0}] da classe [{1}] com o valor [{2}] não atinge o tamanho mínimo de [{3}] +default.invalid.validator.message=O campo [{0}] da classe [{1}] com o valor [{2}] não passou na validação +default.not.inlist.message=O campo [{0}] da classe [{1}] com o valor [{2}] não se encontra nos valores permitidos da lista [{3}] +default.blank.message=O campo [{0}] da classe [{1}] não pode ser vazio +default.not.equal.message=O campo [{0}] da classe [{1}] com o valor [{2}] não pode ser igual a [{3}] +default.null.message=O campo [{0}] da classe [{1}] não pode ser vazio +default.not.unique.message=O campo [{0}] da classe [{1}] com o valor [{2}] deve ser único + +default.paginate.prev=Anterior +default.paginate.next=Próximo + +# Mensagens de erro em atribuição de valores. Use "typeMismatch.$className.$propertyName" para personalizar(eg typeMismatch.Book.author) +typeMismatch.java.net.URL=O campo {0} deve ser um URL válido. +typeMismatch.java.net.URI=O campo {0} deve ser um URI válido. +typeMismatch.java.util.Date=O campo {0} deve ser uma data válida +typeMismatch.java.lang.Double=O campo {0} deve ser um número válido. +typeMismatch.java.lang.Integer=O campo {0} deve ser um número válido. +typeMismatch.java.lang.Long=O campo {0} deve ser um número valido. +typeMismatch.java.lang.Short=O campo {0} deve ser um número válido. +typeMismatch.java.math.BigDecimal=O campo {0} deve ser um número válido. +typeMismatch.java.math.BigInteger=O campo {0} deve ser um número válido. diff --git a/BuildingQuality/sample-code/metrics/grails-app/i18n/messages_ru.properties b/BuildingQuality/sample-code/metrics/grails-app/i18n/messages_ru.properties new file mode 100644 index 0000000..02239db --- /dev/null +++ b/BuildingQuality/sample-code/metrics/grails-app/i18n/messages_ru.properties @@ -0,0 +1,31 @@ +default.doesnt.match.message=Значение [{2}] поля [{0}] класса [{1}] не соответствует образцу [{3}] +default.invalid.url.message=Значение [{2}] поля [{0}] класса [{1}] не является допустимым URL-адресом +default.invalid.creditCard.message=Значение [{2}] поля [{0}] класса [{1}] не является допустимым номером кредитной карты +default.invalid.email.message=Значение [{2}] поля [{0}] класса [{1}] не является допустимым e-mail адресом +default.invalid.range.message=Значение [{2}] поля [{0}] класса [{1}] не попадает в допустимый интервал от [{3}] до [{4}] +default.invalid.size.message=Размер поля [{0}] класса [{1}] (значение: [{2}]) не попадает в допустимый интервал от [{3}] до [{4}] +default.invalid.max.message=Значение [{2}] поля [{0}] класса [{1}] больше чем максимально допустимое значение [{3}] +default.invalid.min.message=Значение [{2}] поля [{0}] класса [{1}] меньше чем минимально допустимое значение [{3}] +default.invalid.max.size.message=Размер поля [{0}] класса [{1}] (значение: [{2}]) больше чем максимально допустимый размер [{3}] +default.invalid.min.size.message=Размер поля [{0}] класса [{1}] (значение: [{2}]) меньше чем минимально допустимый размер [{3}] +default.invalid.validator.message=Значение [{2}] поля [{0}] класса [{1}] не допустимо +default.not.inlist.message=Значение [{2}] поля [{0}] класса [{1}] не попадает в список допустимых значений [{3}] +default.blank.message=Поле [{0}] класса [{1}] не может быть пустым +default.not.equal.message=Значение [{2}] поля [{0}] класса [{1}] не может быть равно [{3}] +default.null.message=Поле [{0}] класса [{1}] не может иметь значение null +default.not.unique.message=Значение [{2}] поля [{0}] класса [{1}] должно быть уникальным + +default.paginate.prev=Предыдушая страница +default.paginate.next=Следующая страница + +# Ошибки при присвоении данных. Для точной настройки для полей классов используйте +# формат "typeMismatch.$className.$propertyName" (например, typeMismatch.Book.author) +typeMismatch.java.net.URL=Значение поля {0} не является допустимым URL +typeMismatch.java.net.URI=Значение поля {0} не является допустимым URI +typeMismatch.java.util.Date=Значение поля {0} не является допустимой датой +typeMismatch.java.lang.Double=Значение поля {0} не является допустимым числом +typeMismatch.java.lang.Integer=Значение поля {0} не является допустимым числом +typeMismatch.java.lang.Long=Значение поля {0} не является допустимым числом +typeMismatch.java.lang.Short=Значение поля {0} не является допустимым числом +typeMismatch.java.math.BigDecimal=Значение поля {0} не является допустимым числом +typeMismatch.java.math.BigInteger=Значение поля {0} не является допустимым числом diff --git a/BuildingQuality/sample-code/metrics/grails-app/i18n/messages_sv.properties b/BuildingQuality/sample-code/metrics/grails-app/i18n/messages_sv.properties new file mode 100644 index 0000000..61899d7 --- /dev/null +++ b/BuildingQuality/sample-code/metrics/grails-app/i18n/messages_sv.properties @@ -0,0 +1,55 @@ +default.doesnt.match.message=Attributet [{0}] för klassen [{1}] med värde [{2}] matchar inte mot uttrycket [{3}] +default.invalid.url.message=Attributet [{0}] för klassen [{1}] med värde [{2}] är inte en giltig URL +default.invalid.creditCard.message=Attributet [{0}] för klassen [{1}] med värde [{2}] är inte ett giltigt kreditkortsnummer +default.invalid.email.message=Attributet [{0}] för klassen [{1}] med värde [{2}] är inte en giltig e-postadress +default.invalid.range.message=Attributet [{0}] för klassen [{1}] med värde [{2}] är inte inom intervallet [{3}] till [{4}] +default.invalid.size.message=Attributet [{0}] för klassen [{1}] med värde [{2}] har en storlek som inte är inom [{3}] till [{4}] +default.invalid.max.message=Attributet [{0}] för klassen [{1}] med värde [{2}] överskrider maxvärdet [{3}] +default.invalid.min.message=Attributet [{0}] för klassen [{1}] med värde [{2}] är mindre än minimivärdet [{3}] +default.invalid.max.size.message=Attributet [{0}] för klassen [{1}] med värde [{2}] överskrider maxstorleken [{3}] +default.invalid.min.size.message=Attributet [{0}] för klassen [{1}] med värde [{2}] är mindre än minimistorleken [{3}] +default.invalid.validator.message=Attributet [{0}] för klassen [{1}] med värde [{2}] är inte giltigt enligt anpassad regel +default.not.inlist.message=Attributet [{0}] för klassen [{1}] med värde [{2}] är inte giltigt, måste vara ett av [{3}] +default.blank.message=Attributet [{0}] för klassen [{1}] får inte vara tomt +default.not.equal.message=Attributet [{0}] för klassen [{1}] med värde [{2}] får inte vara lika med [{3}] +default.null.message=Attributet [{0}] för klassen [{1}] får inte vara tomt +default.not.unique.message=Attributet [{0}] för klassen [{1}] med värde [{2}] måste vara unikt + +default.paginate.prev=Föregående +default.paginate.next=Nästa +default.boolean.true=Sant +default.boolean.false=Falskt +default.date.format=yyyy-MM-dd HH:mm:ss z +default.number.format=0 + +default.created.message={0} {1} skapades +default.updated.message={0} {1} uppdaterades +default.deleted.message={0} {1} borttagen +default.not.deleted.message={0} {1} kunde inte tas bort +default.not.found.message={0} med id {1} kunde inte hittas +default.optimistic.locking.failure=En annan användare har uppdaterat det här {0} objektet medan du redigerade det + +default.home.label=Hem +default.list.label= {0} - Lista +default.add.label=Lägg till {0} +default.new.label=Skapa {0} +default.create.label=Skapa {0} +default.show.label=Visa {0} +default.edit.label=Ändra {0} + +default.button.create.label=Skapa +default.button.edit.label=Ändra +default.button.update.label=Uppdatera +default.button.delete.label=Ta bort +default.button.delete.confirm.message=Är du säker? + +# Data binding errors. Use "typeMismatch.$className.$propertyName to customize (eg typeMismatch.Book.author) +typeMismatch.java.net.URL=Värdet för {0} måste vara en giltig URL +typeMismatch.java.net.URI=Värdet för {0} måste vara en giltig URI +typeMismatch.java.util.Date=Värdet {0} måste vara ett giltigt datum +typeMismatch.java.lang.Double=Värdet {0} måste vara ett giltigt nummer +typeMismatch.java.lang.Integer=Värdet {0} måste vara ett giltigt heltal +typeMismatch.java.lang.Long=Värdet {0} måste vara ett giltigt heltal +typeMismatch.java.lang.Short=Värdet {0} måste vara ett giltigt heltal +typeMismatch.java.math.BigDecimal=Värdet {0} måste vara ett giltigt nummer +typeMismatch.java.math.BigInteger=Värdet {0} måste vara ett giltigt heltal \ No newline at end of file diff --git a/BuildingQuality/sample-code/metrics/grails-app/i18n/messages_th.properties b/BuildingQuality/sample-code/metrics/grails-app/i18n/messages_th.properties new file mode 100644 index 0000000..4f4076d --- /dev/null +++ b/BuildingQuality/sample-code/metrics/grails-app/i18n/messages_th.properties @@ -0,0 +1,55 @@ +default.doesnt.match.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] ไม่ถูกต้องตามรูปแบบที่กำหนดไว้ใน [{3}] +default.invalid.url.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] ไม่ถูกต้องตามรูปแบบ URL +default.invalid.creditCard.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] ไม่ถูกต้องตามรูปแบบหมายเลขบัตรเครดิต +default.invalid.email.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] ไม่ถูกต้องตามรูปแบบอีเมล์ +default.invalid.range.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] ไม่ได้มีค่าที่ถูกต้องในช่วงจาก [{3}] ถึง [{4}] +default.invalid.size.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] ไม่ได้มีขนาดที่ถูกต้องในช่วงจาก [{3}] ถึง [{4}] +default.invalid.max.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] มีค่าเกิดกว่าค่ามากสุด [{3}] +default.invalid.min.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] มีค่าน้อยกว่าค่าต่ำสุด [{3}] +default.invalid.max.size.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] มีขนาดเกินกว่าขนาดมากสุดของ [{3}] +default.invalid.min.size.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] มีขนาดต่ำกว่าขนาดต่ำสุดของ [{3}] +default.invalid.validator.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] ไม่ผ่านการทวนสอบค่าที่ตั้งขึ้น +default.not.inlist.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] ไม่ได้อยู่ในรายการต่อไปนี้ [{3}] +default.blank.message=คุณสมบัติ [{0}] ของคลาส [{1}] ไม่สามารถเป็นค่าว่างได้ +default.not.equal.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] ไม่สามารถเท่ากับ [{3}] ได้ +default.null.message=คุณสมบัติ [{0}] ของคลาส [{1}] ไม่สามารถเป็น null ได้ +default.not.unique.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] จะต้องไม่ซ้ำ (unique) + +default.paginate.prev=ก่อนหน้า +default.paginate.next=ถัดไป +default.boolean.true=จริง +default.boolean.false=เท็จ +default.date.format=dd-MM-yyyy HH:mm:ss z +default.number.format=0 + +default.created.message=สร้าง {0} {1} เรียบร้อยแล้ว +default.updated.message=ปรับปรุง {0} {1} เรียบร้อยแล้ว +default.deleted.message=ลบ {0} {1} เรียบร้อยแล้ว +default.not.deleted.message=ไม่สามารถลบ {0} {1} +default.not.found.message=ไม่พบ {0} ด้วย id {1} นี้ +default.optimistic.locking.failure=มีผู้ใช้ท่านอื่นปรับปรุง {0} ขณะที่คุณกำลังแก้ไขข้อมูลอยู่ + +default.home.label=หน้าแรก +default.list.label=รายการ {0} +default.add.label=เพิ่ม {0} +default.new.label=สร้าง {0} ใหม่ +default.create.label=สร้าง {0} +default.show.label=แสดง {0} +default.edit.label=แก้ไข {0} + +default.button.create.label=สร้าง +default.button.edit.label=แก้ไข +default.button.update.label=ปรับปรุง +default.button.delete.label=ลบ +default.button.delete.confirm.message=คุณแน่ใจหรือไม่ ? + +# Data binding errors. Use "typeMismatch.$className.$propertyName to customize (eg typeMismatch.Book.author) +typeMismatch.java.net.URL=คุณสมบัติ '{0}' จะต้องเป็นค่า URL ที่ถูกต้อง +typeMismatch.java.net.URI=คุณสมบัติ '{0}' จะต้องเป็นค่า URI ที่ถูกต้อง +typeMismatch.java.util.Date=คุณสมบัติ '{0}' จะต้องมีค่าเป็นวันที่ +typeMismatch.java.lang.Double=คุณสมบัติ '{0}' จะต้องมีค่าเป็นจำนวนประเภท Double +typeMismatch.java.lang.Integer=คุณสมบัติ '{0}' จะต้องมีค่าเป็นจำนวนประเภท Integer +typeMismatch.java.lang.Long=คุณสมบัติ '{0}' จะต้องมีค่าเป็นจำนวนประเภท Long +typeMismatch.java.lang.Short=คุณสมบัติ '{0}' จะต้องมีค่าเป็นจำนวนประเภท Short +typeMismatch.java.math.BigDecimal=คุณสมบัติ '{0}' จะต้องมีค่าเป็นจำนวนประเภท BigDecimal +typeMismatch.java.math.BigInteger=คุณสมบัติ '{0}' จะต้องมีค่าเป็นจำนวนประเภท BigInteger diff --git a/BuildingQuality/sample-code/metrics/grails-app/i18n/messages_zh_CN.properties b/BuildingQuality/sample-code/metrics/grails-app/i18n/messages_zh_CN.properties new file mode 100644 index 0000000..782580b --- /dev/null +++ b/BuildingQuality/sample-code/metrics/grails-app/i18n/messages_zh_CN.properties @@ -0,0 +1,18 @@ +default.blank.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u4E0D\u80FD\u4E3A\u7A7A +default.doesnt.match.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u4E0E\u5B9A\u4E49\u7684\u6A21\u5F0F [{3}]\u4E0D\u5339\u914D +default.invalid.creditCard.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u4E0D\u662F\u4E00\u4E2A\u6709\u6548\u7684\u4FE1\u7528\u5361\u53F7 +default.invalid.email.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u4E0D\u662F\u4E00\u4E2A\u5408\u6CD5\u7684\u7535\u5B50\u90AE\u4EF6\u5730\u5740 +default.invalid.max.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u6BD4\u6700\u5927\u503C [{3}]\u8FD8\u5927 +default.invalid.max.size.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u7684\u5927\u5C0F\u6BD4\u6700\u5927\u503C [{3}]\u8FD8\u5927 +default.invalid.min.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u6BD4\u6700\u5C0F\u503C [{3}]\u8FD8\u5C0F +default.invalid.min.size.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u7684\u5927\u5C0F\u6BD4\u6700\u5C0F\u503C [{3}]\u8FD8\u5C0F +default.invalid.range.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u4E0D\u5728\u5408\u6CD5\u7684\u8303\u56F4\u5185( [{3}] \uFF5E [{4}] ) +default.invalid.size.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u7684\u5927\u5C0F\u4E0D\u5728\u5408\u6CD5\u7684\u8303\u56F4\u5185( [{3}] \uFF5E [{4}] ) +default.invalid.url.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u4E0D\u662F\u4E00\u4E2A\u5408\u6CD5\u7684URL +default.invalid.validator.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u672A\u80FD\u901A\u8FC7\u81EA\u5B9A\u4E49\u7684\u9A8C\u8BC1 +default.not.equal.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u4E0E[{3}]\u4E0D\u76F8\u7B49 +default.not.inlist.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u4E0D\u5728\u5217\u8868\u7684\u53D6\u503C\u8303\u56F4\u5185 +default.not.unique.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u5FC5\u987B\u662F\u552F\u4E00\u7684 +default.null.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u4E0D\u80FD\u4E3Anull +default.paginate.next=\u4E0B\u9875 +default.paginate.prev=\u4E0A\u9875 diff --git a/BuildingQuality/sample-code/metrics/grails-app/views/book/_form.gsp b/BuildingQuality/sample-code/metrics/grails-app/views/book/_form.gsp new file mode 100644 index 0000000..56bd339 --- /dev/null +++ b/BuildingQuality/sample-code/metrics/grails-app/views/book/_form.gsp @@ -0,0 +1,4 @@ +<%@ page import="metrics.Book" %> + + + diff --git a/BuildingQuality/sample-code/metrics/grails-app/views/book/create.gsp b/BuildingQuality/sample-code/metrics/grails-app/views/book/create.gsp new file mode 100644 index 0000000..6eec28f --- /dev/null +++ b/BuildingQuality/sample-code/metrics/grails-app/views/book/create.gsp @@ -0,0 +1,39 @@ +<%@ page import="metrics.Book" %> + + + + + + <g:message code="default.create.label" args="[entityName]" /> + + + + +
+

+ +
${flash.message}
+
+ + + + +
+ +
+
+ +
+
+
+ + diff --git a/BuildingQuality/sample-code/metrics/grails-app/views/book/edit.gsp b/BuildingQuality/sample-code/metrics/grails-app/views/book/edit.gsp new file mode 100644 index 0000000..7b1541c --- /dev/null +++ b/BuildingQuality/sample-code/metrics/grails-app/views/book/edit.gsp @@ -0,0 +1,43 @@ +<%@ page import="metrics.Book" %> + + + + + + <g:message code="default.edit.label" args="[entityName]" /> + + + + +
+

+ +
${flash.message}
+
+ + + + + + +
+ +
+
+ + +
+
+
+ + diff --git a/BuildingQuality/sample-code/metrics/grails-app/views/book/list.gsp b/BuildingQuality/sample-code/metrics/grails-app/views/book/list.gsp new file mode 100644 index 0000000..fb751d6 --- /dev/null +++ b/BuildingQuality/sample-code/metrics/grails-app/views/book/list.gsp @@ -0,0 +1,42 @@ + +<%@ page import="metrics.Book" %> + + + + + + <g:message code="default.list.label" args="[entityName]" /> + + + + +
+

+ +
${flash.message}
+
+ + + + + + + + + + + + + +
+ +
+ + diff --git a/BuildingQuality/sample-code/metrics/grails-app/views/book/show.gsp b/BuildingQuality/sample-code/metrics/grails-app/views/book/show.gsp new file mode 100644 index 0000000..84aaf39 --- /dev/null +++ b/BuildingQuality/sample-code/metrics/grails-app/views/book/show.gsp @@ -0,0 +1,36 @@ + +<%@ page import="metrics.Book" %> + + + + + + <g:message code="default.show.label" args="[entityName]" /> + + + + +
+

+ +
${flash.message}
+
+
    + +
+ +
+ + + +
+
+
+ + diff --git a/BuildingQuality/sample-code/metrics/grails-app/views/error.gsp b/BuildingQuality/sample-code/metrics/grails-app/views/error.gsp new file mode 100644 index 0000000..64a0b08 --- /dev/null +++ b/BuildingQuality/sample-code/metrics/grails-app/views/error.gsp @@ -0,0 +1,11 @@ + + + + Grails Runtime Exception + + + + + + + \ No newline at end of file diff --git a/BuildingQuality/sample-code/metrics/grails-app/views/index.gsp b/BuildingQuality/sample-code/metrics/grails-app/views/index.gsp new file mode 100644 index 0000000..11e2838 --- /dev/null +++ b/BuildingQuality/sample-code/metrics/grails-app/views/index.gsp @@ -0,0 +1,122 @@ + + + + + Welcome to Grails + + + + + +
+

Welcome to Grails

+

Congratulations, you have successfully started your first Grails application! At the moment + this is the default page, feel free to modify it to either redirect to a controller or display whatever + content you may choose. Below is a list of controllers that are currently deployed in this application, + click on each to execute its default action:

+ + +
+ + diff --git a/BuildingQuality/sample-code/metrics/grails-app/views/layouts/main.gsp b/BuildingQuality/sample-code/metrics/grails-app/views/layouts/main.gsp new file mode 100644 index 0000000..cebc5b1 --- /dev/null +++ b/BuildingQuality/sample-code/metrics/grails-app/views/layouts/main.gsp @@ -0,0 +1,28 @@ + + + + + + + + + + <g:layoutTitle default="Grails"/> + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/BuildingQuality/sample-code/metrics/test/unit/metrics/BookControllerTests.groovy b/BuildingQuality/sample-code/metrics/test/unit/metrics/BookControllerTests.groovy new file mode 100644 index 0000000..0b5c8f1 --- /dev/null +++ b/BuildingQuality/sample-code/metrics/test/unit/metrics/BookControllerTests.groovy @@ -0,0 +1,159 @@ +package metrics + + + +import org.junit.* +import grails.test.mixin.* + +@TestFor(BookController) +@Mock(Book) +class BookControllerTests { + + + def populateValidParams(params) { + assert params != null + // TODO: Populate valid properties like... + //params["name"] = 'someValidName' + } + + void testIndex() { + controller.index() + assert "/book/list" == response.redirectedUrl + } + + void testList() { + + def model = controller.list() + + assert model.bookInstanceList.size() == 0 + assert model.bookInstanceTotal == 0 + } + + void testCreate() { + def model = controller.create() + + assert model.bookInstance != null + } + + void testSave() { + controller.save() + + assert model.bookInstance != null + assert view == '/book/create' + + response.reset() + + populateValidParams(params) + controller.save() + + assert response.redirectedUrl == '/book/show/1' + assert controller.flash.message != null + assert Book.count() == 1 + } + + void testShow() { + controller.show() + + assert flash.message != null + assert response.redirectedUrl == '/book/list' + + + populateValidParams(params) + def book = new Book(params) + + assert book.save() != null + + params.id = book.id + + def model = controller.show() + + assert model.bookInstance == book + } + + void testEdit() { + controller.edit() + + assert flash.message != null + assert response.redirectedUrl == '/book/list' + + + populateValidParams(params) + def book = new Book(params) + + assert book.save() != null + + params.id = book.id + + def model = controller.edit() + + assert model.bookInstance == book + } + + void testUpdate() { + controller.update() + + assert flash.message != null + assert response.redirectedUrl == '/book/list' + + response.reset() + + + populateValidParams(params) + def book = new Book(params) + + assert book.save() != null + + // test invalid parameters in update + params.id = book.id + //TODO: add invalid values to params object + + controller.update() + + assert view == "/book/edit" + assert model.bookInstance != null + + book.clearErrors() + + populateValidParams(params) + controller.update() + + assert response.redirectedUrl == "/book/show/$book.id" + assert flash.message != null + + //test outdated version number + response.reset() + book.clearErrors() + + populateValidParams(params) + params.id = book.id + params.version = -1 + controller.update() + + assert view == "/book/edit" + assert model.bookInstance != null + assert model.bookInstance.errors.getFieldError('version') + assert flash.message != null + } + + void testDelete() { + controller.delete() + assert flash.message != null + assert response.redirectedUrl == '/book/list' + + response.reset() + + populateValidParams(params) + def book = new Book(params) + + assert book.save() != null + assert Book.count() == 1 + + params.id = book.id + + controller.delete() + + assert Book.count() == 0 + assert Book.get(book.id) == null + assert response.redirectedUrl == '/book/list' + } +} diff --git a/BuildingQuality/sample-code/metrics/test/unit/metrics/BookTests.groovy b/BuildingQuality/sample-code/metrics/test/unit/metrics/BookTests.groovy new file mode 100644 index 0000000..69c2dc9 --- /dev/null +++ b/BuildingQuality/sample-code/metrics/test/unit/metrics/BookTests.groovy @@ -0,0 +1,17 @@ +package metrics + + + +import grails.test.mixin.* +import org.junit.* + +/** + * See the API for {@link grails.test.mixin.domain.DomainClassUnitTestMixin} for usage instructions + */ +@TestFor(Book) +class BookTests { + + void testSomething() { + fail "Implement me" + } +} diff --git a/BuildingQuality/sample-code/metrics/web-app/WEB-INF/applicationContext.xml b/BuildingQuality/sample-code/metrics/web-app/WEB-INF/applicationContext.xml new file mode 100644 index 0000000..69fbef3 --- /dev/null +++ b/BuildingQuality/sample-code/metrics/web-app/WEB-INF/applicationContext.xml @@ -0,0 +1,33 @@ + + + + + Grails application factory bean + + + + + + A bean that manages Grails plugins + + + + + + + + + + + + + + + + utf-8 + + + \ No newline at end of file diff --git a/BuildingQuality/sample-code/metrics/web-app/WEB-INF/sitemesh.xml b/BuildingQuality/sample-code/metrics/web-app/WEB-INF/sitemesh.xml new file mode 100644 index 0000000..72399ce --- /dev/null +++ b/BuildingQuality/sample-code/metrics/web-app/WEB-INF/sitemesh.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/BuildingQuality/sample-code/metrics/web-app/WEB-INF/tld/c.tld b/BuildingQuality/sample-code/metrics/web-app/WEB-INF/tld/c.tld new file mode 100644 index 0000000..5e18236 --- /dev/null +++ b/BuildingQuality/sample-code/metrics/web-app/WEB-INF/tld/c.tld @@ -0,0 +1,572 @@ + + + + + JSTL 1.2 core library + JSTL core + 1.2 + c + http://java.sun.com/jsp/jstl/core + + + + Provides core validation features for JSTL tags. + + + org.apache.taglibs.standard.tlv.JstlCoreTLV + + + + + + Catches any Throwable that occurs in its body and optionally + exposes it. + + catch + org.apache.taglibs.standard.tag.common.core.CatchTag + JSP + + +Name of the exported scoped variable for the +exception thrown from a nested action. The type of the +scoped variable is the type of the exception thrown. + + var + false + false + + + + + + Simple conditional tag that establishes a context for + mutually exclusive conditional operations, marked by + <when> and <otherwise> + + choose + org.apache.taglibs.standard.tag.common.core.ChooseTag + JSP + + + + + Simple conditional tag, which evalutes its body if the + supplied condition is true and optionally exposes a Boolean + scripting variable representing the evaluation of this condition + + if + org.apache.taglibs.standard.tag.rt.core.IfTag + JSP + + +The test condition that determines whether or +not the body content should be processed. + + test + true + true + boolean + + + +Name of the exported scoped variable for the +resulting value of the test condition. The type +of the scoped variable is Boolean. + + var + false + false + + + +Scope for var. + + scope + false + false + + + + + + Retrieves an absolute or relative URL and exposes its contents + to either the page, a String in 'var', or a Reader in 'varReader'. + + import + org.apache.taglibs.standard.tag.rt.core.ImportTag + org.apache.taglibs.standard.tei.ImportTEI + JSP + + +The URL of the resource to import. + + url + true + true + + + +Name of the exported scoped variable for the +resource's content. The type of the scoped +variable is String. + + var + false + false + + + +Scope for var. + + scope + false + false + + + +Name of the exported scoped variable for the +resource's content. The type of the scoped +variable is Reader. + + varReader + false + false + + + +Name of the context when accessing a relative +URL resource that belongs to a foreign +context. + + context + false + true + + + +Character encoding of the content at the input +resource. + + charEncoding + false + true + + + + + + The basic iteration tag, accepting many different + collection types and supporting subsetting and other + functionality + + forEach + org.apache.taglibs.standard.tag.rt.core.ForEachTag + org.apache.taglibs.standard.tei.ForEachTEI + JSP + + +Collection of items to iterate over. + + items + false + true + java.lang.Object + + java.lang.Object + + + + +If items specified: +Iteration begins at the item located at the +specified index. First item of the collection has +index 0. +If items not specified: +Iteration begins with index set at the value +specified. + + begin + false + true + int + + + +If items specified: +Iteration ends at the item located at the +specified index (inclusive). +If items not specified: +Iteration ends when index reaches the value +specified. + + end + false + true + int + + + +Iteration will only process every step items of +the collection, starting with the first one. + + step + false + true + int + + + +Name of the exported scoped variable for the +current item of the iteration. This scoped +variable has nested visibility. Its type depends +on the object of the underlying collection. + + var + false + false + + + +Name of the exported scoped variable for the +status of the iteration. Object exported is of type +javax.servlet.jsp.jstl.core.LoopTagStatus. This scoped variable has nested +visibility. + + varStatus + false + false + + + + + + Iterates over tokens, separated by the supplied delimeters + + forTokens + org.apache.taglibs.standard.tag.rt.core.ForTokensTag + JSP + + +String of tokens to iterate over. + + items + true + true + java.lang.String + + java.lang.String + + + + +The set of delimiters (the characters that +separate the tokens in the string). + + delims + true + true + java.lang.String + + + +Iteration begins at the token located at the +specified index. First token has index 0. + + begin + false + true + int + + + +Iteration ends at the token located at the +specified index (inclusive). + + end + false + true + int + + + +Iteration will only process every step tokens +of the string, starting with the first one. + + step + false + true + int + + + +Name of the exported scoped variable for the +current item of the iteration. This scoped +variable has nested visibility. + + var + false + false + + + +Name of the exported scoped variable for the +status of the iteration. Object exported is of +type +javax.servlet.jsp.jstl.core.LoopTag +Status. This scoped variable has nested +visibility. + + varStatus + false + false + + + + + + Like <%= ... >, but for expressions. + + out + org.apache.taglibs.standard.tag.rt.core.OutTag + JSP + + +Expression to be evaluated. + + value + true + true + + + +Default value if the resulting value is null. + + default + false + true + + + +Determines whether characters <,>,&,'," in the +resulting string should be converted to their +corresponding character entity codes. Default value is +true. + + escapeXml + false + true + + + + + + + Subtag of <choose> that follows <when> tags + and runs only if all of the prior conditions evaluated to + 'false' + + otherwise + org.apache.taglibs.standard.tag.common.core.OtherwiseTag + JSP + + + + + Adds a parameter to a containing 'import' tag's URL. + + param + org.apache.taglibs.standard.tag.rt.core.ParamTag + JSP + + +Name of the query string parameter. + + name + true + true + + + +Value of the parameter. + + value + false + true + + + + + + Redirects to a new URL. + + redirect + org.apache.taglibs.standard.tag.rt.core.RedirectTag + JSP + + +The URL of the resource to redirect to. + + url + false + true + + + +Name of the context when redirecting to a relative URL +resource that belongs to a foreign context. + + context + false + true + + + + + + Removes a scoped variable (from a particular scope, if specified). + + remove + org.apache.taglibs.standard.tag.common.core.RemoveTag + empty + + +Name of the scoped variable to be removed. + + var + true + false + + + +Scope for var. + + scope + false + false + + + + + + Sets the result of an expression evaluation in a 'scope' + + set + org.apache.taglibs.standard.tag.rt.core.SetTag + JSP + + +Name of the exported scoped variable to hold the value +specified in the action. The type of the scoped variable is +whatever type the value expression evaluates to. + + var + false + false + + + +Expression to be evaluated. + + value + false + true + + java.lang.Object + + + + +Target object whose property will be set. Must evaluate to +a JavaBeans object with setter property property, or to a +java.util.Map object. + + target + false + true + + + +Name of the property to be set in the target object. + + property + false + true + + + +Scope for var. + + scope + false + false + + + + + + Creates a URL with optional query parameters. + + url + org.apache.taglibs.standard.tag.rt.core.UrlTag + JSP + + +Name of the exported scoped variable for the +processed url. The type of the scoped variable is +String. + + var + false + false + + + +Scope for var. + + scope + false + false + + + +URL to be processed. + + value + false + true + + + +Name of the context when specifying a relative URL +resource that belongs to a foreign context. + + context + false + true + + + + + + Subtag of <choose> that includes its body if its + condition evalutes to 'true' + + when + org.apache.taglibs.standard.tag.rt.core.WhenTag + JSP + + +The test condition that determines whether or not the +body content should be processed. + + test + true + true + boolean + + + + diff --git a/BuildingQuality/sample-code/metrics/web-app/WEB-INF/tld/fmt.tld b/BuildingQuality/sample-code/metrics/web-app/WEB-INF/tld/fmt.tld new file mode 100644 index 0000000..2ae4776 --- /dev/null +++ b/BuildingQuality/sample-code/metrics/web-app/WEB-INF/tld/fmt.tld @@ -0,0 +1,671 @@ + + + + + JSTL 1.2 i18n-capable formatting library + JSTL fmt + 1.2 + fmt + http://java.sun.com/jsp/jstl/fmt + + + + Provides core validation features for JSTL tags. + + + org.apache.taglibs.standard.tlv.JstlFmtTLV + + + + + + Sets the request character encoding + + requestEncoding + org.apache.taglibs.standard.tag.rt.fmt.RequestEncodingTag + empty + + +Name of character encoding to be applied when +decoding request parameters. + + value + false + true + + + + + + Stores the given locale in the locale configuration variable + + setLocale + org.apache.taglibs.standard.tag.rt.fmt.SetLocaleTag + empty + + +A String value is interpreted as the +printable representation of a locale, which +must contain a two-letter (lower-case) +language code (as defined by ISO-639), +and may contain a two-letter (upper-case) +country code (as defined by ISO-3166). +Language and country codes must be +separated by hyphen (-) or underscore +(_). + + value + true + true + + + +Vendor- or browser-specific variant. +See the java.util.Locale javadocs for +more information on variants. + + variant + false + true + + + +Scope of the locale configuration variable. + + scope + false + false + + + + + + Specifies the time zone for any time formatting or parsing actions + nested in its body + + timeZone + org.apache.taglibs.standard.tag.rt.fmt.TimeZoneTag + JSP + + +The time zone. A String value is interpreted as +a time zone ID. This may be one of the time zone +IDs supported by the Java platform (such as +"America/Los_Angeles") or a custom time zone +ID (such as "GMT-8"). See +java.util.TimeZone for more information on +supported time zone formats. + + value + true + true + + + + + + Stores the given time zone in the time zone configuration variable + + setTimeZone + org.apache.taglibs.standard.tag.rt.fmt.SetTimeZoneTag + empty + + +The time zone. A String value is interpreted as +a time zone ID. This may be one of the time zone +IDs supported by the Java platform (such as +"America/Los_Angeles") or a custom time zone +ID (such as "GMT-8"). See java.util.TimeZone for +more information on supported time zone +formats. + + value + true + true + + + +Name of the exported scoped variable which +stores the time zone of type +java.util.TimeZone. + + var + false + false + + + +Scope of var or the time zone configuration +variable. + + scope + false + false + + + + + + Loads a resource bundle to be used by its tag body + + bundle + org.apache.taglibs.standard.tag.rt.fmt.BundleTag + JSP + + +Resource bundle base name. This is the bundle's +fully-qualified resource name, which has the same +form as a fully-qualified class name, that is, it uses +"." as the package component separator and does not +have any file type (such as ".class" or ".properties") +suffix. + + basename + true + true + + + +Prefix to be prepended to the value of the message +key of any nested <fmt:message> action. + + prefix + false + true + + + + + + Loads a resource bundle and stores it in the named scoped variable or + the bundle configuration variable + + setBundle + org.apache.taglibs.standard.tag.rt.fmt.SetBundleTag + empty + + +Resource bundle base name. This is the bundle's +fully-qualified resource name, which has the same +form as a fully-qualified class name, that is, it uses +"." as the package component separator and does not +have any file type (such as ".class" or ".properties") +suffix. + + basename + true + true + + + +Name of the exported scoped variable which stores +the i18n localization context of type +javax.servlet.jsp.jstl.fmt.LocalizationC +ontext. + + var + false + false + + + +Scope of var or the localization context +configuration variable. + + scope + false + false + + + + + + Maps key to localized message and performs parametric replacement + + message + org.apache.taglibs.standard.tag.rt.fmt.MessageTag + JSP + + +Message key to be looked up. + + key + false + true + + + +Localization context in whose resource +bundle the message key is looked up. + + bundle + false + true + + + +Name of the exported scoped variable +which stores the localized message. + + var + false + false + + + +Scope of var. + + scope + false + false + + + + + + Supplies an argument for parametric replacement to a containing + <message> tag + + param + org.apache.taglibs.standard.tag.rt.fmt.ParamTag + JSP + + +Argument used for parametric replacement. + + value + false + true + + + + + + Formats a numeric value as a number, currency, or percentage + + formatNumber + org.apache.taglibs.standard.tag.rt.fmt.FormatNumberTag + JSP + + +Numeric value to be formatted. + + value + false + true + + + +Specifies whether the value is to be +formatted as number, currency, or +percentage. + + type + false + true + + + +Custom formatting pattern. + + pattern + false + true + + + +ISO 4217 currency code. Applied only +when formatting currencies (i.e. if type is +equal to "currency"); ignored otherwise. + + currencyCode + false + true + + + +Currency symbol. Applied only when +formatting currencies (i.e. if type is equal +to "currency"); ignored otherwise. + + currencySymbol + false + true + + + +Specifies whether the formatted output +will contain any grouping separators. + + groupingUsed + false + true + + + +Maximum number of digits in the integer +portion of the formatted output. + + maxIntegerDigits + false + true + + + +Minimum number of digits in the integer +portion of the formatted output. + + minIntegerDigits + false + true + + + +Maximum number of digits in the +fractional portion of the formatted output. + + maxFractionDigits + false + true + + + +Minimum number of digits in the +fractional portion of the formatted output. + + minFractionDigits + false + true + + + +Name of the exported scoped variable +which stores the formatted result as a +String. + + var + false + false + + + +Scope of var. + + scope + false + false + + + + + + Parses the string representation of a number, currency, or percentage + + parseNumber + org.apache.taglibs.standard.tag.rt.fmt.ParseNumberTag + JSP + + +String to be parsed. + + value + false + true + + + +Specifies whether the string in the value +attribute should be parsed as a number, +currency, or percentage. + + type + false + true + + + +Custom formatting pattern that determines +how the string in the value attribute is to be +parsed. + + pattern + false + true + + + +Locale whose default formatting pattern (for +numbers, currencies, or percentages, +respectively) is to be used during the parse +operation, or to which the pattern specified +via the pattern attribute (if present) is +applied. + + parseLocale + false + true + + + +Specifies whether just the integer portion of +the given value should be parsed. + + integerOnly + false + true + + + +Name of the exported scoped variable which +stores the parsed result (of type +java.lang.Number). + + var + false + false + + + +Scope of var. + + scope + false + false + + + + + + Formats a date and/or time using the supplied styles and pattern + + formatDate + org.apache.taglibs.standard.tag.rt.fmt.FormatDateTag + empty + + +Date and/or time to be formatted. + + value + true + true + + + +Specifies whether the time, the date, or both +the time and date components of the given +date are to be formatted. + + type + false + true + + + +Predefined formatting style for dates. Follows +the semantics defined in class +java.text.DateFormat. Applied only +when formatting a date or both a date and +time (i.e. if type is missing or is equal to +"date" or "both"); ignored otherwise. + + dateStyle + false + true + + + +Predefined formatting style for times. Follows +the semantics defined in class +java.text.DateFormat. Applied only +when formatting a time or both a date and +time (i.e. if type is equal to "time" or "both"); +ignored otherwise. + + timeStyle + false + true + + + +Custom formatting style for dates and times. + + pattern + false + true + + + +Time zone in which to represent the formatted +time. + + timeZone + false + true + + + +Name of the exported scoped variable which +stores the formatted result as a String. + + var + false + false + + + +Scope of var. + + scope + false + false + + + + + + Parses the string representation of a date and/or time + + parseDate + org.apache.taglibs.standard.tag.rt.fmt.ParseDateTag + JSP + + +Date string to be parsed. + + value + false + true + + + +Specifies whether the date string in the +value attribute is supposed to contain a +time, a date, or both. + + type + false + true + + + +Predefined formatting style for days +which determines how the date +component of the date string is to be +parsed. Applied only when formatting a +date or both a date and time (i.e. if type +is missing or is equal to "date" or "both"); +ignored otherwise. + + dateStyle + false + true + + + +Predefined formatting styles for times +which determines how the time +component in the date string is to be +parsed. Applied only when formatting a +time or both a date and time (i.e. if type +is equal to "time" or "both"); ignored +otherwise. + + timeStyle + false + true + + + +Custom formatting pattern which +determines how the date string is to be +parsed. + + pattern + false + true + + + +Time zone in which to interpret any time +information in the date string. + + timeZone + false + true + + + +Locale whose predefined formatting styles +for dates and times are to be used during +the parse operation, or to which the +pattern specified via the pattern +attribute (if present) is applied. + + parseLocale + false + true + + + +Name of the exported scoped variable in +which the parsing result (of type +java.util.Date) is stored. + + var + false + false + + + +Scope of var. + + scope + false + false + + + + diff --git a/BuildingQuality/sample-code/metrics/web-app/WEB-INF/tld/grails.tld b/BuildingQuality/sample-code/metrics/web-app/WEB-INF/tld/grails.tld new file mode 100644 index 0000000..9bd036b --- /dev/null +++ b/BuildingQuality/sample-code/metrics/web-app/WEB-INF/tld/grails.tld @@ -0,0 +1,550 @@ + + + The Grails custom tag library + 0.2 + grails + http://grails.codehaus.org/tags + + + link + org.codehaus.groovy.grails.web.taglib.jsp.JspLinkTag + JSP + + action + false + true + + + controller + false + true + + + id + false + true + + + url + false + true + + + params + false + true + + true + + + form + org.codehaus.groovy.grails.web.taglib.jsp.JspFormTag + JSP + + action + false + true + + + controller + false + true + + + id + false + true + + + url + false + true + + + method + true + true + + true + + + select + org.codehaus.groovy.grails.web.taglib.jsp.JspSelectTag + JSP + + name + true + true + + + value + false + true + + + optionKey + false + true + + + optionValue + false + true + + true + + + datePicker + org.codehaus.groovy.grails.web.taglib.jsp.JspDatePickerTag + empty + + name + true + true + + + value + false + true + + + precision + false + true + + false + + + currencySelect + org.codehaus.groovy.grails.web.taglib.jsp.JspCurrencySelectTag + empty + + name + true + true + + + value + false + true + + true + + + localeSelect + org.codehaus.groovy.grails.web.taglib.jsp.JspLocaleSelectTag + empty + + name + true + true + + + value + false + true + + true + + + timeZoneSelect + org.codehaus.groovy.grails.web.taglib.jsp.JspTimeZoneSelectTag + empty + + name + true + true + + + value + false + true + + true + + + checkBox + org.codehaus.groovy.grails.web.taglib.jsp.JspCheckboxTag + empty + + name + true + true + + + value + true + true + + true + + + hasErrors + org.codehaus.groovy.grails.web.taglib.jsp.JspHasErrorsTag + JSP + + model + false + true + + + bean + false + true + + + field + false + true + + false + + + eachError + org.codehaus.groovy.grails.web.taglib.jsp.JspEachErrorTag + JSP + + model + false + true + + + bean + false + true + + + field + false + true + + false + + + renderErrors + org.codehaus.groovy.grails.web.taglib.jsp.JspEachErrorTag + JSP + + model + false + true + + + bean + false + true + + + field + false + true + + + as + true + true + + false + + + message + org.codehaus.groovy.grails.web.taglib.jsp.JspMessageTag + JSP + + code + false + true + + + error + false + true + + + default + false + true + + false + + + remoteFunction + org.codehaus.groovy.grails.web.taglib.jsp.JspRemoteFunctionTag + empty + + before + false + true + + + after + false + true + + + action + false + true + + + controller + false + true + + + id + false + true + + + url + false + true + + + params + false + true + + + asynchronous + false + true + + + method + false + true + + + update + false + true + + + onSuccess + false + true + + + onFailure + false + true + + + onComplete + false + true + + + onLoading + false + true + + + onLoaded + false + true + + + onInteractive + false + true + + true + + + remoteLink + org.codehaus.groovy.grails.web.taglib.jsp.JspRemoteLinkTag + JSP + + before + false + true + + + after + false + true + + + action + false + true + + + controller + false + true + + + id + false + true + + + url + false + true + + + params + false + true + + + asynchronous + false + true + + + method + false + true + + + update + false + true + + + onSuccess + false + true + + + onFailure + false + true + + + onComplete + false + true + + + onLoading + false + true + + + onLoaded + false + true + + + onInteractive + false + true + + true + + + formRemote + org.codehaus.groovy.grails.web.taglib.jsp.JspFormRemoteTag + JSP + + before + false + true + + + after + false + true + + + action + false + true + + + controller + false + true + + + id + false + true + + + url + false + true + + + params + false + true + + + asynchronous + false + true + + + method + false + true + + + update + false + true + + + onSuccess + false + true + + + onFailure + false + true + + + onComplete + false + true + + + onLoading + false + true + + + onLoaded + false + true + + + onInteractive + false + true + + true + + + invokeTag + org.codehaus.groovy.grails.web.taglib.jsp.JspInvokeGrailsTagLibTag + JSP + + it + java.lang.Object + true + NESTED + + + tagName + true + true + + true + + + diff --git a/BuildingQuality/sample-code/metrics/web-app/WEB-INF/tld/spring.tld b/BuildingQuality/sample-code/metrics/web-app/WEB-INF/tld/spring.tld new file mode 100644 index 0000000..1bc7091 --- /dev/null +++ b/BuildingQuality/sample-code/metrics/web-app/WEB-INF/tld/spring.tld @@ -0,0 +1,311 @@ + + + + + + 1.1.1 + + 1.2 + + Spring + + http://www.springframework.org/tags + + Spring Framework JSP Tag Library. Authors: Rod Johnson, Juergen Hoeller + + + + + htmlEscape + org.springframework.web.servlet.tags.HtmlEscapeTag + JSP + + + Sets default HTML escape value for the current page. + Overrides a "defaultHtmlEscape" context-param in web.xml, if any. + + + + defaultHtmlEscape + true + true + + + + + + + + escapeBody + org.springframework.web.servlet.tags.EscapeBodyTag + JSP + + + Escapes its enclosed body content, applying HTML escaping and/or JavaScript escaping. + The HTML escaping flag participates in a page-wide or application-wide setting + (i.e. by HtmlEscapeTag or a "defaultHtmlEscape" context-param in web.xml). + + + + htmlEscape + false + true + + + + javaScriptEscape + false + true + + + + + + + + message + org.springframework.web.servlet.tags.MessageTag + JSP + + + Retrieves the message with the given code, or text if code isn't resolvable. + The HTML escaping flag participates in a page-wide or application-wide setting + (i.e. by HtmlEscapeTag or a "defaultHtmlEscape" context-param in web.xml). + + + + code + false + true + + + + arguments + false + true + + + + text + false + true + + + + var + false + true + + + + scope + false + true + + + + htmlEscape + false + true + + + + javaScriptEscape + false + true + + + + + + + + theme + org.springframework.web.servlet.tags.ThemeTag + JSP + + + Retrieves the theme message with the given code, or text if code isn't resolvable. + The HTML escaping flag participates in a page-wide or application-wide setting + (i.e. by HtmlEscapeTag or a "defaultHtmlEscape" context-param in web.xml). + + + + code + false + true + + + + arguments + false + true + + + + text + false + true + + + + var + false + true + + + + scope + false + true + + + + htmlEscape + false + true + + + + javaScriptEscape + false + true + + + + + + + + hasBindErrors + org.springframework.web.servlet.tags.BindErrorsTag + JSP + + + Provides Errors instance in case of bind errors. + The HTML escaping flag participates in a page-wide or application-wide setting + (i.e. by HtmlEscapeTag or a "defaultHtmlEscape" context-param in web.xml). + + + + errors + org.springframework.validation.Errors + + + + name + true + true + + + + htmlEscape + false + true + + + + + + + + nestedPath + org.springframework.web.servlet.tags.NestedPathTag + JSP + + + Sets a nested path to be used by the bind tag's path. + + + + nestedPath + java.lang.String + + + + path + true + true + + + + + + + + bind + org.springframework.web.servlet.tags.BindTag + JSP + + + Provides BindStatus object for the given bind path. + The HTML escaping flag participates in a page-wide or application-wide setting + (i.e. by HtmlEscapeTag or a "defaultHtmlEscape" context-param in web.xml). + + + + status + org.springframework.web.servlet.support.BindStatus + + + + path + true + true + + + + ignoreNestedPath + false + true + + + + htmlEscape + false + true + + + + + + + + transform + org.springframework.web.servlet.tags.TransformTag + JSP + + + Provides transformation of variables to Strings, using an appropriate + custom PropertyEditor from BindTag (can only be used inside BindTag). + The HTML escaping flag participates in a page-wide or application-wide setting + (i.e. by HtmlEscapeTag or a "defaultHtmlEscape" context-param in web.xml). + + + + value + true + true + + + + var + false + true + + + + scope + false + true + + + + htmlEscape + false + true + + + + + diff --git a/BuildingQuality/sample-code/metrics/web-app/css/errors.css b/BuildingQuality/sample-code/metrics/web-app/css/errors.css new file mode 100644 index 0000000..bdb58bc --- /dev/null +++ b/BuildingQuality/sample-code/metrics/web-app/css/errors.css @@ -0,0 +1,109 @@ +h1, h2 { + margin: 10px 25px 5px; +} + +h2 { + font-size: 1.1em; +} + +.filename { + font-style: italic; +} + +.exceptionMessage { + margin: 10px; + border: 1px solid #000; + padding: 5px; + background-color: #E9E9E9; +} + +.stack, +.snippet { + margin: 0 25px 10px; +} + +.stack, +.snippet { + border: 1px solid #ccc; + -mox-box-shadow: 0 0 2px rgba(0,0,0,0.2); + -webkit-box-shadow: 0 0 2px rgba(0,0,0,0.2); + box-shadow: 0 0 2px rgba(0,0,0,0.2); +} + +/* error details */ +.error-details { + border-top: 1px solid #FFAAAA; + -mox-box-shadow: 0 0 2px rgba(0,0,0,0.2); + -webkit-box-shadow: 0 0 2px rgba(0,0,0,0.2); + box-shadow: 0 0 2px rgba(0,0,0,0.2); + border-bottom: 1px solid #FFAAAA; + -mox-box-shadow: 0 0 2px rgba(0,0,0,0.2); + -webkit-box-shadow: 0 0 2px rgba(0,0,0,0.2); + box-shadow: 0 0 2px rgba(0,0,0,0.2); + background-color:#FFF3F3; + line-height: 1.5; + overflow: hidden; + padding: 5px; + padding-left:25px; +} + +.error-details dt { + clear: left; + float: left; + font-weight: bold; + margin-right: 5px; +} + +.error-details dt:after { + content: ":"; +} + +.error-details dd { + display: block; +} + +/* stack trace */ +.stack { + padding: 5px; + overflow: auto; + height: 150px; +} + +/* code snippet */ +.snippet { + background-color: #fff; + font-family: monospace; +} + +.snippet .line { + display: block; +} + +.snippet .lineNumber { + background-color: #ddd; + color: #999; + display: inline-block; + margin-right: 5px; + padding: 0 3px; + text-align: right; + width: 3em; +} + +.snippet .error { + background-color: #fff3f3; + font-weight: bold; +} + +.snippet .error .lineNumber { + background-color: #faa; + color: #333; + font-weight: bold; +} + +.snippet .line:first-child .lineNumber { + padding-top: 5px; +} + +.snippet .line:last-child .lineNumber { + padding-bottom: 5px; +} \ No newline at end of file diff --git a/BuildingQuality/sample-code/metrics/web-app/css/main.css b/BuildingQuality/sample-code/metrics/web-app/css/main.css new file mode 100644 index 0000000..fcdc5eb --- /dev/null +++ b/BuildingQuality/sample-code/metrics/web-app/css/main.css @@ -0,0 +1,591 @@ +/* FONT STACK */ +body, +input, select, textarea { + font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; +} + +h1, h2, h3, h4, h5, h6 { + line-height: 1.1; +} + +/* BASE LAYOUT */ + +html { + background-color: #ddd; + background-image: -moz-linear-gradient(center top, #aaa, #ddd); + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #aaa), color-stop(1, #ddd)); + background-image: linear-gradient(top, #aaa, #ddd); + filter: progid:DXImageTransform.Microsoft.gradient(startColorStr = '#aaaaaa', EndColorStr = '#dddddd'); + background-repeat: no-repeat; + height: 100%; + /* change the box model to exclude the padding from the calculation of 100% height (IE8+) */ + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +html.no-cssgradients { + background-color: #aaa; +} + +.ie6 html { + height: 100%; +} + +html * { + margin: 0; +} + +body { + background: #ffffff; + color: #333333; + margin: 0 auto; + max-width: 960px; + overflow-x: hidden; /* prevents box-shadow causing a horizontal scrollbar in firefox when viewport < 960px wide */ + -moz-box-shadow: 0 0 0.3em #255b17; + -webkit-box-shadow: 0 0 0.3em #255b17; + box-shadow: 0 0 0.3em #255b17; +} + +#grailsLogo { + background-color: #abbf78; +} + +/* replace with .no-boxshadow body if you have modernizr available */ +.ie6 body, +.ie7 body, +.ie8 body { + border-color: #255b17; + border-style: solid; + border-width: 0 1px; +} + +.ie6 body { + height: 100%; +} + +a:link, a:visited, a:hover { + color: #48802c; +} + +a:hover, a:active { + outline: none; /* prevents outline in webkit on active links but retains it for tab focus */ +} + +h1 { + color: #48802c; + font-weight: normal; + font-size: 1.25em; + margin: 0.8em 0 0.3em 0; +} + +ul { + padding: 0; +} + +img { + border: 0; +} + +/* GENERAL */ + +#grailsLogo a { + display: inline-block; + margin: 1em; +} + +.content { +} + +.content h1 { + border-bottom: 1px solid #CCCCCC; + margin: 0.8em 1em 0.3em; + padding: 0 0.25em; +} + +.scaffold-list h1 { + border: none; +} + +.footer { + background: #abbf78; + color: #000; + clear: both; + font-size: 0.8em; + margin-top: 1.5em; + padding: 1em; + min-height: 1em; +} + +.footer a { + color: #255b17; +} + +.spinner { + background: url(../images/spinner.gif) 50% 50% no-repeat transparent; + height: 16px; + width: 16px; + padding: 0.5em; + position: absolute; + right: 0; + top: 0; + text-indent: -9999px; +} + +/* NAVIGATION MENU */ + +.nav { + background-color: #efefef; + padding: 0.5em 0.75em; + -moz-box-shadow: 0 0 3px 1px #aaaaaa; + -webkit-box-shadow: 0 0 3px 1px #aaaaaa; + box-shadow: 0 0 3px 1px #aaaaaa; + zoom: 1; +} + +.nav ul { + overflow: hidden; + padding-left: 0; + zoom: 1; +} + +.nav li { + display: block; + float: left; + list-style-type: none; + margin-right: 0.5em; + padding: 0; +} + +.nav a { + color: #666666; + display: block; + padding: 0.25em 0.7em; + text-decoration: none; + -moz-border-radius: 0.3em; + -webkit-border-radius: 0.3em; + border-radius: 0.3em; +} + +.nav a:active, .nav a:visited { + color: #666666; +} + +.nav a:focus, .nav a:hover { + background-color: #999999; + color: #ffffff; + outline: none; + text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.8); +} + +.no-borderradius .nav a:focus, .no-borderradius .nav a:hover { + background-color: transparent; + color: #444444; + text-decoration: underline; +} + +.nav a.home, .nav a.list, .nav a.create { + background-position: 0.7em center; + background-repeat: no-repeat; + text-indent: 25px; +} + +.nav a.home { + background-image: url(../images/skin/house.png); +} + +.nav a.list { + background-image: url(../images/skin/database_table.png); +} + +.nav a.create { + background-image: url(../images/skin/database_add.png); +} + +/* CREATE/EDIT FORMS AND SHOW PAGES */ + +fieldset, +.property-list { + margin: 0.6em 1.25em 0 1.25em; + padding: 0.3em 1.8em 1.25em; + position: relative; + zoom: 1; + border: none; +} + +.property-list .fieldcontain { + list-style: none; + overflow: hidden; + zoom: 1; +} + +.fieldcontain { + margin-top: 1em; +} + +.fieldcontain label, +.fieldcontain .property-label { + color: #666666; + text-align: right; + width: 25%; +} + +.fieldcontain .property-label { + float: left; +} + +.fieldcontain .property-value { + display: block; + margin-left: 27%; +} + +label { + cursor: pointer; + display: inline-block; + margin: 0 0.25em 0 0; +} + +input, select, textarea { + background-color: #fcfcfc; + border: 1px solid #cccccc; + font-size: 1em; + padding: 0.2em 0.4em; +} + +select { + padding: 0.2em 0.2em 0.2em 0; +} + +select[multiple] { + vertical-align: top; +} + +textarea { + width: 250px; + height: 150px; + overflow: auto; /* IE always renders vertical scrollbar without this */ + vertical-align: top; +} + +input[type=checkbox], input[type=radio] { + background-color: transparent; + border: 0; + padding: 0; +} + +input:focus, select:focus, textarea:focus { + background-color: #ffffff; + border: 1px solid #eeeeee; + outline: 0; + -moz-box-shadow: 0 0 0.5em #ffffff; + -webkit-box-shadow: 0 0 0.5em #ffffff; + box-shadow: 0 0 0.5em #ffffff; +} + +.required-indicator { + color: #48802C; + display: inline-block; + font-weight: bold; + margin-left: 0.3em; + position: relative; + top: 0.1em; +} + +ul.one-to-many { + display: inline-block; + list-style-position: inside; + vertical-align: top; +} + +.ie6 ul.one-to-many, .ie7 ul.one-to-many { + display: inline; + zoom: 1; +} + +ul.one-to-many li.add { + list-style-type: none; +} + +/* EMBEDDED PROPERTIES */ + +fieldset.embedded { + background-color: transparent; + border: 1px solid #CCCCCC; + margin-left: 0; + margin-right: 0; + padding-left: 0; + padding-right: 0; + -moz-box-shadow: none; + -webkit-box-shadow: none; + box-shadow: none; +} + +fieldset.embedded legend { + margin: 0 1em; +} + +/* MESSAGES AND ERRORS */ + +.errors, +.message { + font-size: 0.8em; + line-height: 2; + margin: 1em 2em; + padding: 0.25em; +} + +.message { + background: #f3f3ff; + border: 1px solid #b2d1ff; + color: #006dba; + -moz-box-shadow: 0 0 0.25em #b2d1ff; + -webkit-box-shadow: 0 0 0.25em #b2d1ff; + box-shadow: 0 0 0.25em #b2d1ff; +} + +.errors { + background: #fff3f3; + border: 1px solid #ffaaaa; + color: #cc0000; + -moz-box-shadow: 0 0 0.25em #ff8888; + -webkit-box-shadow: 0 0 0.25em #ff8888; + box-shadow: 0 0 0.25em #ff8888; +} + +.errors ul, +.message { + padding: 0; +} + +.errors li { + list-style: none; + background: transparent url(../images/skin/exclamation.png) 0.5em 50% no-repeat; + text-indent: 2.2em; +} + +.message { + background: transparent url(../images/skin/information.png) 0.5em 50% no-repeat; + text-indent: 2.2em; +} + +/* form fields with errors */ + +.error input, .error select, .error textarea { + background: #fff3f3; + border-color: #ffaaaa; + color: #cc0000; +} + +.error input:focus, .error select:focus, .error textarea:focus { + -moz-box-shadow: 0 0 0.5em #ffaaaa; + -webkit-box-shadow: 0 0 0.5em #ffaaaa; + box-shadow: 0 0 0.5em #ffaaaa; +} + +/* same effects for browsers that support HTML5 client-side validation (these have to be specified separately or IE will ignore the entire rule) */ + +input:invalid, select:invalid, textarea:invalid { + background: #fff3f3; + border-color: #ffaaaa; + color: #cc0000; +} + +input:invalid:focus, select:invalid:focus, textarea:invalid:focus { + -moz-box-shadow: 0 0 0.5em #ffaaaa; + -webkit-box-shadow: 0 0 0.5em #ffaaaa; + box-shadow: 0 0 0.5em #ffaaaa; +} + +/* TABLES */ + +table { + border-top: 1px solid #DFDFDF; + border-collapse: collapse; + width: 100%; + margin-bottom: 1em; +} + +tr { + border: 0; +} + +tr>td:first-child, tr>th:first-child { + padding-left: 1.25em; +} + +tr>td:last-child, tr>th:last-child { + padding-right: 1.25em; +} + +td, th { + line-height: 1.5em; + padding: 0.5em 0.6em; + text-align: left; + vertical-align: top; +} + +th { + background-color: #efefef; + background-image: -moz-linear-gradient(top, #ffffff, #eaeaea); + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #ffffff), color-stop(1, #eaeaea)); + filter: progid:DXImageTransform.Microsoft.gradient(startColorStr = '#ffffff', EndColorStr = '#eaeaea'); + -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#ffffff', EndColorStr='#eaeaea')"; + color: #666666; + font-weight: bold; + line-height: 1.7em; + padding: 0.2em 0.6em; +} + +thead th { + white-space: nowrap; +} + +th a { + display: block; + text-decoration: none; +} + +th a:link, th a:visited { + color: #666666; +} + +th a:hover, th a:focus { + color: #333333; +} + +th.sortable a { + background-position: right; + background-repeat: no-repeat; + padding-right: 1.1em; +} + +th.asc a { + background-image: url(../images/skin/sorted_asc.gif); +} + +th.desc a { + background-image: url(../images/skin/sorted_desc.gif); +} + +.odd { + background: #f7f7f7; +} + +.even { + background: #ffffff; +} + +th:hover, tr:hover { + background: #E1F2B6; +} + +/* PAGINATION */ + +.pagination { + border-top: 0; + margin: 0; + padding: 0.3em 0.2em; + text-align: center; + -moz-box-shadow: 0 0 3px 1px #AAAAAA; + -webkit-box-shadow: 0 0 3px 1px #AAAAAA; + box-shadow: 0 0 3px 1px #AAAAAA; + background-color: #EFEFEF; +} + +.pagination a, +.pagination .currentStep { + color: #666666; + display: inline-block; + margin: 0 0.1em; + padding: 0.25em 0.7em; + text-decoration: none; + -moz-border-radius: 0.3em; + -webkit-border-radius: 0.3em; + border-radius: 0.3em; +} + +.pagination a:hover, .pagination a:focus, +.pagination .currentStep { + background-color: #999999; + color: #ffffff; + outline: none; + text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.8); +} + +.no-borderradius .pagination a:hover, .no-borderradius .pagination a:focus, +.no-borderradius .pagination .currentStep { + background-color: transparent; + color: #444444; + text-decoration: underline; +} + +/* ACTION BUTTONS */ + +.buttons { + background-color: #efefef; + overflow: hidden; + padding: 0.3em; + -moz-box-shadow: 0 0 3px 1px #aaaaaa; + -webkit-box-shadow: 0 0 3px 1px #aaaaaa; + box-shadow: 0 0 3px 1px #aaaaaa; + margin: 0.1em 0 0 0; + border: none; +} + +.buttons input, +.buttons a { + background-color: transparent; + border: 0; + color: #666666; + cursor: pointer; + display: inline-block; + margin: 0 0.25em 0; + overflow: visible; + padding: 0.25em 0.7em; + text-decoration: none; + + -moz-border-radius: 0.3em; + -webkit-border-radius: 0.3em; + border-radius: 0.3em; +} + +.buttons input:hover, .buttons input:focus, +.buttons a:hover, .buttons a:focus { + background-color: #999999; + color: #ffffff; + outline: none; + text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.8); + -moz-box-shadow: none; + -webkit-box-shadow: none; + box-shadow: none; +} + +.no-borderradius .buttons input:hover, .no-borderradius .buttons input:focus, +.no-borderradius .buttons a:hover, .no-borderradius .buttons a:focus { + background-color: transparent; + color: #444444; + text-decoration: underline; +} + +.buttons .delete, .buttons .edit, .buttons .save { + background-position: 0.7em center; + background-repeat: no-repeat; + text-indent: 25px; +} + +.buttons .delete { + background-image: url(../images/skin/database_delete.png); +} + +.buttons .edit { + background-image: url(../images/skin/database_edit.png); +} + +.buttons .save { + background-image: url(../images/skin/database_save.png); +} + +a.skip { + position: absolute; + left: -9999px; +} diff --git a/BuildingQuality/sample-code/metrics/web-app/css/mobile.css b/BuildingQuality/sample-code/metrics/web-app/css/mobile.css new file mode 100644 index 0000000..167f502 --- /dev/null +++ b/BuildingQuality/sample-code/metrics/web-app/css/mobile.css @@ -0,0 +1,82 @@ +/* Styles for mobile devices */ + +@media screen and (max-width: 480px) { + .nav { + padding: 0.5em; + } + + .nav li { + margin: 0 0.5em 0 0; + padding: 0.25em; + } + + /* Hide individual steps in pagination, just have next & previous */ + .pagination .step, .pagination .currentStep { + display: none; + } + + .pagination .prevLink { + float: left; + } + + .pagination .nextLink { + float: right; + } + + /* pagination needs to wrap around floated buttons */ + .pagination { + overflow: hidden; + } + + /* slightly smaller margin around content body */ + fieldset, + .property-list { + padding: 0.3em 1em 1em; + } + + input, textarea { + width: 100%; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + -ms-box-sizing: border-box; + box-sizing: border-box; + } + + select, input[type=checkbox], input[type=radio], input[type=submit], input[type=button], input[type=reset] { + width: auto; + } + + /* hide all but the first column of list tables */ + .scaffold-list td:not(:first-child), + .scaffold-list th:not(:first-child) { + display: none; + } + + .scaffold-list thead th { + text-align: center; + } + + /* stack form elements */ + .fieldcontain { + margin-top: 0.6em; + } + + .fieldcontain label, + .fieldcontain .property-label, + .fieldcontain .property-value { + display: block; + float: none; + margin: 0 0 0.25em 0; + text-align: left; + width: auto; + } + + .errors ul, + .message p { + margin: 0.5em; + } + + .error ul { + margin-left: 0; + } +} diff --git a/BuildingQuality/sample-code/metrics/web-app/images/apple-touch-icon-retina.png b/BuildingQuality/sample-code/metrics/web-app/images/apple-touch-icon-retina.png new file mode 100644 index 0000000000000000000000000000000000000000..5cc83edbe69203eaaf7d64e5b2596de6e01fff29 GIT binary patch literal 14986 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 literal 0 HcmV?d00001 diff --git a/BuildingQuality/sample-code/metrics/web-app/images/favicon.ico b/BuildingQuality/sample-code/metrics/web-app/images/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..3dfcb9279f60f2396a8f19fb6607ff281800c905 GIT binary patch literal 10134 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 HxB~wLBPRzvo?bs5u)ML^KP)Z7$c zVPOGoFb{x%1AMMT`}+WZxw#U+4FCW;Ai=@`urO;zOp^SMx+$}MnuYCO?X1kY1`8`7 z$h=xH>2JBgq`&X{->c0{|KPi-R#zNk?`f&3>jI2f;1a;b%KG>Nip zIF5+$^YV-Qj|-y%5aI?LSj5>_P6Dh#ENnt7jBWtTWS@g6mA``dkHW&r&q2muqJ4IOcPJU5G>YgoZKaG25G5C&NTEA7qzu%bC=D0ojca
v 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 literal 0 HcmV?d00001 diff --git a/BuildingQuality/sample-code/metrics/web-app/images/grails_logo.png b/BuildingQuality/sample-code/metrics/web-app/images/grails_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..9836b93d2cbdee17ee3c18329bef39ec724dcf97 GIT binary patch literal 10172 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 Vd*l#Wn-~B9002ovPDHLkV1nEVK@R`` literal 0 HcmV?d00001 diff --git a/BuildingQuality/sample-code/metrics/web-app/images/leftnav_midstretch.png b/BuildingQuality/sample-code/metrics/web-app/images/leftnav_midstretch.png new file mode 100644 index 0000000000000000000000000000000000000000..3cb8a51559b4bd4ed79fba033b4274b33e5cdd2c GIT binary patch literal 2883 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 literal 0 HcmV?d00001 diff --git a/BuildingQuality/sample-code/metrics/web-app/images/leftnav_top.png b/BuildingQuality/sample-code/metrics/web-app/images/leftnav_top.png new file mode 100644 index 0000000000000000000000000000000000000000..6afec7d32f3163446829de0ed38099021fc7b0d6 GIT binary patch literal 3317 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 literal 0 HcmV?d00001 diff --git a/BuildingQuality/sample-code/metrics/web-app/images/skin/database_delete.png b/BuildingQuality/sample-code/metrics/web-app/images/skin/database_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..cce652e845cde732ac3ce9a4132b597301ad660e GIT binary patch literal 659 zcmV;E0&M+>P)ps_J1 zHhTmGl@tMUh=_=a3Fb%)BqZVTW3s!xH?UsxE?7A5@n+t<@6Gq#%m~l(@IOPFT;%il z03|#}Sa4nU2-$-Kn!4}FekQv@$S0FY$L9!N0g;c={9!m8K4zLG48uSu6aw$J+ii5a zT~sO+G#ZW9!I0fqFSvY9*@h|sR=YqL#x%oU@(yD@pz0* zr-R{eDEHX6V*RaK<|4rWl@GKt@8COeKZT>%ICBq4+h_I-+?Y*V28oxmqBc+Oz5 zc>4@kzJgDe<1lkKXYEtktsNC`FoTI)4qLaF!_1E&4qv>EKx`iUcee83)!MzalltZ# z3K)~8`*H_w9^uf5^9X)<39-6>(AOuJvu0IKc#FRkFoCa%ULtC>8v6bIR-H|{S~CWm zy|LB2yL+L!Vs5g8ONBz=aUzj0EX$JbfSV}a#vT*B_2)32Uc<0oLyzLS9V$=7hM4?~ znM@`|iEa~8)bZW?7q}d~l*7K(I`+@}grT|_=WaH**u tj~DMRZZpzVy^OjT85Vq(G=8XD@S91FH}kp`d7hyPh1 z5CCa%X>*RH50W(1GMNlqE*ChCgTvu4bCM)M5Co)BDTG2HvvyYjmSvI4<)A2v`CcxU zQ79BpEEdf*P56K_c;lUWy=bic9s#4IZm`yWps?HR<^;5uf_%3rLf1Uy7}ym7{u3SG zgQxL#;V@<+y-&7GK#MIB!!Xb^&5SuEhPoOV9{wDJpWonQN~qlHho`!h-y&cUDCjiw zot3{JSR;b3Z$U9V2&bDtVsaL$Qu?FFtIb;kXm<)qqyl<=9Kq@&_)r^^)N|OJWjH)_ za7i;6X_aj`duRB^h5&`toyKA^3V-E1_yb`=eg>PPj8Y+p^vFkpk)_tg?(s>=HO~R< zNVkfdL~{$}rBQI|9QHR{MrpYhcBg@2p$?h%pAnUsbBDUeKUv#oTc6-&EEZdf$Kwze zM&QwZLDd6D&pd?=1#1F{N2f6?Hf8gwvt`>|pf)ft5F|nm_AI~XywcT&?}K--v^WN? z_7vo-s3)9F{TXfF{hpqll^q2vdwBb}datvKg-yfc+gC^|#8-K5)%lB$rlxi}-rEGO xUZ|2A>wRp~(I5;*aZFyx-fDe3J-^%i_y?+(!m^mX(n$aS002ovPDHLkV1gwlT*CkW literal 0 HcmV?d00001 diff --git a/BuildingQuality/sample-code/metrics/web-app/images/skin/database_save.png b/BuildingQuality/sample-code/metrics/web-app/images/skin/database_save.png new file mode 100644 index 0000000000000000000000000000000000000000..44c06dddf19fbda14efe428b9b1793c13f46b2cf GIT binary patch literal 755 zcmV3^_07cLZBR}_>&jXObH zw2it@svr%qE?kJ(Xuudu+DSW|WWK!jNvbU^UO02#+Tt zYOko4%Vx8c4Gh!M(=Qem7g;XcE?n0Qi^XD?&*vX7@xPFCIh;%;@xMr?(;$(vo9j9i z6;riZMJyIWG#Z6r7^-I5HtO{{DwPWQ`}>&y+Y;!yjz*&a$8prX=XtO!3$0d5J>%Mz z1f8>Jnx-7^X2#7Yb#zC2VYfZ>c17@L{s)8{OuWBa3WHFfVXfhLv2t?V0V~q5R2D*D z&315l_#iF}b>Zoo?-;+7*`WOJWsMw(x3WXv`@U*s@Y-&edFEYpz0skP)dFfu zZ4wIp&Vbb!+|0+3Qa}p<*AH-eY>3q8s6?RA)zqP8W39IT5HLFG9m1F);gE|P`L7@@ zctjKsn1rA6!ZZR%R^(SjU!r=2o$yGp<$KViK~{B;AIcgvN+J+&Nvur+W(Sw&=H?z} zGMRW^U!Nl3AvWzQ3~C%Z*G*(?qLfNCq;tpg2yRW4@yl9;p3CK)O-@c8Sy))OUMiKc zQp#QYFZe-*@LZDInR^#F=Bm=!vA2i6tkEJ#i0aggzp2D%3!>h~r~3uLt(-IMoyFAT&uF!>{(iS?1OX-eX zKw9bunxR5FrF6QaYs~9>A4#zW^dwIvCpq(+cfR?U`T6-{9LHUqo16RKcDwUVr?cX4 zIN~hJDs48~aRAJ}U_2g=KAB9SP$;0;Y@*$6Ly{z<(`i^NmbL#1W@l#$wOS3;YPBOE zJ;7`?L*?Ga6XzC292wl75}>gDz`(>h?is$JPxm#0jGnotoK|nAVM5$DQ z!C*kO-aeF@+Ejy?nVHEp8V&F~k7BWicsx!aH9kHLRpcQ?L&JFBAB4i&kAaVUxVvzh z3a-EY0%m%8nhI7|SE(QpiBL#sG#VUMM9}*(0mg2(Q$Zq;z|PJNd_Euiem@;jtJN@i za|c2MmsL?PR;yKNwOUA}QuO=7;V@#c7!{~gs?J7hAlsE7U#g?$aRkhSTqLq6iuCu9 z10_j_=;?Dc?4cZ386qH0HkgHTDT|HmGR`W4V2noNQJqfLJEot)q{V_UtsW+m31cP~ zDwWEi3HYBSoF4M;T?VaIdqinn1HZ9}32qs-PdwPbCf+WI6n9jl0-8cjV3%1FB%B&r z+`mzSliyLSH0dxYE}rk&=!uCa*V>()2znj`_XYjtbt>@4FLHnJE|G`xv)Ba@oLBny z1%3K7c4fiB^4{k6E8Pif0kNy62}b@9+N#0$9Ug7g~-`rQ^qx~m@y2OU8A z#zh~=7n#Z$Z*fx-GOtDf07cgx0suCz_W(2~Y(0tf@FX@P6EPuM_dgn$vj9LucO)%W zw%HgMW>=#oL>nZ>M&NEf08>)#)k<{$fCT_r>rPi=BV=hFh6WS^qqze>C6Ek}o{M5% za|@JGowu0t{&hgNzySHZxy@LTNh);YzZ2zSp_ zl$^T&Dnc|NLb&RD_!4>pt@VHdP)ZGER%5ZmWEe$lryR&y;2u^3cOkO4#6c%-(EY6a{600000NkvXXu0mjfxS2AI literal 0 HcmV?d00001 diff --git a/BuildingQuality/sample-code/metrics/web-app/images/skin/house.png b/BuildingQuality/sample-code/metrics/web-app/images/skin/house.png new file mode 100644 index 0000000000000000000000000000000000000000..fed62219f57cdfb854782dbadf5123c44d056bd4 GIT binary patch literal 806 zcmV+>1KIqEP)v;U&v3%|^C`Ga3?LtY&4dQB4Oz;1v;J%z!D&%WRH@BZ?x; z3)8@IUIv@hG|@IwyHLC`l{1<4BK>wam95g|i|?Cfzt876&-Zx_0f5*l-9`IJI&mHu zE6$@xB)6N}7VeR;!X8D!TAw;;&0Bsj?A071cO>X3K0wl7WZ1;Tg!4LHyNcnzoeQ7t zNW`aSlm8WXYkek&ir$13=ngczvf zV0vnjNpCF&K8px}dunv+`LIb-sOC$_jD(;IBI$xC|7`(+9cA>Vir_V#z{?k7SX^Ah z^71m~W@q439Ycqfhi7+gp#A14n1n1!e>$EdeATG|f798Y=ggzwEKH2Q!qU2QA(Se?dwqG69%>n$6rtE z%F(845Az8c{w(XgimJg96!jLMz?zS6I1HUm2baqQx7&@nx;lhHA!r6vs2|fqJETOu zLxeu2OQ(3(au%dg>AcZsWI(zXn9XJg1cLe8k~0h0wOL=&HK}7X k{AKr*U4z7Szv)i%9gTgghwgU$Q~&?~07*qoM6N<$g31kYk^lez literal 0 HcmV?d00001 diff --git a/BuildingQuality/sample-code/metrics/web-app/images/skin/information.png b/BuildingQuality/sample-code/metrics/web-app/images/skin/information.png new file mode 100644 index 0000000000000000000000000000000000000000..12cd1aef900803abba99b26920337ec01ad5c267 GIT binary patch literal 778 zcmV+l1NHogP)BVme|mWaqy4$_pJm?y9KM{-*hp?1+Ey3e-CEDooTa!B;e(Q>TSF?bj>5At13y1p zriN3w3x~5SfZj{@J4M{kp{?=M_Lh2bV+5LH)Q)5W!-ePA$RgE1@5f1cyHki0Y}JyVEYZF(LD$xXlt$7A5CgE@ zpV-&l%vf;=5kZ2-2gi@Y6J&=cuwt>!vJ^#(&n|LcZyUzi6Duj$$hJ1s*HD-#;k-w@ zpdrwAuoDG_N2bvb07G$Zk*?Hc)JLtW4yqOnic_$zO7NZ#l>Fm){;fE?b$IbOaX2fe z0la4g0Dfw2xk7Wi7NapVD8YMPCZu?A1QCK*67dgsvRKBLFtrM>?$%&_lD1882mzdO zWPdw5KWw6IT`m1b_8=lS5jt8D3=RDa=&jWzR-)S@56WMslZ~mKu1)-wpXB>rNBQ>N zU#K`#1B&v|_AQK;7I~B}OdGiUT9LX>f0xm6<;LeP!=vFjPsUQF*wCJ*dO)4YBypgdiuF!=i@6Zyi7F|q#K zz?tlSZULa@t1D?$e;f@b36&N!V2mjOHw|*FMR=dr@6o0ZXGBB_+=zx3%$`cG63Jm-*84Da1I50Ew7%?y?G#+5$ UVU>wEFhP-tNtBU=gM+~u00(^_>i_@% literal 0 HcmV?d00001 diff --git a/BuildingQuality/sample-code/metrics/web-app/images/skin/sorted_desc.gif b/BuildingQuality/sample-code/metrics/web-app/images/skin/sorted_desc.gif new file mode 100644 index 0000000000000000000000000000000000000000..38b3a01d078418d3afcdb2765251a9f21b7995be GIT binary patch literal 834 zcmZ?wbhEHbWMg1s_|Cu}C@83_tE;D{=jG+)?d|RKCt}{bc?%XSShQ%-?%lih?%lh8 z|9*y1Fd72GGz1iXvM@3*urla?{0GVt3>@+doD32i4hNW;7z9Kl3=A9^nYh^GDt25@ NJj%i*$Hu~74FL5|8=3$B literal 0 HcmV?d00001 diff --git a/BuildingQuality/sample-code/metrics/web-app/images/spinner.gif b/BuildingQuality/sample-code/metrics/web-app/images/spinner.gif new file mode 100644 index 0000000000000000000000000000000000000000..1ed786f2ece49ec5db07dee13a56ef38025b628c GIT binary patch literal 2037 zcmY*ZcTf|19{+AO8xjIZfItFCFrkL3BodGwflvety+|>T03uy{D35o<4X`9Q3=bSU zojZMs3Qw_)j=f_!)B!!mUKqwc>ezd^4c;H{$Ifr|uTTHRC8&buXgI)uM*u&6{`~Rd zM}L3+_wV1IK7G1x-@ebEKY#i1<^B8j-@bj@wr$&s7cWknII(;8?sMnPJ$(4^-Me>t z_wN1p@#D#pCr3v|A3b`6qUeJM5ANT;KRi7A^5x65YuBDSb?WNXs}mCwVPRo|gM+(v z?RxX(&Gzlv_w3no`}XavTesf4dGq@9>xT~?_VDnybm`KK8#fLfJh*P%x(gRB?AWp6 z>({T(pFdAaOMCY0SzBA%hYueT6BF;;xnpHzb@}q;O`A4(d3im4{J5Z?;ONn#0|NsW zFJ9cgfB);(ugAv5a&vP_OG`&aMz(C(^6J&A@$vBk2M!!Re*DRkCvV@rJ%9duQ&ZFC z&6|%MJC>4?a{Bb?vuDqqIdg`~z*4Ws1>(;I2=4ORL zQCC-|R4OYgD_5;rwQSk44I4IW+_=%t&(GD>Rj=1yxpHM_Xh`ytnG&0k9<5Zz%KT@c z2mnYvQ>hsF`jQ_R5(mKIydH2saldkg!Gzlvi9nFeu<gyfnCs8|SGO1R0M3N~Sp zx@MoynP5Rh(303ldPHFemMT%$+lXy}A1JR?IwL6=E`apW=@Z-0R!QO^@j_&{6#;i|5R1o$ zJ1J~xCDQ$1cs9`DW9Z!)D)^+%&Ug81908UkMXX;jkp>#b+SE}d{`0S>>Ef(`Ns6oa zB~H-LX25y1!BDgW%?nC0$RettYz8zsuz>9Z!g8TH$kU;rwYWrSTkjuYCH9utgFU6b z*wzBKaG6IjEXYSpAo5j4&c(t zwi-c(Q6YX2N-v2q(mgN`>wuCTV&XSRUA4h-f8g+uV2k_=o;2wb`7N)&+7T-C+CT_Bu4KrjWmK>x0AbH2rmR&7+q6fX+R0o&}V!t?TP+g0{x`8PSP{7CvnEPL^Hzx^T2Eus2 zi$U6ZM7}+l%$}afWn#%|+MPTsC236GKi9-ad*Z9;Ymg?jSO$L1s$w4BvDzu_kH9>z zTWC{K?jx4~H3oGGt3}I}LWNw@H)C>9GF4^|x(5n#+Va}kr_cb>{a+K%>B+@JNrC8? zJOUkD3fe*NdA-rJupqo?FfRK}k zOm!l7Dj$dsL|kS`3FL3^@^7axrU9d*@79yf!+bu3kXbziU!v&TO3p#w{y_lYG5ZPzDh;giB_lkGp((nqZ12&%LTrgm4vY= z{ffd0B$DiUKReJ9>?{#_KVrMyhiu_A8fNd!&DWTZ4+9S|1lJHkLv-^}a0IC{WI9N! zQTY-}db!%OH^;l2ZeajnA&Q6Uv=#0KZB9;^^lzMOi^0~bS~m!&K#e6hia79(ItV9M SXP~*+AU!zMlD%~Wg#Hic*k=_0 literal 0 HcmV?d00001 diff --git a/BuildingQuality/sample-code/metrics/web-app/images/springsource.png b/BuildingQuality/sample-code/metrics/web-app/images/springsource.png new file mode 100644 index 0000000000000000000000000000000000000000..e806d001151dd0c5dfbb2d24e9255e7b1f3c1cc3 GIT binary patch literal 9109 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 literal 0 HcmV?d00001 diff --git a/BuildingQuality/sample-code/metrics/web-app/js/application.js b/BuildingQuality/sample-code/metrics/web-app/js/application.js new file mode 100644 index 0000000..b2adb96 --- /dev/null +++ b/BuildingQuality/sample-code/metrics/web-app/js/application.js @@ -0,0 +1,9 @@ +if (typeof jQuery !== 'undefined') { + (function($) { + $('#spinner').ajaxStart(function() { + $(this).fadeIn(); + }).ajaxStop(function() { + $(this).fadeOut(); + }); + })(jQuery); +}