Browse files

initial commit of blueprint project

  • Loading branch information...
0 parents commit 0cfb6e0c5ecfe3f887f80634350045a8f15fbd3b @warnero committed Aug 25, 2010
Showing with 17,202 additions and 0 deletions.
  1. +8 −0 application.properties
  2. +7 −0 grails-app/conf/BootStrap.groovy
  3. +31 −0 grails-app/conf/BuildConfig.groovy
  4. +83 −0 grails-app/conf/Config.groovy
  5. +32 −0 grails-app/conf/DataSource.groovy
  6. +13 −0 grails-app/conf/UrlMappings.groovy
  7. +3 −0 grails-app/conf/spring/resources.groovy
  8. +6 −0 grails-app/controllers/blueprint/PlayerController.groovy
  9. +12 −0 grails-app/domain/blueprint/Player.groovy
  10. +55 −0 grails-app/i18n/messages.properties
  11. +56 −0 grails-app/i18n/messages_da.properties
  12. +55 −0 grails-app/i18n/messages_de.properties
  13. +30 −0 grails-app/i18n/messages_es.properties
  14. +19 −0 grails-app/i18n/messages_fr.properties
  15. +19 −0 grails-app/i18n/messages_it.properties
  16. +19 −0 grails-app/i18n/messages_ja.properties
  17. +55 −0 grails-app/i18n/messages_nl.properties
  18. +34 −0 grails-app/i18n/messages_pt_BR.properties
  19. +34 −0 grails-app/i18n/messages_pt_PT.properties
  20. +31 −0 grails-app/i18n/messages_ru.properties
  21. +35 −0 grails-app/i18n/messages_th.properties
  22. +18 −0 grails-app/i18n/messages_zh_CN.properties
  23. +54 −0 grails-app/views/error.gsp
  24. +100 −0 grails-app/views/index.gsp
  25. +24 −0 grails-app/views/layouts/main.gsp
  26. +4 −0 src/templates/artifacts/Controller.groovy
  27. +5 −0 src/templates/artifacts/DomainClass.groovy
  28. +17 −0 src/templates/artifacts/Filters.groovy
  29. +7 −0 src/templates/artifacts/Script.groovy
  30. +8 −0 src/templates/artifacts/Service.groovy
  31. +3 −0 src/templates/artifacts/TagLib.groovy
  32. +15 −0 src/templates/artifacts/Tests.groovy
  33. +54 −0 src/templates/artifacts/WebTest.groovy
  34. +18 −0 src/templates/artifacts/hibernate.cfg.xml
  35. +98 −0 src/templates/scaffolding/Controller.groovy
  36. +65 −0 src/templates/scaffolding/create.gsp
  37. +64 −0 src/templates/scaffolding/edit.gsp
  38. +62 −0 src/templates/scaffolding/list.gsp
  39. +171 −0 src/templates/scaffolding/renderEditor.template
  40. +66 −0 src/templates/scaffolding/show.gsp
  41. +102 −0 src/templates/war/web.xml
  42. +17 −0 test/unit/blueprint/PlayerControllerTests.groovy
  43. +17 −0 test/unit/blueprint/PlayerTests.groovy
  44. +42 −0 web-app/WEB-INF/applicationContext.xml
  45. +14 −0 web-app/WEB-INF/sitemesh.xml
  46. +563 −0 web-app/WEB-INF/tld/c.tld
  47. +671 −0 web-app/WEB-INF/tld/fmt.tld
  48. +550 −0 web-app/WEB-INF/tld/grails.tld
  49. +311 −0 web-app/WEB-INF/tld/spring.tld
  50. +31 −0 web-app/css/application.css
  51. +35 −0 web-app/css/blueprint/ie.css
  52. BIN web-app/css/blueprint/plugins/buttons/icons/cross.png
  53. BIN web-app/css/blueprint/plugins/buttons/icons/key.png
  54. BIN web-app/css/blueprint/plugins/buttons/icons/tick.png
  55. +32 −0 web-app/css/blueprint/plugins/buttons/readme.txt
  56. +97 −0 web-app/css/blueprint/plugins/buttons/screen.css
  57. +14 −0 web-app/css/blueprint/plugins/fancy-type/readme.txt
  58. +71 −0 web-app/css/blueprint/plugins/fancy-type/screen.css
  59. BIN web-app/css/blueprint/plugins/link-icons/icons/doc.png
  60. BIN web-app/css/blueprint/plugins/link-icons/icons/email.png
  61. BIN web-app/css/blueprint/plugins/link-icons/icons/external.png
  62. BIN web-app/css/blueprint/plugins/link-icons/icons/feed.png
  63. BIN web-app/css/blueprint/plugins/link-icons/icons/im.png
  64. BIN web-app/css/blueprint/plugins/link-icons/icons/pdf.png
  65. BIN web-app/css/blueprint/plugins/link-icons/icons/visited.png
  66. BIN web-app/css/blueprint/plugins/link-icons/icons/xls.png
  67. +18 −0 web-app/css/blueprint/plugins/link-icons/readme.txt
  68. +40 −0 web-app/css/blueprint/plugins/link-icons/screen.css
  69. +10 −0 web-app/css/blueprint/plugins/rtl/readme.txt
  70. +110 −0 web-app/css/blueprint/plugins/rtl/screen.css
  71. +29 −0 web-app/css/blueprint/print.css
  72. +258 −0 web-app/css/blueprint/screen.css
  73. +65 −0 web-app/css/blueprint/src/forms.css
  74. +280 −0 web-app/css/blueprint/src/grid.css
  75. BIN web-app/css/blueprint/src/grid.png
  76. +76 −0 web-app/css/blueprint/src/ie.css
  77. +85 −0 web-app/css/blueprint/src/print.css
  78. +45 −0 web-app/css/blueprint/src/reset.css
  79. +106 −0 web-app/css/blueprint/src/typography.css
  80. +270 −0 web-app/css/main.css
  81. BIN web-app/images/favicon.ico
  82. BIN web-app/images/grails_logo.jpg
  83. BIN web-app/images/grails_logo.png
  84. BIN web-app/images/leftnav_btm.png
  85. BIN web-app/images/leftnav_midstretch.png
  86. BIN web-app/images/leftnav_top.png
  87. BIN web-app/images/skin/database_add.png
  88. BIN web-app/images/skin/database_delete.png
  89. BIN web-app/images/skin/database_edit.png
  90. BIN web-app/images/skin/database_save.png
  91. BIN web-app/images/skin/database_table.png
  92. BIN web-app/images/skin/exclamation.png
  93. BIN web-app/images/skin/house.png
  94. BIN web-app/images/skin/information.png
  95. BIN web-app/images/skin/shadow.jpg
  96. BIN web-app/images/skin/sorted_asc.gif
  97. BIN web-app/images/skin/sorted_desc.gif
  98. BIN web-app/images/spinner.gif
  99. BIN web-app/images/springsource.png
  100. +13 −0 web-app/js/application.js
  101. +7 −0 web-app/js/prototype/animation.js
  102. +136 −0 web-app/js/prototype/builder.js
  103. +965 −0 web-app/js/prototype/controls.js
  104. +974 −0 web-app/js/prototype/dragdrop.js
  105. +1,123 −0 web-app/js/prototype/effects.js
  106. +4,874 −0 web-app/js/prototype/prototype.js
  107. +2,691 −0 web-app/js/prototype/rico.js
  108. +68 −0 web-app/js/prototype/scriptaculous.js
  109. +275 −0 web-app/js/prototype/slider.js
  110. +59 −0 web-app/js/prototype/sound.js
  111. +568 −0 web-app/js/prototype/unittest.js
8 application.properties
@@ -0,0 +1,8 @@
+#Grails Metadata file
+#Tue Jul 20 11:08:59 MST 2010
+app.grails.version=1.3.3
+app.name=blueprint
+app.servlet.version=2.4
+app.version=0.1
+plugins.hibernate=1.3.3
+plugins.tomcat=1.3.3
7 grails-app/conf/BootStrap.groovy
@@ -0,0 +1,7 @@
+class BootStrap {
+
+ def init = { servletContext ->
+ }
+ def destroy = {
+ }
+}
31 grails-app/conf/BuildConfig.groovy
@@ -0,0 +1,31 @@
+grails.project.class.dir = "target/classes"
+grails.project.test.class.dir = "target/test-classes"
+grails.project.test.reports.dir = "target/test-reports"
+//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 "warn" // log level of Ivy resolver, either 'error', 'warn', 'info', 'debug' or 'verbose'
+ repositories {
+ grailsPlugins()
+ grailsHome()
+ grailsCentral()
+
+ // uncomment the below to enable remote dependency resolution
+ // from public Maven repositories
+ //mavenLocal()
+ //mavenCentral()
+ //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.5'
+ }
+}
83 grails-app/conf/Config.groovy
@@ -0,0 +1,83 @@
+// 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'
+ ]
+// 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
+// whether to install the java.util.logging bridge for sl4j. Disable for AppEngine!
+grails.logging.jul.usebridge = true
+// packages to include in Spring bean scanning
+grails.spring.bean.packages = []
+
+// set per-environment serverURL stem for creating absolute links
+environments {
+ production {
+ grails.serverURL = "http://www.changeme.com"
+ }
+ development {
+ grails.serverURL = "http://localhost:8080/${appName}"
+ }
+ test {
+ grails.serverURL = "http://localhost:8080/${appName}"
+ }
+
+}
+
+// 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'
+
+ warn 'org.mortbay.log'
+}
32 grails-app/conf/DataSource.groovy
@@ -0,0 +1,32 @@
+dataSource {
+ pooled = true
+ driverClassName = "org.hsqldb.jdbcDriver"
+ username = "sa"
+ password = ""
+}
+hibernate {
+ cache.use_second_level_cache = true
+ cache.use_query_cache = true
+ cache.provider_class = 'net.sf.ehcache.hibernate.EhCacheProvider'
+}
+// environment specific settings
+environments {
+ development {
+ dataSource {
+ dbCreate = "create-drop" // one of 'create', 'create-drop','update'
+ url = "jdbc:hsqldb:mem:devDB"
+ }
+ }
+ test {
+ dataSource {
+ dbCreate = "update"
+ url = "jdbc:hsqldb:mem:testDb"
+ }
+ }
+ production {
+ dataSource {
+ dbCreate = "update"
+ url = "jdbc:hsqldb:file:prodDb;shutdown=true"
+ }
+ }
+}
13 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')
+ }
+}
3 grails-app/conf/spring/resources.groovy
@@ -0,0 +1,3 @@
+// Place your Spring DSL code here
+beans = {
+}
6 grails-app/controllers/blueprint/PlayerController.groovy
@@ -0,0 +1,6 @@
+package blueprint
+
+class PlayerController {
+
+ def scaffold = true
+}
12 grails-app/domain/blueprint/Player.groovy
@@ -0,0 +1,12 @@
+package blueprint
+
+class Player {
+ String firstName
+ String lastName
+ String email
+ Date joined
+ String password
+
+ static constraints = {
+ }
+}
55 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
56 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
+
55 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
30 grails-app/i18n/messages_es.properties
@@ -0,0 +1,30 @@
+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
+
+# 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
19 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
19 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
19 grails-app/i18n/messages_ja.properties
@@ -0,0 +1,19 @@
+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=次へ
55 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
34 grails-app/i18n/messages_pt_BR.properties
@@ -0,0 +1,34 @@
+#
+# 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
+
+# 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.
34 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.
31 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} не является допустимым числом
35 grails-app/i18n/messages_th.properties
@@ -0,0 +1,35 @@
+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
+
+# 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
18 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
54 grails-app/views/error.gsp
@@ -0,0 +1,54 @@
+<html>
+ <head>
+ <title>Grails Runtime Exception</title>
+ <style type="text/css">
+ .message {
+ border: 1px solid black;
+ padding: 5px;
+ background-color:#E9E9E9;
+ }
+ .stack {
+ border: 1px solid black;
+ padding: 5px;
+ overflow:auto;
+ height: 300px;
+ }
+ .snippet {
+ padding: 5px;
+ background-color:white;
+ border:1px solid black;
+ margin:3px;
+ font-family:courier;
+ }
+ </style>
+ </head>
+
+ <body>
+ <h1>Grails Runtime Exception</h1>
+ <h2>Error Details</h2>
+
+ <div class="message">
+ <strong>Error ${request.'javax.servlet.error.status_code'}:</strong> ${request.'javax.servlet.error.message'.encodeAsHTML()}<br/>
+ <strong>Servlet:</strong> ${request.'javax.servlet.error.servlet_name'}<br/>
+ <strong>URI:</strong> ${request.'javax.servlet.error.request_uri'}<br/>
+ <g:if test="${exception}">
+ <strong>Exception Message:</strong> ${exception.message?.encodeAsHTML()} <br />
+ <strong>Caused by:</strong> ${exception.cause?.message?.encodeAsHTML()} <br />
+ <strong>Class:</strong> ${exception.className} <br />
+ <strong>At Line:</strong> [${exception.lineNumber}] <br />
+ <strong>Code Snippet:</strong><br />
+ <div class="snippet">
+ <g:each var="cs" in="${exception.codeSnippet}">
+ ${cs?.encodeAsHTML()}<br />
+ </g:each>
+ </div>
+ </g:if>
+ </div>
+ <g:if test="${exception}">
+ <h2>Stack Trace</h2>
+ <div class="stack">
+ <pre><g:each in="${exception.stackTraceLines}">${it.encodeAsHTML()}<br/></g:each></pre>
+ </div>
+ </g:if>
+ </body>
+</html>
100 grails-app/views/index.gsp
@@ -0,0 +1,100 @@
+<html>
+ <head>
+ <title>Welcome to Grails</title>
+ <meta name="layout" content="main" />
+ <style type="text/css" media="screen">
+
+ #nav {
+ margin-top:20px;
+ margin-left:30px;
+ width:228px;
+ float:left;
+
+ }
+ .homePagePanel * {
+ margin:0px;
+ }
+ .homePagePanel .panelBody ul {
+ list-style-type:none;
+ margin-bottom:10px;
+ }
+ .homePagePanel .panelBody h1 {
+ text-transform:uppercase;
+ font-size:1.1em;
+ margin-bottom:10px;
+ }
+ .homePagePanel .panelBody {
+ background: url(images/leftnav_midstretch.png) repeat-y top;
+ margin:0px;
+ padding:15px;
+ }
+ .homePagePanel .panelBtm {
+ background: url(images/leftnav_btm.png) no-repeat top;
+ height:20px;
+ margin:0px;
+ }
+
+ .homePagePanel .panelTop {
+ background: url(images/leftnav_top.png) no-repeat top;
+ height:11px;
+ margin:0px;
+ }
+ h2 {
+ margin-top:15px;
+ margin-bottom:15px;
+ font-size:1.2em;
+ }
+ #pageBody {
+ margin-left:280px;
+ margin-right:20px;
+ }
+ </style>
+ </head>
+ <body>
+ <div id="nav">
+ <div class="homePagePanel">
+ <div class="panelTop"></div>
+ <div class="panelBody">
+ <h1>Application Status</h1>
+ <ul>
+ <li>App version: <g:meta name="app.version"></g:meta></li>
+ <li>Grails version: <g:meta name="app.grails.version"></g:meta></li>
+ <li>Groovy version: ${org.codehaus.groovy.runtime.InvokerHelper.getVersion()}</li>
+ <li>JVM version: ${System.getProperty('java.version')}</li>
+ <li>Controllers: ${grailsApplication.controllerClasses.size()}</li>
+ <li>Domains: ${grailsApplication.domainClasses.size()}</li>
+ <li>Services: ${grailsApplication.serviceClasses.size()}</li>
+ <li>Tag Libraries: ${grailsApplication.tagLibClasses.size()}</li>
+ </ul>
+ <h1>Installed Plugins</h1>
+ <ul>
+ <g:set var="pluginManager"
+ value="${applicationContext.getBean('pluginManager')}"></g:set>
+
+ <g:each var="plugin" in="${pluginManager.allPlugins}">
+ <li>${plugin.name} - ${plugin.version}</li>
+ </g:each>
+
+ </ul>
+ </div>
+ <div class="panelBtm"></div>
+ </div>
+ </div>
+ <div id="pageBody">
+ <h1>Welcome to Grails</h1>
+ <p>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:</p>
+
+ <div id="controllerList" class="dialog">
+ <h2>Available Controllers:</h2>
+ <ul>
+ <g:each var="c" in="${grailsApplication.controllerClasses.sort { it.fullName } }">
+ <li class="controller"><g:link controller="${c.logicalPropertyName}">${c.fullName}</g:link></li>
+ </g:each>
+ </ul>
+ </div>
+ </div>
+ </body>
+</html>
24 grails-app/views/layouts/main.gsp
@@ -0,0 +1,24 @@
+<html>
+<head>
+ <title><g:layoutTitle default="Grails"/></title>
+ <link rel="stylesheet" href="${resource(dir: 'css/blueprint', file: 'print.css')}" media="print"/>
+ <link rel="stylesheet" href="${resource(dir: 'css/blueprint', file: 'screen.css')}" media="screen, projection"/>
+ <!--[if lt IE 8]>
+ <link rel="stylesheet" href="${resource(dir: 'css/blueprint', file: 'ie.css')}" media="screen, projection"/>
+ <![endif]-->
+ <link rel="stylesheet" href="${resource(dir: 'css', file: 'application.css')}"/>
+ <link rel="shortcut icon" href="${resource(dir: 'images', file: 'favicon.ico')}" type="image/x-icon"/>
+ <g:layoutHead/>
+ <g:javascript library="application"/>
+</head>
+<body>
+
+<div class="container">
+ <div id="spinner" style="display:none;">
+ <img src="${resource(dir: 'images', file: 'spinner.gif')}" alt="${message(code: 'spinner.alt', default: 'Loading...')}"/>
+ </div>
+ <div id="grailsLogo"><a href="http://grails.org"><img src="${resource(dir: 'images', file: 'grails_logo.png')}" alt="Grails" border="0"/></a></div>
+ <g:layoutBody/>
+</div>
+</body>
+</html>
4 src/templates/artifacts/Controller.groovy
@@ -0,0 +1,4 @@
+@artifact.package@class @artifact.name@ {
+
+ def index = { }
+}
5 src/templates/artifacts/DomainClass.groovy
@@ -0,0 +1,5 @@
+@artifact.package@class @artifact.name@ {
+
+ static constraints = {
+ }
+}
17 src/templates/artifacts/Filters.groovy
@@ -0,0 +1,17 @@
+@artifact.package@class @artifact.name@ {
+
+ def filters = {
+ all(controller:'*', action:'*') {
+ before = {
+
+ }
+ after = {
+
+ }
+ afterView = {
+
+ }
+ }
+ }
+
+}
7 src/templates/artifacts/Script.groovy
@@ -0,0 +1,7 @@
+includeTargets << grailsScript("Init")
+
+target(main: "The description of the script goes here!") {
+ // TODO: Implement script here
+}
+
+setDefaultTarget(main)
8 src/templates/artifacts/Service.groovy
@@ -0,0 +1,8 @@
+@artifact.package@class @artifact.name@ {
+
+ static transactional = true
+
+ def serviceMethod() {
+
+ }
+}
3 src/templates/artifacts/TagLib.groovy
@@ -0,0 +1,3 @@
+@artifact.package@class @artifact.name@ {
+
+}
15 src/templates/artifacts/Tests.groovy
@@ -0,0 +1,15 @@
+@artifact.package@import grails.test.*
+
+class @artifact.name@ extends @artifact.superclass@ {
+ protected void setUp() {
+ super.setUp()
+ }
+
+ protected void tearDown() {
+ super.tearDown()
+ }
+
+ void testSomething() {
+
+ }
+}
54 src/templates/artifacts/WebTest.groovy
@@ -0,0 +1,54 @@
+class @webtest.name.caps@Test extends grails.util.WebTest {
+
+ // Unlike unit tests, functional tests are often sequence dependent.
+ // Specify that sequence here.
+ void suite() {
+ test@webtest.name.caps@ListNewDelete()
+ // add tests for more operations here
+ }
+
+ def test@webtest.name.caps@ListNewDelete() {
+ webtest('@webtest.name.caps@ basic operations: view list, create new entry, view, edit, delete, view') {
+ invoke(url:'@webtest.name.lower@')
+ verifyText(text:'Home')
+
+ verifyListPage(0)
+
+ clickLink(label:'New @webtest.name.caps@')
+ verifyText(text:'Create @webtest.name.caps@')
+ clickButton(label:'Create')
+ verifyText(text:'Show @webtest.name.caps@', description:'Detail page')
+ clickLink(label:'List', description:'Back to list view')
+
+ verifyListPage(1)
+
+ group(description:'edit the one element') {
+ clickLink(label:'Show', description:'go to detail view')
+ clickButton(label:'Edit')
+ verifyText(text:'Edit @webtest.name.caps@')
+ clickButton(label:'Update')
+ verifyText(text:'Show @webtest.name.caps@')
+ clickLink(label:'List', description:'Back to list view')
+ }
+
+ verifyListPage(1)
+
+ group(description:'delete the only element') {
+ clickLink(label:'Show', description:'go to detail view')
+ clickButton(label:'Delete')
+ verifyXPath(xpath:"//div[@class='message']", text:/@webtest.name.caps@.*deleted./, regex:true)
+ }
+
+ verifyListPage(0)
+ }
+ }
+
+ String ROW_COUNT_XPATH = "count(//td[@class='actionButtons']/..)"
+
+ def verifyListPage(int count) {
+ ant.group(description:"verify @webtest.name.caps@ list view with $count row(s)") {
+ verifyText(text:'@webtest.name.caps@ List')
+ verifyXPath(xpath:ROW_COUNT_XPATH, text:count, description:"$count row(s) of data expected")
+ }
+ }
+}
18 src/templates/artifacts/hibernate.cfg.xml
@@ -0,0 +1,18 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!DOCTYPE hibernate-configuration PUBLIC
+ '-//Hibernate/Hibernate Configuration DTD 3.0//EN'
+ 'http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd'>
+
+<hibernate-configuration>
+
+ <session-factory>
+ <!--
+ <mapping package='com.books' />
+
+ <mapping class='com.books.Book' />
+
+ <mapping resource='someresource.hbm.xml'/>
+ -->
+ </session-factory>
+
+</hibernate-configuration>
98 src/templates/scaffolding/Controller.groovy
@@ -0,0 +1,98 @@
+<%=packageName ? "package ${packageName}\n\n" : ''%>class ${className}Controller {
+
+ 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)
+ [${propertyName}List: ${className}.list(params), ${propertyName}Total: ${className}.count()]
+ }
+
+ def create = {
+ def ${propertyName} = new ${className}()
+ ${propertyName}.properties = params
+ return [${propertyName}: ${propertyName}]
+ }
+
+ def save = {
+ def ${propertyName} = new ${className}(params)
+ if (${propertyName}.save(flush: true)) {
+ flash.message = "\${message(code: 'default.created.message', args: [message(code: '${domainClass.propertyName}.label', default: '${className}'), ${propertyName}.id])}"
+ redirect(action: "show", id: ${propertyName}.id)
+ }
+ else {
+ render(view: "create", model: [${propertyName}: ${propertyName}])
+ }
+ }
+
+ def show = {
+ def ${propertyName} = ${className}.get(params.id)
+ if (!${propertyName}) {
+ flash.message = "\${message(code: 'default.not.found.message', args: [message(code: '${domainClass.propertyName}.label', default: '${className}'), params.id])}"
+ redirect(action: "list")
+ }
+ else {
+ [${propertyName}: ${propertyName}]
+ }
+ }
+
+ def edit = {
+ def ${propertyName} = ${className}.get(params.id)
+ if (!${propertyName}) {
+ flash.message = "\${message(code: 'default.not.found.message', args: [message(code: '${domainClass.propertyName}.label', default: '${className}'), params.id])}"
+ redirect(action: "list")
+ }
+ else {
+ return [${propertyName}: ${propertyName}]
+ }
+ }
+
+ def update = {
+ def ${propertyName} = ${className}.get(params.id)
+ if (${propertyName}) {
+ if (params.version) {
+ def version = params.version.toLong()
+ if (${propertyName}.version > version) {
+ <% def lowerCaseName = grails.util.GrailsNameUtils.getPropertyName(className) %>
+ ${propertyName}.errors.rejectValue("version", "default.optimistic.locking.failure", [message(code: '${domainClass.propertyName}.label', default: '${className}')] as Object[], "Another user has updated this ${className} while you were editing")
+ render(view: "edit", model: [${propertyName}: ${propertyName}])
+ return
+ }
+ }
+ ${propertyName}.properties = params
+ if (!${propertyName}.hasErrors() && ${propertyName}.save(flush: true)) {
+ flash.message = "\${message(code: 'default.updated.message', args: [message(code: '${domainClass.propertyName}.label', default: '${className}'), ${propertyName}.id])}"
+ redirect(action: "show", id: ${propertyName}.id)
+ }
+ else {
+ render(view: "edit", model: [${propertyName}: ${propertyName}])
+ }
+ }
+ else {
+ flash.message = "\${message(code: 'default.not.found.message', args: [message(code: '${domainClass.propertyName}.label', default: '${className}'), params.id])}"
+ redirect(action: "list")
+ }
+ }
+
+ def delete = {
+ def ${propertyName} = ${className}.get(params.id)
+ if (${propertyName}) {
+ try {
+ ${propertyName}.delete(flush: true)
+ flash.message = "\${message(code: 'default.deleted.message', args: [message(code: '${domainClass.propertyName}.label', default: '${className}'), params.id])}"
+ redirect(action: "list")
+ }
+ catch (org.springframework.dao.DataIntegrityViolationException e) {
+ flash.message = "\${message(code: 'default.not.deleted.message', args: [message(code: '${domainClass.propertyName}.label', default: '${className}'), params.id])}"
+ redirect(action: "show", id: params.id)
+ }
+ }
+ else {
+ flash.message = "\${message(code: 'default.not.found.message', args: [message(code: '${domainClass.propertyName}.label', default: '${className}'), params.id])}"
+ redirect(action: "list")
+ }
+ }
+}
65 src/templates/scaffolding/create.gsp
@@ -0,0 +1,65 @@
+<% import grails.persistence.Event %>
+<% import org.codehaus.groovy.grails.plugins.PluginManagerHolder %>
+<%=packageName%>
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+ <meta name="layout" content="main"/>
+ <g:set var="entityName" value="\${message(code: '${domainClass.propertyName}.label', default: '${className}')}"/>
+ <title><g:message code="default.create.label" args="[entityName]"/></title>
+</head>
+<body>
+<div class="span-24">
+ <a class="home" href="\${createLink(uri: '/')}"><g:message code="default.home.label"/></a>
+ <g:link class="list" action="list"><g:message code="default.list.label" args="[entityName]"/></g:link>
+</div>
+<div class="span-24">
+ <div class="span-12 append-12">
+ <g:if test="\${flash.message}">
+ <div class="success">\${flash.message}</div>
+ </g:if>
+ <g:hasErrors bean="\${${propertyName}}">
+ <div class="error">
+ <g:renderErrors bean="\${${propertyName}}" as="list"/>
+ </div>
+ </g:hasErrors>
+ </div>
+
+ <div class="span-12 append-12">
+ <g:form action="save" method="post" <%= multiPart ? ' enctype="multipart/form-data"' : '' %>>
+ <fieldset>
+ <legend><g:message code="default.create.label" args="[entityName]"/></legend>
+ <div class="span-10 append-2">
+ <% excludedProps = Event.allEvents.toList() << 'version' << 'id' << 'dateCreated' << 'lastUpdated'
+ props = domainClass.properties.findAll { !excludedProps.contains(it.name) }
+ Collections.sort(props, comparator.constructors[0].newInstance([domainClass] as Object[]))
+ display = true
+ boolean hasHibernate = PluginManagerHolder.pluginManager.hasGrailsPlugin('hibernate')
+ props.each {p ->
+ if (!Collection.class.isAssignableFrom(p.type)) {
+ if (hasHibernate) {
+ cp = domainClass.constrainedProperties[p.name]
+ display = (cp ? cp.display : true)
+ }
+ if (display) { %>
+ <p><label for="${p.name}"><g:message code="${domainClass.propertyName}.${p.name}.label" default="${p.naturalName}"/></label>
+ ${renderEditor(p)}</p>
+
+
+ <% }
+ }
+ } %>
+ </div>
+ <div class="span-9 first">
+ <button type="submit" name="create" id="create" value="\${message(code: 'default.button.create.label', default: 'Create')}">
+ \${message(code: 'default.button.create.label', default: 'Create')}
+ </button>
+
+ </div>
+
+ </fieldset>
+ </g:form>
+ </div>
+</div>
+</body>
+</html>
64 src/templates/scaffolding/edit.gsp
@@ -0,0 +1,64 @@
+<% import grails.persistence.Event %>
+<% import org.codehaus.groovy.grails.plugins.PluginManagerHolder %>
+<%=packageName%>
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+ <meta name="layout" content="main"/>
+ <g:set var="entityName" value="\${message(code: '${domainClass.propertyName}.label', default: '${className}')}"/>
+ <title><g:message code="default.edit.label" args="[entityName]"/></title>
+</head>
+<body>
+<div class="span-24">
+ <a class="home" href="\${createLink(uri: '/')}"><g:message code="default.home.label"/></a>
+ <g:link class="list" action="list"><g:message code="default.list.label" args="[entityName]"/></g:link>
+ <g:link class="create" action="create"><g:message code="default.new.label" args="[entityName]"/></g:link>
+</div>
+<div class="span-24">
+ <div class="span-12 append-12">
+ <g:if test="\${flash.message}">
+ <div class="success">\${flash.message}</div>
+ </g:if>
+ <g:hasErrors bean="\${${propertyName}}">
+ <div class="error">
+ <g:renderErrors bean="\${${propertyName}}" as="list"/>
+ </div>
+ </g:hasErrors>
+ </div>
+ <div class="span-12 append-12">
+ <g:form method="post" <%= multiPart ? ' enctype="multipart/form-data"' : '' %>>
+ <fieldset>
+ <legend><g:message code="default.edit.label" args="[entityName]"/></legend>
+ <div class="span-10">
+ <g:hiddenField name="id" value="\${${propertyName}?.id}"/>
+ <g:hiddenField name="version" value="\${${propertyName}?.version}"/>
+ <% excludedProps = Event.allEvents.toList() << 'version' << 'id' << 'dateCreated' << 'lastUpdated'
+ props = domainClass.properties.findAll { !excludedProps.contains(it.name) }
+ Collections.sort(props, comparator.constructors[0].newInstance([domainClass] as Object[]))
+ display = true
+ boolean hasHibernate = PluginManagerHolder.pluginManager.hasGrailsPlugin('hibernate')
+ props.each {p ->
+ if (hasHibernate) {
+ cp = domainClass.constrainedProperties[p.name]
+ display = (cp?.display ?: true)
+ }
+ if (display) { %>
+ <p><label for="${p.name}"><g:message code="${domainClass.propertyName}.${p.name}.label" default="${p.naturalName}"/></label>
+ ${renderEditor(p)}</p>
+ <% }
+ } %>
+ </div>
+ <div class="span-9 first">
+ <button type="submit" name="_action_delete" value="\${message(code: 'default.button.delete.label', default: 'Delete')}" onclick="return confirm('\${message(code: 'default.button.delete.confirm.message', default: 'Are you sure?')}');">
+ \${message(code: 'default.button.delete.label', default: 'Delete')}
+ </button>
+ <button type="submit" name="_action_update" value="\${message(code: 'default.button.update.label', default: 'Update')}">
+ \${message(code: 'default.button.update.label', default: 'Update')}
+ </button>
+ </div>
+ </fieldset>
+ </g:form>
+ </div>
+</div>
+</body>
+</html>
62 src/templates/scaffolding/list.gsp
@@ -0,0 +1,62 @@
+<% import grails.persistence.Event %>
+<%=packageName%>
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+ <meta name="layout" content="main"/>
+ <g:set var="entityName" value="\${message(code: '${domainClass.propertyName}.label', default: '${className}')}"/>
+ <title><g:message code="default.list.label" args="[entityName]"/></title>
+</head>
+<body>
+<div class="span-24">
+ <a class="home" href="\${createLink(uri: '/')}"><g:message code="default.home.label"/></a>
+ <g:link class="create" action="create"><g:message code="default.new.label" args="[entityName]"/></g:link>
+</div>
+<div class="span-14 append-10">
+ <h1><g:message code="default.list.label" args="[entityName]"/></h1>
+ <g:if test="\${flash.message}">
+ <div class="notice">\${flash.message}</div>
+ </g:if>
+ <table>
+ <thead>
+ <tr>
+ <% excludedProps = Event.allEvents.toList() << 'version'
+ props = domainClass.properties.findAll { !excludedProps.contains(it.name) && it.type != Set.class }
+ Collections.sort(props, comparator.constructors[0].newInstance([domainClass] as Object[]))
+ props.eachWithIndex {p, i ->
+ if (i < 6) {
+ if (p.isAssociation()) { %>
+ <th><g:message code="${domainClass.propertyName}.${p.name}.label" default="${p.naturalName}"/></th>
+ <% } else { %>
+ <g:sortableColumn property="${p.name}" title="\${message(code: '${domainClass.propertyName}.${p.name}.label', default: '${p.naturalName}')}"/>
+ <% }
+ }
+ } %>
+ </tr>
+ </thead>
+ <tbody>
+ <g:each in="\${${propertyName}List}" status="i" var="${propertyName}">
+ <tr class="\${(i % 2) == 0 ? 'odd' : 'even'}">
+ <% props.eachWithIndex {p, i ->
+ if (i == 0) { %>
+ <td><g:link action="show" id="\${${propertyName}.id}">\${fieldValue(bean: ${propertyName}, field: "${p.name}")}</g:link></td>
+ <% } else if (i < 6) {
+ if (p.type == Boolean.class || p.type == boolean.class) { %>
+ <td><g:formatBoolean boolean="\${${propertyName}.${p.name}}"/></td>
+ <% } else if (p.type == Date.class || p.type == java.sql.Date.class || p.type == java.sql.Time.class || p.type == Calendar.class) { %>
+ <td><g:formatDate date="\${${propertyName}.${p.name}}"/></td>
+ <% } else { %>
+ <td>\${fieldValue(bean: ${propertyName}, field: "${p.name}")}</td>
+ <% }
+ }
+ } %>
+ </tr>
+ </g:each>
+ </tbody>
+ </table>
+ <div>
+ <g:paginate total="\${${propertyName}Total}"/>
+ </div>
+</div>
+</body>
+</html>
171 src/templates/scaffolding/renderEditor.template
@@ -0,0 +1,171 @@
+<% if (property.type == Boolean.class || property.type == boolean.class)
+ out << renderBooleanEditor(domainClass, property)
+ else if (Number.class.isAssignableFrom(property.type) || (property.type.isPrimitive() && property.type != boolean.class))
+ out << renderNumberEditor(domainClass, property)
+ else if (property.type == String.class)
+ out << renderStringEditor(domainClass, property)
+ else if (property.type == Date.class || property.type == java.sql.Date.class || property.type == java.sql.Time.class || property.type == Calendar.class)
+ out << renderDateEditor(domainClass, property)
+ else if (property.type == URL.class)
+ out << renderStringEditor(domainClass, property)
+ else if (property.isEnum())
+ out << renderEnumEditor(domainClass, property)
+ else if (property.type == TimeZone.class)
+ out << renderSelectTypeEditor("timeZone", domainClass, property)
+ else if (property.type == Locale.class)
+ out << renderSelectTypeEditor("locale", domainClass, property)
+ else if (property.type == Currency.class)
+ out << renderSelectTypeEditor("currency", domainClass, property)
+ else if (property.type==([] as Byte[]).class) //TODO: Bug in groovy means i have to do this :(
+ out << renderByteArrayEditor(domainClass, property)
+ else if (property.type==([] as byte[]).class) //TODO: Bug in groovy means i have to do this :(
+ out << renderByteArrayEditor(domainClass, property)
+ else if (property.manyToOne || property.oneToOne)
+ out << renderManyToOne(domainClass, property)
+ else if ((property.oneToMany && !property.bidirectional) || (property.manyToMany && property.isOwningSide()))
+ out << renderManyToMany(domainClass, property)
+ else if (property.oneToMany)
+ out << renderOneToMany(domainClass, property)
+
+ private renderEnumEditor(domainClass, property) {
+ return "<g:select name=\"${property.name}\" from=\"\${${property.type.name}?.values()}\" value=\"\${${domainInstance}?.${property.name}}\" ${renderNoSelection(property)} />"
+ }
+
+ private renderStringEditor(domainClass, property) {
+ if (!cp) {
+ return "<g:textField name=\"${property.name}\" value=\"\${${domainInstance}?.${property.name}}\" />"
+ }
+ else {
+ if ("textarea" == cp.widget || (cp.maxSize > 250 && !cp.password && !cp.inList)) {
+ return "<g:textArea name=\"${property.name}\" cols=\"40\" rows=\"5\" value=\"\${${domainInstance}?.${property.name}}\" />"
+ }
+ else {
+ if (cp.inList) {
+ return "<g:select name=\"${property.name}\" from=\"\${${domainInstance}.constraints.${property.name}.inList}\" value=\"\${${domainInstance}?.${property.name}}\" valueMessagePrefix=\"${domainClass.propertyName}.${property?.name}\" ${renderNoSelection(property)} />"
+ }
+ else {
+ def sb = new StringBuffer("<g:")
+ cp.password ? sb << "passwordField " : sb << "textField "
+ sb << "name=\"${property.name}\" "
+ if (cp.maxSize) sb << "maxlength=\"${cp.maxSize}\" "
+ if (!cp.editable) sb << "readonly=\"readonly\" "
+ sb << "value=\"\${${domainInstance}?.${property.name}}\" />"
+ return sb.toString()
+ }
+ }
+ }
+ }
+
+ private renderByteArrayEditor(domainClass, property) {
+ return "<input type=\"file\" id=\"${property.name}\" name=\"${property.name}\" />"
+ }
+
+ private renderManyToOne(domainClass,property) {
+ if (property.association) {
+ return "<g:select name=\"${property.name}.id\" from=\"\${${property.type.name}.list()}\" optionKey=\"id\" value=\"\${${domainInstance}?.${property.name}?.id}\" ${renderNoSelection(property)} />"
+ }
+ }
+
+ private renderManyToMany(domainClass, property) {
+ return "<g:select name=\"${property.name}\" from=\"\${${property.referencedDomainClass.fullName}.list()}\" multiple=\"yes\" optionKey=\"id\" size=\"5\" value=\"\${${domainInstance}?.${property.name}*.id}\" />"
+ }
+
+ private renderOneToMany(domainClass, property) {
+ def sw = new StringWriter()
+ def pw = new PrintWriter(sw)
+ pw.println()
+ pw.println "<ul>"
+ pw.println "<g:each in=\"\${${domainInstance}?.${property.name}?}\" var=\"${property.name[0]}\">"
+ pw.println " <li><g:link controller=\"${property.referencedDomainClass.propertyName}\" action=\"show\" id=\"\${${property.name[0]}.id}\">\${${property.name[0]}?.encodeAsHTML()}</g:link></li>"
+ pw.println "</g:each>"
+ pw.println "</ul>"
+ pw.println "<g:link controller=\"${property.referencedDomainClass.propertyName}\" action=\"create\" params=\"['${domainClass.propertyName}.id': ${domainInstance}?.id]\">\${message(code: 'default.add.label', args: [message(code: '${property.referencedDomainClass.propertyName}.label', default: '${property.referencedDomainClass.shortName}')])}</g:link>"
+ return sw.toString()
+ }
+
+ private renderNumberEditor(domainClass, property) {
+ if (!cp) {
+ if (property.type == Byte.class) {
+ return "<g:select name=\"${property.name}\" from=\"\${-128..127}\" value=\"\${fieldValue(bean: ${domainInstance}, field: '${property.name}')}\" />"
+ }
+ else {
+ return "<g:textField name=\"${property.name}\" value=\"\${fieldValue(bean: ${domainInstance}, field: '${property.name}')}\" />"
+ }
+ }
+ else {
+ if (cp.range) {
+ return "<g:select name=\"${property.name}\" from=\"\${${cp.range.from}..${cp.range.to}}\" value=\"\${fieldValue(bean: ${domainInstance}, field: '${property.name}')}\" ${renderNoSelection(property)} />"
+ }
+ else if (cp.inList) {
+ return "<g:select name=\"${property.name}\" from=\"\${${domainInstance}.constraints.${property.name}.inList}\" value=\"\${fieldValue(bean: ${domainInstance}, field: '${property.name}')}\" valueMessagePrefix=\"${domainClass.propertyName}.${property?.name}\" ${renderNoSelection(property)} />"
+ }
+ else {
+ return "<g:textField name=\"${property.name}\" value=\"\${fieldValue(bean: ${domainInstance}, field: '${property.name}')}\" />"
+ }
+ }
+ }
+
+ private renderBooleanEditor(domainClass, property) {
+ if (!cp) {
+ return "<g:checkBox name=\"${property.name}\" value=\"\${${domainInstance}?.${property.name}}\" />"
+ }
+ else {
+ def sb = new StringBuffer("<g:checkBox name=\"${property.name}\" ")
+ if (cp.widget) sb << "widget=\"${cp.widget}\" ";
+ cp.attributes.each { k, v ->
+ sb << "${k}=\"${v}\" "
+ }
+ sb << "value=\"\${${domainInstance}?.${property.name}}\" />"
+ return sb.toString()
+ }
+ }
+
+ private renderDateEditor(domainClass, property) {
+ def precision = (property.type == Date.class || property.type == java.sql.Date.class || property.type == Calendar.class) ? "day" : "minute";
+ if (!cp) {
+ return "<g:datePicker name=\"${property.name}\" precision=\"${precision}\" value=\"\${${domainInstance}?.${property.name}}\" />"
+ }
+ else {
+ if (!cp.editable) {
+ return "\${${domainInstance}?.${property.name}?.toString()}"
+ }
+ else {
+ def sb = new StringBuffer("<g:datePicker name=\"${property.name}\" ")
+ if (cp.format) sb << "format=\"${cp.format}\" "
+ if (cp.widget) sb << "widget=\"${cp.widget}\" "
+ cp.attributes.each { k, v ->
+ sb << "${k}=\"${v}\" "
+ }
+ sb << "precision=\"${precision}\" value=\"\${${domainInstance}?.${property.name}}\" ${renderNoSelection(property)} />"
+ return sb.toString()
+ }
+ }
+ }
+
+ private renderSelectTypeEditor(type, domainClass,property) {
+ if (!cp) {
+ return "<g:${type}Select name=\"${property.name}\" value=\"\${${domainInstance}?.${property.name}}\" />"
+ }
+ else {
+ def sb = new StringBuffer("<g:${type}Select name=\"${property.name}\" ")
+ if (cp.widget) sb << "widget=\"${cp.widget}\" ";
+ cp.attributes.each { k, v ->
+ sb << "${k}=\"${v}\" "
+ }
+ sb << "value=\"\${${domainInstance}?.${property.name}}\" ${renderNoSelection(property)} />"
+ return sb.toString()
+ }
+ }
+
+ private renderNoSelection(property) {
+ if (property.optional) {
+ if (property.manyToOne || property.oneToOne) {
+ return "noSelection=\"['null': '']\""
+ }
+ else {
+ return "noSelection=\"['': '']\""
+ }
+ }
+ return ""
+ }
+%>
66 src/templates/scaffolding/show.gsp
@@ -0,0 +1,66 @@
+<% import grails.persistence.Event %>
+<%=packageName%>
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+ <meta name="layout" content="main"/>
+ <g:set var="entityName" value="\${message(code: '${domainClass.propertyName}.label', default: '${className}')}"/>
+ <title><g:message code="default.show.label" args="[entityName]"/></title>
+</head>
+<body>
+<div class="span-24">
+ <a class="home" href="\${createLink(uri: '/')}"><g:message code="default.home.label"/></a>
+ <g:link class="list" action="list"><g:message code="default.list.label" args="[entityName]"/></g:link>
+ <g:link class="create" action="create"><g:message code="default.new.label" args="[entityName]"/></g:link>
+</div>
+<div class="span-12 append-12">
+ <g:if test="\${flash.message}">
+ <div class="notice">\${flash.message}</div>
+ </g:if>
+ <div class="span-12 append-12">
+
+ <fieldset>
+ <legend><g:message code="default.show.label" args="[entityName]"/></legend>
+ <div class="span-10">
+ <% excludedProps = Event.allEvents.toList() << 'version'
+ props = domainClass.properties.findAll { !excludedProps.contains(it.name) }
+ Collections.sort(props, comparator.constructors[0].newInstance([domainClass] as Object[]))
+ props.each {p -> %>
+ <p><strong><g:message code="${domainClass.propertyName}.${p.name}.label" default="${p.naturalName}"/></strong>:&nbsp;
+ <% if (p.isEnum()) { %>
+ \${${propertyName}?.${p.name}?.encodeAsHTML()}
+ <% } else if (p.oneToMany || p.manyToMany) { %>
+
+ <ul>
+ <g:each in="\${${propertyName}.${p.name}}" var="${p.name[0]}">
+ <li><g:link controller="${p.referencedDomainClass?.propertyName}" action="show" id="\${${p.name[0]}.id}">\${${p.name[0]}?.encodeAsHTML()}</g:link></li>
+ </g:each>
+ </ul>
+ <% } else if (p.manyToOne || p.oneToOne) { %>
+ <g:link controller="${p.referencedDomainClass?.propertyName}" action="show" id="\${${propertyName}?.${p.name}?.id}">\${${propertyName}?.${p.name}?.encodeAsHTML()}</g:link>
+ <% } else if (p.type == Boolean.class || p.type == boolean.class) { %>
+ <g:formatBoolean boolean="\${${propertyName}?.${p.name}}"/>
+ <% } else if (p.type == Date.class || p.type == java.sql.Date.class || p.type == java.sql.Time.class || p.type == Calendar.class) { %>
+ <g:formatDate date="\${${propertyName}?.${p.name}}"/>
+ <% } else { %>
+ \${fieldValue(bean: ${propertyName}, field: "${p.name}")}
+ <% } %>
+ </p>
+ <% } %>
+ </div>
+ <g:form>
+ <g:hiddenField name="id" value="\${${propertyName}?.id}"/>
+ <div class="span-9 first">
+ <button type="submit" name="_action_delete" value="\${message(code: 'default.button.delete.label', default: 'Delete')}" onclick="return confirm('\${message(code: 'default.button.delete.confirm.message', default: 'Are you sure?')}');">
+ \${message(code: 'default.button.delete.label', default: 'Delete')}
+ </button>
+ <button type="submit" name="_action_edit" value="\${message(code: 'default.button.edit.label', default: 'Edit')}">
+ \${message(code: 'default.button.edit.label', default: 'Edit')}
+ </button>
+ </div>
+ </g:form>
+ </fieldset>
+ </div>
+</div>
+</body>
+</html>
102 src/templates/war/web.xml
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app version="2.4"
+ xmlns="http://java.sun.com/xml/ns/j2ee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
+ <display-name>/@grails.project.key@</display-name>
+
+
+ <context-param>
+ <param-name>contextConfigLocation</param-name>
+ <param-value>/WEB-INF/applicationContext.xml</param-value>
+ </context-param>
+
+ <context-param>
+ <param-name>webAppRootKey</param-name>
+ <param-value>@grails.project.key@</param-value>
+ </context-param>
+
+ <filter>
+ <filter-name>sitemesh</filter-name>
+ <filter-class>org.codehaus.groovy.grails.web.sitemesh.GrailsPageFilter</filter-class>
+ </filter>
+
+ <filter>
+ <filter-name>charEncodingFilter</filter-name>
+ <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
+ <init-param>
+ <param-name>targetBeanName</param-name>
+ <param-value>characterEncodingFilter</param-value>
+ </init-param>
+ <init-param>
+ <param-name>targetFilterLifecycle</param-name>
+ <param-value>true</param-value>
+ </init-param>
+ </filter>
+
+ <filter-mapping>
+ <filter-name>charEncodingFilter</filter-name>
+ <url-pattern>/*</url-pattern>
+ </filter-mapping>
+
+ <filter-mapping>
+ <filter-name>sitemesh</filter-name>
+ <url-pattern>/*</url-pattern>
+ </filter-mapping>
+
+ <listener>
+ <listener-class>org.codehaus.groovy.grails.web.util.Log4jConfigListener</listener-class>
+ </listener>
+
+ <listener>
+ <listener-class>org.codehaus.groovy.grails.web.context.GrailsContextLoaderListener</listener-class>
+ </listener>
+
+ <!-- Grails dispatcher servlet -->
+ <servlet>
+ <servlet-name>grails</servlet-name>
+ <servlet-class>org.codehaus.groovy.grails.web.servlet.GrailsDispatcherServlet</servlet-class>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+
+ <!-- The Groovy Server Pages servlet -->
+ <servlet>
+ <servlet-name>gsp</servlet-name>
+ <servlet-class>org.codehaus.groovy.grails.web.pages.GroovyPagesServlet</servlet-class>
+ </servlet>
+
+ <servlet-mapping>
+ <servlet-name>gsp</servlet-name>
+ <url-pattern>*.gsp</url-pattern>
+ </servlet-mapping>
+
+ <welcome-file-list>
+ <!--
+ The order of the welcome pages is important. JBoss deployment will
+ break if index.gsp is first in the list.
+ -->
+ <welcome-file>index.html</welcome-file>
+ <welcome-file>index.jsp</welcome-file>
+ <welcome-file>index.gsp</welcome-file>
+ </welcome-file-list>
+
+ <jsp-config>
+ <taglib>
+ <taglib-uri>http://java.sun.com/jsp/jstl/core</taglib-uri>
+ <taglib-location>/WEB-INF/tld/c.tld</taglib-location>
+ </taglib>
+ <taglib>
+ <taglib-uri>http://java.sun.com/jsp/jstl/fmt</taglib-uri>
+ <taglib-location>/WEB-INF/tld/fmt.tld</taglib-location>
+ </taglib>
+ <taglib>
+ <taglib-uri>http://www.springframework.org/tags</taglib-uri>
+ <taglib-location>/WEB-INF/tld/spring.tld</taglib-location>
+ </taglib>
+ <taglib>
+ <taglib-uri>http://grails.codehaus.org/tags</taglib-uri>
+ <taglib-location>/WEB-INF/tld/grails.tld</taglib-location>
+ </taglib>
+ </jsp-config>
+
+</web-app>
17 test/unit/blueprint/PlayerControllerTests.groovy
@@ -0,0 +1,17 @@
+package blueprint
+
+import grails.test.*
+
+class PlayerControllerTests extends ControllerUnitTestCase {
+ protected void setUp() {
+ super.setUp()
+ }
+
+ protected void tearDown() {
+ super.tearDown()
+ }
+
+ void testSomething() {
+
+ }
+}
17 test/unit/blueprint/PlayerTests.groovy
@@ -0,0 +1,17 @@
+package blueprint
+
+import grails.test.*
+
+class PlayerTests extends GrailsUnitTestCase {
+ protected void setUp() {
+ super.setUp()
+ }
+
+ protected void tearDown() {
+ super.tearDown()
+ }
+
+ void testSomething() {
+
+ }
+}
42 web-app/WEB-INF/applicationContext.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="
+http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
+
+ <bean id="grailsApplication" class="org.codehaus.groovy.grails.commons.GrailsApplicationFactoryBean">
+ <description>Grails application factory bean</description>
+ <property name="grailsDescriptor" value="/WEB-INF/grails.xml" />
+ <property name="grailsResourceLoader" ref="grailsResourceLoader" />
+ </bean>
+
+ <bean id="pluginManager" class="org.codehaus.groovy.grails.plugins.GrailsPluginManagerFactoryBean">
+ <description>A bean that manages Grails plugins</description>
+ <property name="grailsDescriptor" value="/WEB-INF/grails.xml" />
+ <property name="application" ref="grailsApplication" />
+ </bean>
+
+ <bean id="grailsConfigurator" class="org.codehaus.groovy.grails.commons.spring.GrailsRuntimeConfigurator">
+ <constructor-arg>
+ <ref bean="grailsApplication" />
+ </constructor-arg>
+ <property name="pluginManager" ref="pluginManager" />
+ </bean>
+
+ <bean id="grailsResourceLoader" class="org.codehaus.groovy.grails.commons.GrailsResourceLoaderFactoryBean">
+ <property name="grailsResourceHolder" ref="grailsResourceHolder" />
+ </bean>
+
+ <bean id="grailsResourceHolder" scope="prototype" class="org.codehaus.groovy.grails.commons.spring.GrailsResourceHolder">
+ <property name="resources">
+ <value>classpath*:**/grails-app/**/*.groovy</value>
+ </property>
+ </bean>
+
+ <bean id="characterEncodingFilter"
+ class="org.springframework.web.filter.CharacterEncodingFilter">
+ <property name="encoding">
+ <value>utf-8</value>
+ </property>
+ </bean>
+</beans>
14 web-app/WEB-INF/sitemesh.xml
@@ -0,0 +1,14 @@
+<sitemesh>
+ <page-parsers>
+ <parser content-type="text/html"
+ class="org.codehaus.groovy.grails.web.sitemesh.GrailsHTMLPageParser" />
+ <parser content-type="text/html;charset=ISO-8859-1"
+ class="org.codehaus.groovy.grails.web.sitemesh.GrailsHTMLPageParser" />
+ <parser content-type="text/html;charset=UTF-8"
+ class="org.codehaus.groovy.grails.web.sitemesh.GrailsHTMLPageParser" />
+ </page-parsers>
+
+ <decorator-mappers>
+ <mapper class="org.codehaus.groovy.grails.web.sitemesh.GrailsLayoutDecoratorMapper" />
+ </decorator-mappers>
+</sitemesh>
563 web-app/WEB-INF/tld/c.tld
@@ -0,0 +1,563 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
+ version="2.0">
+
+ <description>JSTL 1.1 core library</description>
+ <display-name>JSTL core</display-name>
+ <tlib-version>1.1</tlib-version>
+ <short-name>c</short-name>
+ <uri>http://java.sun.com/jsp/jstl/core</uri>
+
+ <validator>
+ <description>
+ Provides core validation features for JSTL tags.
+ </description>
+ <validator-class>
+ org.apache.taglibs.standard.tlv.JstlCoreTLV
+ </validator-class>
+ </validator>
+
+ <tag>
+ <description>
+ Catches any Throwable that occurs in its body and optionally
+ exposes it.
+ </description>
+ <name>catch</name>
+ <tag-class>org.apache.taglibs.standard.tag.common.core.CatchTag</tag-class>
+ <body-content>JSP</body-content>
+ <attribute>
+ <description>
+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.
+ </description>
+ <name>var</name>
+ <required>false</required>
+ <rtexprvalue>false</rtexprvalue>
+ </attribute>
+ </tag>
+
+ <tag>
+ <description>
+ Simple conditional tag that establishes a context for
+ mutually exclusive conditional operations, marked by
+ &lt;when&gt; and &lt;otherwise&gt;
+ </description>
+ <name>choose</name>
+ <tag-class>org.apache.taglibs.standard.tag.common.core.ChooseTag</tag-class>
+ <body-content>JSP</body-content>
+ </tag>
+
+ <tag>
+ <description>
+ 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
+ </description>
+ <name>if</name>
+ <tag-class>org.apache.taglibs.standard.tag.rt.core.IfTag</tag-class>
+ <body-content>JSP</body-content>
+ <attribute>
+ <description>
+The test condition that determines whether or
+not the body content should be processed.
+ </description>
+ <name>test</name>
+ <required>true</required>
+ <rtexprvalue>true</rtexprvalue>
+ <type>boolean</type>
+ </attribute>
+ <attribute>
+ <description>
+Name of the exported scoped variable for the
+resulting value of the test condition. The type
+of the scoped variable is Boolean.
+ </description>
+ <name>var</name>
+ <required>false</required>
+ <rtexprvalue>false</rtexprvalue>
+ </attribute>
+ <attribute>
+ <description>
+Scope for var.
+ </description>
+ <name>scope</name>
+ <required>false</required>
+ <rtexprvalue>false</rtexprvalue>
+ </attribute>
+ </tag>
+
+ <tag>
+ <description>
+ Retrieves an absolute or relative URL and exposes its contents
+ to either the page, a String in 'var', or a Reader in 'varReader'.
+ </description>
+ <name>import</name>
+ <tag-class>org.apache.taglibs.standard.tag.rt.core.ImportTag</tag-class>
+ <tei-class>org.apache.taglibs.standard.tei.ImportTEI</tei-class>
+ <body-content>JSP</body-content>
+ <attribute>
+ <description>
+The URL of the resource to import.
+ </description>
+ <name>url</name>
+ <required>true</required>
+ <rtexprvalue>true</rtexprvalue>
+ </attribute>
+ <attribute>
+ <description>
+Name of the exported scoped variable for the
+resource's content. The type of the scoped
+variable is String.
+ </description>
+ <name>var</name>
+ <required>false</required>
+ <rtexprvalue>false</rtexprvalue>
+ </attribute>
+ <attribute>
+ <description>
+Scope for var.
+ </description>
+ <name>scope</name>
+ <required>false</required>
+ <rtexprvalue>false</rtexprvalue>
+ </attribute>
+ <attribute>
+ <description>
+Name of the exported scoped variable for the
+resource's content. The type of the scoped
+variable is Reader.
+ </description>
+ <name>varReader</name>
+ <required>false</required>
+ <rtexprvalue>false</rtexprvalue>
+ </attribute>
+ <attribute>
+ <description>
+Name of the context when accessing a relative
+URL resource that belongs to a foreign
+context.
+ </description>
+ <name>context</name>
+ <required>false</required>
+ <rtexprvalue>true</rtexprvalue>
+ </attribute>
+ <attribute>
+ <description>
+Character encoding of the content at the input
+resource.
+ </description>
+ <name>charEncoding</name>
+ <required>false</required>
+ <rtexprvalue>true</rtexprvalue>
+ </attribute>
+ </tag>
+
+ <tag>
+ <description>
+ The basic iteration tag, accepting many different
+ collection types and supporting subsetting and other
+ functionality
+ </description>
+ <name>forEach</name>
+ <tag-class>org.apache.taglibs.standard.tag.rt.core.ForEachTag</tag-class>
+ <tei-class>org.apache.taglibs.standard.tei.ForEachTEI</tei-class>
+ <body-content>JSP</body-content>
+ <attribute>
+ <description>
+Collection of items to iterate over.
+ </description>
+ <name>items</name>
+ <required>false</required>
+ <rtexprvalue>true</rtexprvalue>
+ <type>java.lang.Object</type>
+ </attribute>
+ <attribute>
+ <description>
+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