From b61e86f0e5e309a96cfc00046bd8a2ac801eaa86 Mon Sep 17 00:00:00 2001 From: Kazuki YAMAMOTO Date: Wed, 3 Jul 2013 00:51:40 +0900 Subject: [PATCH 001/230] remove duplicate content --- src/en/guide/webServices/REST/binding.gdoc | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/en/guide/webServices/REST/binding.gdoc b/src/en/guide/webServices/REST/binding.gdoc index 53396e1cc04..dafbb810a25 100644 --- a/src/en/guide/webServices/REST/binding.gdoc +++ b/src/en/guide/webServices/REST/binding.gdoc @@ -20,16 +20,6 @@ class BookController { } {code} -If the root element of the XML document contains an @id@ attribute, the @id@ value will be used to retrieve the corresponding persistent instance from the database and then the rest of the document will be bound to the instance. If no corresponding record is found in the database, the command object reference will be null. - -{code} - - - The Stand - Stephen King - -{code} - Command objects will automatically be bound with the body of the request: {code:java} From 6f8cad42e72d213a8bba2e37bb6253aa3ce269d1 Mon Sep 17 00:00:00 2001 From: Jeff Scott Brown Date: Mon, 30 Jun 2014 10:13:34 -0500 Subject: [PATCH 002/230] Use Grails 2.4.3.BUILD-SNAPSHOT --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 0a0552bb40e..b06d7990921 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,6 @@ apply plugin: "base" -version = System.getProperty("grails.version") ?: "2.4.2.BUILD-SNAPSHOT" +version = System.getProperty("grails.version") ?: "2.4.3.BUILD-SNAPSHOT" archivesBaseName = "grails-docs" @@ -22,7 +22,7 @@ buildscript { } dependencies { - classpath "org.grails:grails-docs:2.4.2.BUILD-SNAPSHOT" + classpath "org.grails:grails-docs:2.4.3.BUILD-SNAPSHOT" classpath 'org.codehaus.groovy:groovy-all:2.3.0' } } From 60a9fd375c9e0f53d0dfefdf590c9511824aee9d Mon Sep 17 00:00:00 2001 From: Graeme Rocher Date: Thu, 3 Jul 2014 11:57:13 +0200 Subject: [PATCH 003/230] improve docs on authentication for Aether repos --- src/en/guide/conf/dependencyResolution.gdoc | 7 +- .../configurationsAndDependencies.gdoc | 19 ++-- .../dependencyRepositories.gdoc | 98 ++++--------------- 3 files changed, 32 insertions(+), 92 deletions(-) diff --git a/src/en/guide/conf/dependencyResolution.gdoc b/src/en/guide/conf/dependencyResolution.gdoc index 49d2adbc78c..4333a4c6cd1 100644 --- a/src/en/guide/conf/dependencyResolution.gdoc +++ b/src/en/guide/conf/dependencyResolution.gdoc @@ -1,6 +1,10 @@ Grails features a dependency resolution DSL that lets you control how plugins and JAR dependencies are resolved. -You can choose to use Aether (since Grails 2.3) or Apache Ivy as the dependency resolution engine. Aether is the dependency resolution library used by the Maven build tool, so if you are looking for Maven-like behavior then Aether is the better choise. Ivy allows more flexibility if you wish to resolve jars from flat file systems or none HTTP repositories. Aether is the default dependency resolution engine for Grails applications since Grails 2.3. +You can choose to use Aether (since Grails 2.3) or Apache Ivy as the dependency resolution engine. Aether is the dependency resolution library used by the Maven build tool, so if you are looking for Maven-like behavior then Aether is the better choise. Ivy allows more flexibility if you wish to resolve jars from flat file systems or none HTTP repositories. Aether is the default dependency resolution engine for Grails applications since Grails 2.3. + +{warning} +As of Grails 2.4 the Ivy resolver is considered deprecated and no longer maintained. It is recommended all users switch to using Aether. +{warning} To configure which dependency resolution engine to use you can specify the @grails.project.dependency.resolver@ setting in @grails-app/conf/BuildConfig.groovy@. The default setting is shown below: @@ -79,4 +83,3 @@ grails.project.dependency.resolution = { {code} The details of the above will be explained in the next few sections. - diff --git a/src/en/guide/conf/dependencyResolution/configurationsAndDependencies.gdoc b/src/en/guide/conf/dependencyResolution/configurationsAndDependencies.gdoc index 7df6281dc3b..ec4690a5616 100644 --- a/src/en/guide/conf/dependencyResolution/configurationsAndDependencies.gdoc +++ b/src/en/guide/conf/dependencyResolution/configurationsAndDependencies.gdoc @@ -5,6 +5,7 @@ Grails features five dependency resolution configurations (or 'scopes'): * @runtime@: Dependencies needed at runtime but not for compilation (see above) * @test@: Dependencies needed for testing but not at runtime (see above) * @provided@: Dependencies needed at development time, but not during WAR deployment +* @optional@ (Aether only): Dependencies considered optional and not required for the execution of the application or plugin Within the @dependencies@ block you can specify a dependency that falls into one of these configurations by calling the equivalent method. For example if your application requires the MySQL driver to function at @runtime@ you can specify that like this: @@ -12,7 +13,7 @@ Within the @dependencies@ block you can specify a dependency that falls into one runtime 'com.mysql:mysql-connector-java:5.1.16' {code} -This uses the string syntax: @group:name:version@. +This uses the string syntax: @group:name:version@. If you are using Aether as the dependency resolution library, the Maven pattern of: @@ -72,10 +73,6 @@ runtime group:'com.mysql', transitive:false {code} -{warning} -Disabling transitive dependency resolution only works with the Ivy dependency manager. Aether does not support disabling of transitive resolution, instead explicit exclusions are required (see below). -{warning} - h3. Excluding specific transitive dependencies A far more common scenario is where you want the transitive dependencies, but some of them cause issues with your own dependencies or are unnecessary. For example, many Apache projects have 'commons-logging' as a transitive dependency, but it shouldn't be included in a Grails project (we use SLF4J). That's where the @excludes@ option comes in: @@ -102,17 +99,19 @@ runtime('com.mysql:mysql-connector-java:5.1.16', } {code} -h3. Using Ivy module configurations +h3. Dependency Management (Aether Only) + +If you are using Aether then you can take advantage of Maven's notion of [Dependency Management|http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Dependency_Management]. -Using the Ivy dependency manager (Aether not supported), if you use Ivy module configurations and wish to depend on a specific configuration of a module, you can use the @dependencyConfiguration@ method to specify the configuration to use. +To do so you use a @management@ block, for example: {code} -provided("my.org:web-service:1.0") { - dependencyConfiguration "api" +management { + dependency "commons-logging:commons-logging:1.1.3" } {code} -If the dependency configuration is not explicitly set, the configuration named @"default"@ will be used (which is also the correct value for dependencies coming from Maven style repositories). +The above declaration will force all any transitive dependencies on @commons-logging@ to use the 1.1.3 version without you having to declare an explicit dependency on @commons-logging@ yourself. In addition to the version, you can also control the scope and exclusion rules of a dependency. h3. Where are the JARs? diff --git a/src/en/guide/conf/dependencyResolution/dependencyRepositories.gdoc b/src/en/guide/conf/dependencyResolution/dependencyRepositories.gdoc index 0ba5e21f782..f06c3d91681 100644 --- a/src/en/guide/conf/dependencyResolution/dependencyRepositories.gdoc +++ b/src/en/guide/conf/dependencyResolution/dependencyRepositories.gdoc @@ -8,7 +8,7 @@ repositories { } {code} -In this case the default public Maven repository is specified. +In this case the default public Maven repository is specified. You can also specify a specific Maven repository to use by URL: @@ -28,20 +28,6 @@ repositories { so that you can easily identify it in logs. -h4. Controlling Repositories Inherited from Plugins - -A plugin you have installed may define a reference to a remote repository just as an application can. By default your application will inherit this repository definition when you install the plugin. - -If you do not wish to inherit repository definitions from plugins then you can disable repository inheritance: - -{code:java} -repositories { - inherit false -} -{code} - -In this case your application will not inherit any repository definitions from plugins and it is down to you to provide appropriate (possibly internal) repository definitions. - h4. Offline Mode There are times when it is not desirable to connect to any remote repositories (whilst working on the train for example!). In this case you can use the @offline@ flag to execute Grails commands and Grails will not connect to any remote repositories: @@ -51,7 +37,7 @@ grails --offline run-app {code} {note} -Note that this command will fail if you do not have the necessary dependencies in your local Ivy cache +Note that this command will fail if you do not have the necessary dependencies in your local Maven cache {note} You can also globally configure offline mode by setting @grails.offline.mode@ to @true@ in @~/.grails/settings.groovy@ or in your project's @BuildConfig.groovy@ file: @@ -60,20 +46,6 @@ You can also globally configure offline mode by setting @grails.offline.mode@ to grails.offline.mode=true {code} -h4. Local Resolvers - -If you do not wish to use a public Maven repository you can specify a flat file repository: - -{code} -repositories { - flatDir name:'myRepo', dirs:'/path/to/repo' -} -{code} - -{warning} -Aether does not support the @flatDir@ resolver or any custom file system resolvers. The above feature works only if you are using the Ivy dependency manager. -{warning} - To specify your local Maven cache (@~/.m2/repository@) as a repository: {code} @@ -82,69 +54,35 @@ repositories { } {code} -h4. Custom Resolvers +h4. Authentication with Aether -If you are using the Ivy dependency manager (Aether does not support custom resolvers), then you can explicitly specify an Ivy resolver: +To authenticate with Aether you can either define the credentials on the repository definition: {code} -/* - * Configure our resolver. - */ -def libResolver = new org.apache.ivy.plugins.resolver.URLResolver() -['libraries', 'builds'].each { - - libResolver.addArtifactPattern( - "http://my.repository/\${it}/" + - "[organisation]/[module]/[revision]/[type]s/[artifact].[ext]") - - libResolver.addIvyPattern( - "http://my.repository/\${it}/" + - "[organisation]/[module]/[revision]/[type]s/[artifact].[ext]") +mavenRepo(url:"http://localhost:8082/myrepo") { + auth username: "foo", password: "bar" } +{code} -libResolver.name = "my-repository" -libResolver.settings = ivySettings +Or you can specify an @id@ on the repository: -resolver libResolver {code} - -It's also possible to pull dependencies from a repository using SSH. Ivy comes with a dedicated resolver that you can configure and include in your project like so: +mavenRepo(id:'myrepo', url:"http://localhost:8082/myrepo") {code} -import org.apache.ivy.plugins.resolver.SshResolver -... -repositories { - ... - - def sshResolver = new SshResolver( - name: "myRepo", - user: "username", - host: "dev.x.com", - keyFile: new File("/home/username/.ssh/id_rsa"), - m2compatible: true) - - sshResolver.addArtifactPattern( - "/home/grails/repo/[organisation]/[artifact]/" + - "[revision]/[artifact]-[revision].[ext]") - - sshResolver.latestStrategy = - new org.apache.ivy.plugins.latest.LatestTimeStrategy() - sshResolver.changingPattern = ".*SNAPSHOT" +And then declare your credentials in @USER_HOME/.grails/settings.groovy@: - sshResolver.setCheckmodified(true) - - resolver sshResolver -} -{code} - -Download the [JSch|http://www.jcraft.com/jsch/] JAR and add it to Grails' classpath to use the SSH resolver. You can do this by passing the path in the Grails command line: {code} -grails -classpath /path/to/jsch compile|run-app|etc. +grails.project.dependency.authentication = { + credentials { + id = "myrepo" + username = "admin" + password = "password" + } +} {code} -You can also add its path to the @CLASSPATH@ environment variable but be aware this it affects many Java applications. An alternative on Unix is to create an alias for @grails -classpath ...@ so that you don't have to type the extra arguments each time. - -h4. Authentication +h4. Authentication with Ivy If your repository requires authentication you can configure this using a @credentials@ block: From 4ca7ad0167ee3fee008c8a17e4556431680267f6 Mon Sep 17 00:00:00 2001 From: Tom Crossland Date: Wed, 9 Jul 2014 20:58:51 +0200 Subject: [PATCH 004/230] GRAILS-11016 Add usage note --- src/en/ref/Domain Classes/transients.gdoc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/en/ref/Domain Classes/transients.gdoc b/src/en/ref/Domain Classes/transients.gdoc index 31ff84b03c4..41210154e89 100644 --- a/src/en/ref/Domain Classes/transients.gdoc +++ b/src/en/ref/Domain Classes/transients.gdoc @@ -16,3 +16,7 @@ class Author { {code} Here we have an accessor that takes the @name@ and converts it to uppercase. It doesn't make sense to persist this derived value, so we mark it as transient adding its JavaBean property name to the @transients@ list. + +{note} +As of Grails 2.0 if there is only a getter or only a setter method, you don't need to declare the property name of the method in the transients list. Only typed fields and get/set pairs that form a property but shouldn't be persisted need to go in the transients list. +{note} From a927fc6944c1fe9c952f755598e17d0800300c26 Mon Sep 17 00:00:00 2001 From: Ted Timmons Date: Thu, 10 Jul 2014 11:27:54 -0700 Subject: [PATCH 005/230] fix filename typo really simple, but removes some misleading info. --- src/en/guide/upgradingFrom23.gdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/en/guide/upgradingFrom23.gdoc b/src/en/guide/upgradingFrom23.gdoc index f661cf5ccba..b6483042ff9 100644 --- a/src/en/guide/upgradingFrom23.gdoc +++ b/src/en/guide/upgradingFrom23.gdoc @@ -101,7 +101,7 @@ If you or any plugins you have installed are using these classes you will get a If your application uses the jquery plugin you will need to update to version 1.11.0.2 or later as previous versions of the plugin made use of the @ApplicationHolder@ class. If your application uses the resources plugin you will need to update to version 1.2.7 or later as previous versions of the plugin made use of the @ConfigurationHolder@ class. {note} -h4. Changes To applicationContex.xml +h4. Changes To applicationContext.xml The @web-app/WEB-INF/applicationContext.xml@ file contains a bean definition for a @grailsResourceLoader@ bean which is an instance of @org.codehaus.groovy.grails.commons.GrailsResourceLoaderFactoryBean@. That bean definition needs to be removed from the file. The @grailsApplication@ bean may have the @grailsResourceLoader@ bean injected into it as shown below. From a6df1a7a2cbfbd413fb8f49c8d33bc29ff26c947 Mon Sep 17 00:00:00 2001 From: Jeff Scott Brown Date: Sun, 13 Jul 2014 09:25:41 -0500 Subject: [PATCH 006/230] Fix mistake in code example See http://stackoverflow.com/questions/24719664/binding-to-collections-and-maps --- src/en/guide/theWebLayer/controllers/dataBinding.gdoc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/en/guide/theWebLayer/controllers/dataBinding.gdoc b/src/en/guide/theWebLayer/controllers/dataBinding.gdoc index f652090c272..5d999601e33 100644 --- a/src/en/guide/theWebLayer/controllers/dataBinding.gdoc +++ b/src/en/guide/theWebLayer/controllers/dataBinding.gdoc @@ -178,10 +178,10 @@ album.properties = updatedBindingMap assert album.title == 'The Lamb Lies Down On Broadway' assert album.players.size() == 4 -assert album.players.guitar == 'Steve Hackett' -assert album.players.vocals == 'Peter Gabriel' -assert album.players.keyboards == 'Anthony George Banks' -assert album.players.drums == 'Phil Collins' +assert album.players.guitar.name == 'Steve Hackett' +assert album.players.vocals.name == 'Peter Gabriel' +assert album.players.keyboards.name == 'Anthony George Banks' +assert album.players.drums.name == 'Phil Collins' {code} h4. Binding Request Data to the Model From b9316ee282020a125cdbbc9ab57674d40db34672 Mon Sep 17 00:00:00 2001 From: Jeff Scott Brown Date: Wed, 16 Jul 2014 09:41:27 -0500 Subject: [PATCH 007/230] GRAILS-11585 - document new behavior --- src/en/guide/theWebLayer/controllers/commandObjects.gdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/en/guide/theWebLayer/controllers/commandObjects.gdoc b/src/en/guide/theWebLayer/controllers/commandObjects.gdoc index 52f31bbcafe..1727d13d846 100644 --- a/src/en/guide/theWebLayer/controllers/commandObjects.gdoc +++ b/src/en/guide/theWebLayer/controllers/commandObjects.gdoc @@ -55,7 +55,7 @@ class LoginController { } {code} -If the command object's type is that of a domain class and there is an @id@ request parameter then instead of invoking the domain class constructor to create a new instance a call will be made to the static @get@ method on the domain class and the value of the @id@ parameter will be passed as an argument. Whatever is returned from that call to @get@ is what will be passed into the controller action. This means that if there is an @id@ request parameter and no corresponding record is found in the database then the value of the command object will be @null@. If the command object's type is a domain class and there is no @id@ request parameter then @null@ will be passed into the controller action unless the HTTP request method is "POST", in which case a new instance of the domain class will be created by invoking the domain class constructor. For all of the cases where the domain class instance is non-null, data binding is only performed if the HTTP request method is "POST", "PUT" or "PATCH". +If the command object's type is that of a domain class and there is an @id@ request parameter then instead of invoking the domain class constructor to create a new instance a call will be made to the static @get@ method on the domain class and the value of the @id@ parameter will be passed as an argument. Whatever is returned from that call to @get@ is what will be passed into the controller action. This means that if there is an @id@ request parameter and no corresponding record is found in the database then the value of the command object will be @null@. If an error occurs retrieving the instance from the database then @null@ will be passed as an argument to the controller action and an error will be added the controller's @errors@ property. If the command object's type is a domain class and there is no @id@ request parameter then @null@ will be passed into the controller action unless the HTTP request method is "POST", in which case a new instance of the domain class will be created by invoking the domain class constructor. For all of the cases where the domain class instance is non-null, data binding is only performed if the HTTP request method is "POST", "PUT" or "PATCH". h4. Command Objects And Request Parameter Names From 2d70c2c13b3271e1fb10e5d4e9f1168428b1d14c Mon Sep 17 00:00:00 2001 From: Jeff Scott Brown Date: Wed, 16 Jul 2014 10:10:51 -0500 Subject: [PATCH 008/230] add errors and hasErrors to the controller quick reference --- src/en/ref/Controllers/errors.gdoc | 46 +++++++++++++++++++++++++++ src/en/ref/Controllers/hasErrors.gdoc | 22 +++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 src/en/ref/Controllers/errors.gdoc create mode 100644 src/en/ref/Controllers/hasErrors.gdoc diff --git a/src/en/ref/Controllers/errors.gdoc b/src/en/ref/Controllers/errors.gdoc new file mode 100644 index 00000000000..a52c76e2b1f --- /dev/null +++ b/src/en/ref/Controllers/errors.gdoc @@ -0,0 +1,46 @@ +h1. errors + +h2. Purpose + +An instance of the Spring [Errors|api:org.springframework.validation.Errors] interface containing errors associated with this controller. + +h2. Examples + +{code:java} +class DemoController { + + static allowedMethods = [updatePerson: 'PUT'] + + def generateReport(int size) { + if(hasErrors()) { + errors.allErrors.each { + println it + } + } + } + + def updatePerson(SomeDomainClass sdc) { + // if params.id is found then a call + // will have been made to SomeDomainClass.get(params.id) + // to retrieve the instance from the database. + // if no matching instance is found then + // sdc will be null and the controller + // will not have errors. If params.id + // is found and an exception occurs while + // trying to retrieve the instance then + // sdc will be null and an error will + // be added to the controller + if(sdc == null && hasErrors()) { + errors.allErrors.each { + println it + } + } + } +} +{code} + +h2. Description + +The @errors@ property is used by Grails while processing a request. Errors are generated when a type conversion happens while processing action parameters or if an exception is thrown while trying to retrieve a domain class command object from the database. + +See [hasErrors|controllers]. diff --git a/src/en/ref/Controllers/hasErrors.gdoc b/src/en/ref/Controllers/hasErrors.gdoc new file mode 100644 index 00000000000..f216814ad5d --- /dev/null +++ b/src/en/ref/Controllers/hasErrors.gdoc @@ -0,0 +1,22 @@ +h1. hasErrors + +h2. Purpose + +Check if a controller has errors associated with it. + +h2. Examples + +{code:java} +class DemoController { + + def generateReport(int size) { + if(hasErrors()) { + errors.allErrors.each { + println it + } + } + } +} +{code} + +See [errors|controllers]. From 8e546c1ba0cdd275c2294dc7cc55b03efe82af14 Mon Sep 17 00:00:00 2001 From: Donald Oellerich Date: Tue, 22 Jul 2014 18:47:13 -0400 Subject: [PATCH 009/230] Fix typo --- src/en/ref/Tags/submitToRemote.gdoc | 2 +- src/es/ref/Tags/submitToRemote.gdoc | 2 +- src/fr/ref/Tags/submitToRemote.gdoc | 2 +- src/pt_PT/ref/Tags/submitToRemote.gdoc | 2 +- src/th/ref/Tags/submitToRemote.gdoc | 2 +- src/zh_CN/ref/Tags/submitToRemote.gdoc | 2 +- src/zh_TW/ref/Tags/submitToRemote.gdoc | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/en/ref/Tags/submitToRemote.gdoc b/src/en/ref/Tags/submitToRemote.gdoc index 093c0fdaee8..1aa7d6eced0 100644 --- a/src/en/ref/Tags/submitToRemote.gdoc +++ b/src/en/ref/Tags/submitToRemote.gdoc @@ -38,7 +38,7 @@ This tag creates a submit button that fires an AJAX request when it is pressed. Attributes -* @url@ - The url to submit to, either a map contraining keys for the action, controller and id or a string value +* @url@ - The url to submit to, either a map containing keys for the action, controller and id or a string value * @value@ (optional) - The title of the button * @update@ (optional) - Either a Map containing the elements to update for 'success' or 'failure' states, or a string with the element id to update, in which case failure events would be ignored * @before@ (optional) - The JavaScript function to call before the remote function call. A semi-colon is automatically added so you don't have to provide one yourself in this string. diff --git a/src/es/ref/Tags/submitToRemote.gdoc b/src/es/ref/Tags/submitToRemote.gdoc index 06e99298f95..815dd2af046 100644 --- a/src/es/ref/Tags/submitToRemote.gdoc +++ b/src/es/ref/Tags/submitToRemote.gdoc @@ -38,7 +38,7 @@ This tag creates a submit button that fires an AJAX request when it is pressed. Attributes -* @url@ - The url to submit to, either a map contraining keys for the action, controller and id or a string value +* @url@ - The url to submit to, either a map containing keys for the action, controller and id or a string value * @update@ (optional) - Either a Map containing the elements to update for 'success' or 'failure' states, or a string with the element id to update, in which case failure events would be ignored * @before@ (optional) - The JavaScript function to call before the remote function call. A semi-colon is automatically added so you don't have to provide one yourself in this string. * @after@ (optional) - The JavaScript function to call after the remote function call. A semi-colon is automatically added so you don't have to provide one yourself in this string. diff --git a/src/fr/ref/Tags/submitToRemote.gdoc b/src/fr/ref/Tags/submitToRemote.gdoc index 06e99298f95..815dd2af046 100644 --- a/src/fr/ref/Tags/submitToRemote.gdoc +++ b/src/fr/ref/Tags/submitToRemote.gdoc @@ -38,7 +38,7 @@ This tag creates a submit button that fires an AJAX request when it is pressed. Attributes -* @url@ - The url to submit to, either a map contraining keys for the action, controller and id or a string value +* @url@ - The url to submit to, either a map containing keys for the action, controller and id or a string value * @update@ (optional) - Either a Map containing the elements to update for 'success' or 'failure' states, or a string with the element id to update, in which case failure events would be ignored * @before@ (optional) - The JavaScript function to call before the remote function call. A semi-colon is automatically added so you don't have to provide one yourself in this string. * @after@ (optional) - The JavaScript function to call after the remote function call. A semi-colon is automatically added so you don't have to provide one yourself in this string. diff --git a/src/pt_PT/ref/Tags/submitToRemote.gdoc b/src/pt_PT/ref/Tags/submitToRemote.gdoc index 06e99298f95..815dd2af046 100644 --- a/src/pt_PT/ref/Tags/submitToRemote.gdoc +++ b/src/pt_PT/ref/Tags/submitToRemote.gdoc @@ -38,7 +38,7 @@ This tag creates a submit button that fires an AJAX request when it is pressed. Attributes -* @url@ - The url to submit to, either a map contraining keys for the action, controller and id or a string value +* @url@ - The url to submit to, either a map containing keys for the action, controller and id or a string value * @update@ (optional) - Either a Map containing the elements to update for 'success' or 'failure' states, or a string with the element id to update, in which case failure events would be ignored * @before@ (optional) - The JavaScript function to call before the remote function call. A semi-colon is automatically added so you don't have to provide one yourself in this string. * @after@ (optional) - The JavaScript function to call after the remote function call. A semi-colon is automatically added so you don't have to provide one yourself in this string. diff --git a/src/th/ref/Tags/submitToRemote.gdoc b/src/th/ref/Tags/submitToRemote.gdoc index 06e99298f95..815dd2af046 100644 --- a/src/th/ref/Tags/submitToRemote.gdoc +++ b/src/th/ref/Tags/submitToRemote.gdoc @@ -38,7 +38,7 @@ This tag creates a submit button that fires an AJAX request when it is pressed. Attributes -* @url@ - The url to submit to, either a map contraining keys for the action, controller and id or a string value +* @url@ - The url to submit to, either a map containing keys for the action, controller and id or a string value * @update@ (optional) - Either a Map containing the elements to update for 'success' or 'failure' states, or a string with the element id to update, in which case failure events would be ignored * @before@ (optional) - The JavaScript function to call before the remote function call. A semi-colon is automatically added so you don't have to provide one yourself in this string. * @after@ (optional) - The JavaScript function to call after the remote function call. A semi-colon is automatically added so you don't have to provide one yourself in this string. diff --git a/src/zh_CN/ref/Tags/submitToRemote.gdoc b/src/zh_CN/ref/Tags/submitToRemote.gdoc index 06e99298f95..815dd2af046 100644 --- a/src/zh_CN/ref/Tags/submitToRemote.gdoc +++ b/src/zh_CN/ref/Tags/submitToRemote.gdoc @@ -38,7 +38,7 @@ This tag creates a submit button that fires an AJAX request when it is pressed. Attributes -* @url@ - The url to submit to, either a map contraining keys for the action, controller and id or a string value +* @url@ - The url to submit to, either a map containing keys for the action, controller and id or a string value * @update@ (optional) - Either a Map containing the elements to update for 'success' or 'failure' states, or a string with the element id to update, in which case failure events would be ignored * @before@ (optional) - The JavaScript function to call before the remote function call. A semi-colon is automatically added so you don't have to provide one yourself in this string. * @after@ (optional) - The JavaScript function to call after the remote function call. A semi-colon is automatically added so you don't have to provide one yourself in this string. diff --git a/src/zh_TW/ref/Tags/submitToRemote.gdoc b/src/zh_TW/ref/Tags/submitToRemote.gdoc index 06e99298f95..815dd2af046 100644 --- a/src/zh_TW/ref/Tags/submitToRemote.gdoc +++ b/src/zh_TW/ref/Tags/submitToRemote.gdoc @@ -38,7 +38,7 @@ This tag creates a submit button that fires an AJAX request when it is pressed. Attributes -* @url@ - The url to submit to, either a map contraining keys for the action, controller and id or a string value +* @url@ - The url to submit to, either a map containing keys for the action, controller and id or a string value * @update@ (optional) - Either a Map containing the elements to update for 'success' or 'failure' states, or a string with the element id to update, in which case failure events would be ignored * @before@ (optional) - The JavaScript function to call before the remote function call. A semi-colon is automatically added so you don't have to provide one yourself in this string. * @after@ (optional) - The JavaScript function to call after the remote function call. A semi-colon is automatically added so you don't have to provide one yourself in this string. From dfd7ad095804d60926982c6763ce388fd4fab580 Mon Sep 17 00:00:00 2001 From: Donald Oellerich Date: Wed, 23 Jul 2014 15:58:51 -0400 Subject: [PATCH 010/230] spellchecking --- .../GORM/advancedGORMFeatures/ormdsl/caching.gdoc | 2 +- .../ormdsl/tableAndColumnNames.gdoc | 2 +- src/en/guide/GORM/domainClasses/sets,ListsAndMaps.gdoc | 2 +- src/en/guide/GORM/querying/criteria.gdoc | 2 +- src/en/guide/GORM/querying/detachedCriteria.gdoc | 2 +- src/en/guide/async/asyncRequests.gdoc | 2 +- src/en/guide/async/promises.gdoc | 2 +- src/en/guide/commandLine/forkedMode.gdoc | 4 ++-- src/en/guide/commandLine/interactiveMode.gdoc | 2 +- src/en/guide/conf/config/builtInOptions.gdoc | 2 +- src/en/guide/conf/config/logging.gdoc | 2 +- src/en/guide/conf/dataSource.gdoc | 2 +- src/en/guide/conf/dependencyResolution.gdoc | 2 +- .../guide/conf/dependencyResolution/mavendeploy.gdoc | 2 +- src/en/guide/contributing.gdoc | 2 +- src/en/guide/contributing/build.gdoc | 2 +- src/en/guide/i18n.gdoc | 2 +- .../introduction/whatsNew/persistenceFeatures.gdoc | 2 +- src/en/guide/introduction/whatsNew22.gdoc | 2 +- src/en/guide/introduction/whatsNew24.gdoc | 6 +++--- src/en/guide/plugins/evaluatingConventions.gdoc | 2 +- src/en/guide/scaffolding.gdoc | 2 +- src/en/guide/security/codecs.gdoc | 2 +- src/en/guide/security/securingAgainstAttacks.gdoc | 2 +- src/en/guide/spring/theBeanBuilderDSLExplained.gdoc | 2 +- .../grailsCompileStatic.gdoc | 2 +- src/en/guide/testing.gdoc | 2 +- .../testing/unitTesting/unitTestingControllers.gdoc | 2 +- .../guide/theWebLayer/ajax/ajaxSupport/ajaxEvents.gdoc | 2 +- .../controllers/controllerExceptionHandling.gdoc | 2 +- src/en/guide/theWebLayer/controllers/dataBinding.gdoc | 10 +++++----- .../gsp/makingChangesToADeployedApplication.gdoc | 2 +- src/en/guide/theWebLayer/gsp/resources.gdoc | 8 ++++---- .../guide/theWebLayer/gsp/tags/tagsAsMethodCalls.gdoc | 2 +- src/en/guide/upgradingFrom22.gdoc | 4 ++-- src/en/guide/upgradingFrom23.gdoc | 2 +- src/en/guide/validation/validatingConstraints.gdoc | 2 +- src/en/guide/webServices/REST/hypermedia/hal.gdoc | 2 +- .../REST/renderers/objectMarshallerInterface.gdoc | 2 +- .../webServices/REST/renderers/objectMarshallers.gdoc | 2 +- src/en/ref/Command Line/integrate-with.gdoc | 4 ++-- src/en/ref/Tags/actionSubmit.gdoc | 2 +- src/en/ref/Tags/currencySelect.gdoc | 2 +- src/en/ref/Tags/datePicker.gdoc | 2 +- src/en/ref/Tags/formRemote.gdoc | 2 +- src/en/ref/Tags/formatNumber.gdoc | 2 +- src/en/ref/Tags/radioGroup.gdoc | 2 +- src/en/ref/Tags/remoteField.gdoc | 2 +- src/en/ref/Tags/remoteFunction.gdoc | 2 +- src/en/ref/Tags/remoteLink.gdoc | 2 +- src/en/ref/Tags/select.gdoc | 2 +- src/en/ref/Tags/submitToRemote.gdoc | 2 +- 52 files changed, 64 insertions(+), 64 deletions(-) diff --git a/src/en/guide/GORM/advancedGORMFeatures/ormdsl/caching.gdoc b/src/en/guide/GORM/advancedGORMFeatures/ormdsl/caching.gdoc index bd88f7f8a33..6fb7d15e1be 100644 --- a/src/en/guide/GORM/advancedGORMFeatures/ormdsl/caching.gdoc +++ b/src/en/guide/GORM/advancedGORMFeatures/ormdsl/caching.gdoc @@ -103,5 +103,5 @@ Below is a description of the different cache settings and their usages: * @read-only@ - If your application needs to read but never modify instances of a persistent class, a read-only cache may be used. * @read-write@ - If the application needs to update data, a read-write cache might be appropriate. -* @nonstrict-read-write@ - If the application only occasionally needs to update data (ie. if it is very unlikely that two transactions would try to update the same item simultaneously) and strict transaction isolation is not required, a @nonstrict-read-write@ cache might be appropriate. +* @nonstrict-read-write@ - If the application only occasionally needs to update data (i.e. if it is very unlikely that two transactions would try to update the same item simultaneously) and strict transaction isolation is not required, a @nonstrict-read-write@ cache might be appropriate. * @transactional@ - The @transactional@ cache strategy provides support for fully transactional cache providers such as JBoss TreeCache. Such a cache may only be used in a JTA environment and you must specify @hibernate.transaction.manager_lookup_class@ in the @grails-app/conf/DataSource.groovy@ file's @hibernate@ config. diff --git a/src/en/guide/GORM/advancedGORMFeatures/ormdsl/tableAndColumnNames.gdoc b/src/en/guide/GORM/advancedGORMFeatures/ormdsl/tableAndColumnNames.gdoc index ad63e5dd164..539fe386f40 100644 --- a/src/en/guide/GORM/advancedGORMFeatures/ormdsl/tableAndColumnNames.gdoc +++ b/src/en/guide/GORM/advancedGORMFeatures/ormdsl/tableAndColumnNames.gdoc @@ -33,7 +33,7 @@ Here @firstName@ is a dynamic method within the @mapping@ Closure that has a sin h4. Column type -GORM supports configuration of Hibernate types with the DSL using the type attribute. This includes specifing user types that implement the Hibernate [org.hibernate.usertype.UserType|api:org.hibernate.usertype.UserType] interface, which allows complete customization of how a type is persisted. As an example if you had a @PostCodeType@ you could use it as follows: +GORM supports configuration of Hibernate types with the DSL using the type attribute. This includes specifying user types that implement the Hibernate [org.hibernate.usertype.UserType|api:org.hibernate.usertype.UserType] interface, which allows complete customization of how a type is persisted. As an example if you had a @PostCodeType@ you could use it as follows: {code:java} class Address { diff --git a/src/en/guide/GORM/domainClasses/sets,ListsAndMaps.gdoc b/src/en/guide/GORM/domainClasses/sets,ListsAndMaps.gdoc index 3857d1c2bc4..0f4298ce2f8 100644 --- a/src/en/guide/GORM/domainClasses/sets,ListsAndMaps.gdoc +++ b/src/en/guide/GORM/domainClasses/sets,ListsAndMaps.gdoc @@ -8,7 +8,7 @@ class Author { } {code} -The books property that GORM injects is a @java.util.Set@. Sets guarantee uniquenes but not order, which may not be what you want. To have custom ordering you configure the Set as a @SortedSet@: +The books property that GORM injects is a @java.util.Set@. Sets guarantee uniqueness but not order, which may not be what you want. To have custom ordering you configure the Set as a @SortedSet@: {code} class Author { diff --git a/src/en/guide/GORM/querying/criteria.gdoc b/src/en/guide/GORM/querying/criteria.gdoc index 963ba919df5..d93e7385c13 100644 --- a/src/en/guide/GORM/querying/criteria.gdoc +++ b/src/en/guide/GORM/querying/criteria.gdoc @@ -256,7 +256,7 @@ def accountNumber = results.getLong('number') To quote the documentation of Hibernate ScrollableResults: {quote} -A result iterator that allows moving around within the results by arbitrary increments. The Query / ScrollableResults pattern is very similar to the JDBC PreparedStatement/ ResultSet pattern and the semantics of methods of this interface are similar to the similarly named methods on ResultSet. +A result iterator that allows moving around within the results by arbitrary increments. The Query / ScrollableResults pattern is very similar to the JDBC PreparedStatement / ResultSet pattern and the semantics of methods of this interface are similar to the similarly named methods on ResultSet. {quote} Contrary to JDBC, columns of results are numbered from zero. diff --git a/src/en/guide/GORM/querying/detachedCriteria.gdoc b/src/en/guide/GORM/querying/detachedCriteria.gdoc index a76e0f9e842..ade494801ea 100644 --- a/src/en/guide/GORM/querying/detachedCriteria.gdoc +++ b/src/en/guide/GORM/querying/detachedCriteria.gdoc @@ -104,7 +104,7 @@ def results = Person.withCriteria { } {code} -Notice that in this case the subquery class is the same as the original criteria query class (ie. @Person@) and hence the query can be shortened to: +Notice that in this case the subquery class is the same as the original criteria query class (i.e. @Person@) and hence the query can be shortened to: {code} def results = Person.withCriteria { diff --git a/src/en/guide/async/asyncRequests.gdoc b/src/en/guide/async/asyncRequests.gdoc index 2d3fc340e9a..a95c80d947a 100644 --- a/src/en/guide/async/asyncRequests.gdoc +++ b/src/en/guide/async/asyncRequests.gdoc @@ -6,7 +6,7 @@ The reason being that with an asynchronous / non-blocking response, the one thre For example, if you have 70 available container threads and an action takes a minute to complete, if the actions are not executed in a non-blocking fashion the likelihood of all 70 threads being occupied and the container not being able to respond is quite high and you should consider asynchronous request processing. -Since Grails 2.3, Grails features a simplified API for creating asynchronous responses built on the @Promise@ mechism discussed previously. +Since Grails 2.3, Grails features a simplified API for creating asynchronous responses built on the @Promise@ mechanism discussed previously. The implementation is based on Servlet 3.0 async so to enable the async features you need to set your servlet target version to 3.0 in BuildConfig.groovy: diff --git a/src/en/guide/async/promises.gdoc b/src/en/guide/async/promises.gdoc index a913506e3bb..392779a4a05 100644 --- a/src/en/guide/async/promises.gdoc +++ b/src/en/guide/async/promises.gdoc @@ -150,7 +150,7 @@ import grails.async.* Promises.promiseFactory = new SynchronousPromiseFactory() {code} -Using the @PromiseFactory@ mechanism is theoritically possible to plug in other concurrency libraries into the Grails framework. +Using the @PromiseFactory@ mechanism is theoretically possible to plug in other concurrency libraries into the Grails framework. h3. DelegateAsync Transformation diff --git a/src/en/guide/commandLine/forkedMode.gdoc b/src/en/guide/commandLine/forkedMode.gdoc index 290ced0be31..6d21d61c2d3 100644 --- a/src/en/guide/commandLine/forkedMode.gdoc +++ b/src/en/guide/commandLine/forkedMode.gdoc @@ -40,9 +40,9 @@ grails.project.fork = [ ] {code} -h4. Using the Test Runnner Deamon to Speed-up Test Execution +h4. Using the Test Runner Daemon to Speed-up Test Execution -The defaut configuration for the testing is to activate a daemon to run tests using the @daemon@ argument: +The default configuration for the testing is to activate a daemon to run tests using the @daemon@ argument: {code} grails.project.fork = [ diff --git a/src/en/guide/commandLine/interactiveMode.gdoc b/src/en/guide/commandLine/interactiveMode.gdoc index fd97cfc0792..96e79feeaf8 100644 --- a/src/en/guide/commandLine/interactiveMode.gdoc +++ b/src/en/guide/commandLine/interactiveMode.gdoc @@ -20,4 +20,4 @@ Note that with \! (bang) commands, you get file path auto completion - ideal for The @stop-app@ command will stop an application that has been run with the @run-app@ command. -To exit interactive mode enter the @exit@ command. Note that if the Grails application has been run with @run-app@ normally it will terminate when the interactive mode console exits because the JVM will be terminated. An exception to this would be if the application were running in forked mode which means the application is running in a different JVM. In that case the application will be left running afer the interactive mode console terminates. If you want to exit interactive mode and stop an application that is running in forked mode, use the @quit@ command. The @quit@ command will stop the running application and then close interactive mode. +To exit interactive mode enter the @exit@ command. Note that if the Grails application has been run with @run-app@ normally it will terminate when the interactive mode console exits because the JVM will be terminated. An exception to this would be if the application were running in forked mode which means the application is running in a different JVM. In that case the application will be left running after the interactive mode console terminates. If you want to exit interactive mode and stop an application that is running in forked mode, use the @quit@ command. The @quit@ command will stop the running application and then close interactive mode. diff --git a/src/en/guide/conf/config/builtInOptions.gdoc b/src/en/guide/conf/config/builtInOptions.gdoc index 72aae819a16..e0d7be70833 100644 --- a/src/en/guide/conf/config/builtInOptions.gdoc +++ b/src/en/guide/conf/config/builtInOptions.gdoc @@ -34,7 +34,7 @@ On the runtime front, i.e. @Config.groovy@, there are quite a few more core sett h3. War generation * @grails.project.war.file@ - Sets the name and location of the WAR file generated by the [war|commandLine] command -* @grails.war.dependencies@ - A closure containing Ant builder syntax or a list of JAR filenames. Lets you customise what libaries are included in the WAR file. +* @grails.war.dependencies@ - A closure containing Ant builder syntax or a list of JAR filenames. Lets you customise what libraries are included in the WAR file. * @grails.war.copyToWebApp@ - A closure containing Ant builder syntax that is legal inside an Ant copy, for example "fileset()". Lets you control what gets included in the WAR file from the "web-app" directory. * @grails.war.resources@ - A closure containing Ant builder syntax. Allows the application to do any other work before building the final WAR file diff --git a/src/en/guide/conf/config/logging.gdoc b/src/en/guide/conf/config/logging.gdoc index 7f91a320fc1..91298f7990c 100644 --- a/src/en/guide/conf/config/logging.gdoc +++ b/src/en/guide/conf/config/logging.gdoc @@ -92,7 +92,7 @@ This example configures loggers with names starting with 'org.codehaus.groovy.gr In other words, loggers are hierarchical. This makes configuring them by package much simpler than it would otherwise be. -The most common things that you will want to capture log output from are your controllers, services, and other artifacts. Use the convention mentioned earlier to do that: _grails.app.._. In particular the class name must be fully qualifed, i.e. with the package if there is one: +The most common things that you will want to capture log output from are your controllers, services, and other artifacts. Use the convention mentioned earlier to do that: _grails.app.._. In particular the class name must be fully qualified, i.e. with the package if there is one: {code:java} log4j = { diff --git a/src/en/guide/conf/dataSource.gdoc b/src/en/guide/conf/dataSource.gdoc index dc9bfc0ec60..b09caafa508 100644 --- a/src/en/guide/conf/dataSource.gdoc +++ b/src/en/guide/conf/dataSource.gdoc @@ -153,7 +153,7 @@ h4. More on dbCreate Hibernate can automatically create the database tables required for your domain model. You have some control over when and how it does this through the @dbCreate@ property, which can take these values: -* *create* - Drops the existing schemaCreates the schema on startup, dropping existing tables, indexes, etc. first. +* *create* - Drops the existing schema and creates the schema on startup, dropping existing tables, indexes, etc. first. * *create-drop* - Same as *create*, but also drops the tables when the application shuts down cleanly. * *update* - Creates missing tables and indexes, and updates the current schema without dropping any tables or data. Note that this can't properly handle many schema changes like column renames (you're left with the old column containing the existing data). * *validate* - Makes no changes to your database. Compares the configuration with the existing database schema and reports warnings. diff --git a/src/en/guide/conf/dependencyResolution.gdoc b/src/en/guide/conf/dependencyResolution.gdoc index 4333a4c6cd1..eaf695d1d72 100644 --- a/src/en/guide/conf/dependencyResolution.gdoc +++ b/src/en/guide/conf/dependencyResolution.gdoc @@ -1,6 +1,6 @@ Grails features a dependency resolution DSL that lets you control how plugins and JAR dependencies are resolved. -You can choose to use Aether (since Grails 2.3) or Apache Ivy as the dependency resolution engine. Aether is the dependency resolution library used by the Maven build tool, so if you are looking for Maven-like behavior then Aether is the better choise. Ivy allows more flexibility if you wish to resolve jars from flat file systems or none HTTP repositories. Aether is the default dependency resolution engine for Grails applications since Grails 2.3. +You can choose to use Aether (since Grails 2.3) or Apache Ivy as the dependency resolution engine. Aether is the dependency resolution library used by the Maven build tool, so if you are looking for Maven-like behavior then Aether is the better choice. Ivy allows more flexibility if you wish to resolve jars from flat file systems or none HTTP repositories. Aether is the default dependency resolution engine for Grails applications since Grails 2.3. {warning} As of Grails 2.4 the Ivy resolver is considered deprecated and no longer maintained. It is recommended all users switch to using Aether. diff --git a/src/en/guide/conf/dependencyResolution/mavendeploy.gdoc b/src/en/guide/conf/dependencyResolution/mavendeploy.gdoc index 56e9b3e4bd0..0ed80ec6cb2 100644 --- a/src/en/guide/conf/dependencyResolution/mavendeploy.gdoc +++ b/src/en/guide/conf/dependencyResolution/mavendeploy.gdoc @@ -57,7 +57,7 @@ remoteRepository(id: "myRepo", url: "scp://localhost/www/repository") { } {code} -By default the plugin will try to detect the protocol to use from the URL of the repository (ie "http" from "http://.." etc.), however to specify a different protocol you can do: +By default the plugin will try to detect the protocol to use from the URL of the repository (e.g. "http" from "http://.." etc.), however to specify a different protocol you can do: {code} grails maven-deploy --repository=myRepo --protocol=webdav diff --git a/src/en/guide/contributing.gdoc b/src/en/guide/contributing.gdoc index 480409a7404..c0701cb1682 100644 --- a/src/en/guide/contributing.gdoc +++ b/src/en/guide/contributing.gdoc @@ -1 +1 @@ -Grails is an open source project with an active community and we rely heavily on that community to help make Grails better. As such, there are various ways in which people can contribute to Grails. One of these is by [writing useful plugins|guide:plugins] and making them publicly available. In this chapter, we'll look at some fo the other options. +Grails is an open source project with an active community and we rely heavily on that community to help make Grails better. As such, there are various ways in which people can contribute to Grails. One of these is by [writing useful plugins|guide:plugins] and making them publicly available. In this chapter, we'll look at some of the other options. diff --git a/src/en/guide/contributing/build.gdoc b/src/en/guide/contributing/build.gdoc index bf3beedab37..45ba31f0934 100644 --- a/src/en/guide/contributing/build.gdoc +++ b/src/en/guide/contributing/build.gdoc @@ -3,7 +3,7 @@ If you're interested in contributing fixes and features to the core framework, y * A JDK (1.6 or above) * A git client -Once you have all the pre-requisite packages installed, the next step is to download the Grails source code, which is hosted at [GitHub|http://github.com] in several repositories owned by the ["grails" GitHub user|http://github.com/grails]. This is a simple case of cloning the repository you're interested in. For example, to getthe core framework run: +Once you have all the pre-requisite packages installed, the next step is to download the Grails source code, which is hosted at [GitHub|http://github.com] in several repositories owned by the ["grails" GitHub user|http://github.com/grails]. This is a simple case of cloning the repository you're interested in. For example, to get the core framework run: {code} git clone http://github.com/grails/grails-core.git diff --git a/src/en/guide/i18n.gdoc b/src/en/guide/i18n.gdoc index 1878fbec5fe..20083529a48 100644 --- a/src/en/guide/i18n.gdoc +++ b/src/en/guide/i18n.gdoc @@ -4,4 +4,4 @@ Grails supports Internationalization (i18n) out of the box by leveraging the und A Locale object represents a specific geographical, political, or cultural region. An operation that requires a Locale to perform its task is called locale-sensitive and uses the Locale to tailor information for the user. For example, displaying a number is a locale-sensitive operation--the number should be formatted according to the customs/conventions of the user's native country, region, or culture. {quote} -A Locale is made up of a [language code|http://www.loc.gov/standards/iso639-2/php/English_list.php] and a [country code|http://www.iso.org/iso/country_codes/iso_3166_code_lists/country_names_and_code_elements.htm]. For example "en_US" is the code for US english, whilst "en_GB" is the code for British English. +A Locale is made up of a [language code|http://www.loc.gov/standards/iso639-2/php/English_list.php] and a [country code|http://www.iso.org/iso/country_codes/iso_3166_code_lists/country_names_and_code_elements.htm]. For example "en_US" is the code for US English, whilst "en_GB" is the code for British English. diff --git a/src/en/guide/introduction/whatsNew/persistenceFeatures.gdoc b/src/en/guide/introduction/whatsNew/persistenceFeatures.gdoc index 1fb56da2cad..3b1e2faabd6 100644 --- a/src/en/guide/introduction/whatsNew/persistenceFeatures.gdoc +++ b/src/en/guide/introduction/whatsNew/persistenceFeatures.gdoc @@ -29,7 +29,7 @@ h4. New findOrCreate and findOrSave Methods Domain classes have support for the findOrCreateWhere, findOrSaveWhere, findOrCreateBy and findOrSaveBy query methods which behave just like findWhere and findBy methods except that they should never return null. If a matching instance cannot be found in the database then a new instance is created, populated with values represented in the query parameters and returned. In the case of findOrSaveWhere and findOrSaveBy, the instance is saved before being returned. {code} -def book = Book.findOrCreateWhere(author: 'Douglas Adams', title: "The Hitchiker's Guide To The Galaxy") +def book = Book.findOrCreateWhere(author: 'Douglas Adams', title: "The Hitchhiker's Guide To The Galaxy") def book = Book.findOrSaveWhere(author: 'Daniel Suarez', title: 'Daemon') def book = Book.findOrCreateByAuthorAndTitle('Daniel Suarez', 'Daemon') def book = Book.findOrSaveByAuthorAndTitle('Daniel Suarez', 'Daemon') diff --git a/src/en/guide/introduction/whatsNew22.gdoc b/src/en/guide/introduction/whatsNew22.gdoc index a73b68a5245..c43e02ffea3 100644 --- a/src/en/guide/introduction/whatsNew22.gdoc +++ b/src/en/guide/introduction/whatsNew22.gdoc @@ -70,7 +70,7 @@ def c = Box.createCriteria() def results = c.list { projections { - sqlProjection '(2 * (width + height)) as perimiter, (width * height) as area', ['perimeter', 'area'], [INTEGER, INTEGER] + sqlProjection '(2 * (width + height)) as perimeter, (width * height) as area', ['perimeter', 'area'], [INTEGER, INTEGER] } } {code} diff --git a/src/en/guide/introduction/whatsNew24.gdoc b/src/en/guide/introduction/whatsNew24.gdoc index 93ec8777569..77482a878b6 100644 --- a/src/en/guide/introduction/whatsNew24.gdoc +++ b/src/en/guide/introduction/whatsNew24.gdoc @@ -26,8 +26,8 @@ The asset-pipeline provides a new, easier to manage, faster means of managing yo All your assets should now live in the @grails-app/assets@ subfolders. Three folders are made for you by default: -* javascripts -* stylesheets +* javascript +* stylesheets * images Now, defining manifests are done directly in your JavaScript files, or CSS by using require directives! @@ -226,7 +226,7 @@ This means that the Maven plugin version number is no longer tied to the version h4. Unit Testing improvements -There is a Grails "unit testing runtime" that is based on the previous TestMixin based solution. It now separates the TestMixin classes and the actual runtime that handles the lifecycle of the Grails unit testing runtime. State of the runtime is not kept in static fields of the TestMixin classes anymore. The Groovy AST transformation behind the TestMixin annotation integrates to Junit and Spock test classes by adding Junit Rule fields to the class. In the previous solution, Before/BeforeClass and After/AfterClass annotations on AST added mix-in methods were used for the integration. +There is a Grails "unit testing runtime" that is based on the previous TestMixin based solution. It now separates the TestMixin classes and the actual runtime that handles the lifecycle of the Grails unit testing runtime. State of the runtime is not kept in static fields of the TestMixin classes anymore. The Groovy AST transformation behind the TestMixin annotation integrates to JUnit and Spock test classes by adding JUnit Rule fields to the class. In the previous solution, Before/BeforeClass and After/AfterClass annotations on AST added mix-in methods were used for the integration. Some of the main features: diff --git a/src/en/guide/plugins/evaluatingConventions.gdoc b/src/en/guide/plugins/evaluatingConventions.gdoc index 6a5cc1a9a2e..6677f5b66c3 100644 --- a/src/en/guide/plugins/evaluatingConventions.gdoc +++ b/src/en/guide/plugins/evaluatingConventions.gdoc @@ -34,7 +34,7 @@ The @GrailsClass@ interface has a number of useful methods that let you further * @getFullName@ - Returns the full name of the class in the application with the trailing convention part and with the package name * @getPropertyName@ - Returns the name of the class as a property name * @getLogicalPropertyName@ - Returns the logical property name of the class in the application without the trailing convention part if applicable -* @getNaturalName@ - Returns the name of the property in natural terms (eg. 'lastName' becomes 'Last Name') +* @getNaturalName@ - Returns the name of the property in natural terms (e.g. 'lastName' becomes 'Last Name') * @getPackageName@ - Returns the package name For a full reference refer to the [javadoc API|api:org.codehaus.groovy.grails.commons.GrailsClass]. diff --git a/src/en/guide/scaffolding.gdoc b/src/en/guide/scaffolding.gdoc index d92e8e2e083..65cbccefed5 100644 --- a/src/en/guide/scaffolding.gdoc +++ b/src/en/guide/scaffolding.gdoc @@ -13,7 +13,7 @@ As of Grails 2.3, the scaffolding feature has been moved to a plugin. By default } {code} -Version 1.0.0 of the plugin provides the same scaffolding seen in Grails 2.2.x and below. Version 2.0.x of the scaffolding plugin includes different scaffolding templates that are aligned with the new REST APIs introcued in Grails 2.3 and above. +Version 1.0.0 of the plugin provides the same scaffolding seen in Grails 2.2.x and below. Version 2.0.x of the scaffolding plugin includes different scaffolding templates that are aligned with the new REST APIs introduced in Grails 2.3 and above. h4. Dynamic Scaffolding diff --git a/src/en/guide/security/codecs.gdoc b/src/en/guide/security/codecs.gdoc index 3c77fee773d..f066053edd9 100644 --- a/src/en/guide/security/codecs.gdoc +++ b/src/en/guide/security/codecs.gdoc @@ -58,7 +58,7 @@ Example of usage: Note that the HTML encoding does not re-encode apostrophe/single quote so you must use double quotes on attribute values to avoid text with apostrophes affecting your page. {note} -HTMLCodec defaults to HTML4 style escaping (legacy HTMLCodec implementation in Grails ersions before 2.3.0 ) which escapes non-ascii characters. +HTMLCodec defaults to HTML4 style escaping (legacy HTMLCodec implementation in Grails versions before 2.3.0) which escapes non-ascii characters. You can use plain XML escaping instead of HTML4 escaping by setting this config property in Config.groovy: {code} diff --git a/src/en/guide/security/securingAgainstAttacks.gdoc b/src/en/guide/security/securingAgainstAttacks.gdoc index 3bc06270661..a85570da042 100644 --- a/src/en/guide/security/securingAgainstAttacks.gdoc +++ b/src/en/guide/security/securingAgainstAttacks.gdoc @@ -8,7 +8,7 @@ def vulnerable() { } {code} -or the analagous call using a GString: +or the analogous call using a GString: {code:java} def vulnerable() { diff --git a/src/en/guide/spring/theBeanBuilderDSLExplained.gdoc b/src/en/guide/spring/theBeanBuilderDSLExplained.gdoc index eaca589bb22..44de526dbaf 100644 --- a/src/en/guide/spring/theBeanBuilderDSLExplained.gdoc +++ b/src/en/guide/spring/theBeanBuilderDSLExplained.gdoc @@ -111,7 +111,7 @@ Here the example property of @AnotherBean@ is set using a runtime reference to t {code:java} ApplicationContext parent = ...// -der bb = new BeanBuilder(parent) +def bb = new BeanBuilder(parent) bb.beans { anotherBean(AnotherBean) { example = ref("${beanName}Bean", true) diff --git a/src/en/guide/staticTypeCheckingAndCompilation/grailsCompileStatic.gdoc b/src/en/guide/staticTypeCheckingAndCompilation/grailsCompileStatic.gdoc index 6785f452eb0..310ee151033 100644 --- a/src/en/guide/staticTypeCheckingAndCompilation/grailsCompileStatic.gdoc +++ b/src/en/guide/staticTypeCheckingAndCompilation/grailsCompileStatic.gdoc @@ -77,6 +77,6 @@ class SomeClass { } {code} -Code that is marked with @GrailsCompileStatic@ will all be statically compiled except for Grails specific interactions that cannot be statically compiled but that @GrailsCompileStatic@ can identify as permissable for dynamic dispatch. These include things like invoking dynamic finders and DSL code in configuration blocks like constraints and mapping closures in domain classes. +Code that is marked with @GrailsCompileStatic@ will all be statically compiled except for Grails specific interactions that cannot be statically compiled but that @GrailsCompileStatic@ can identify as permissible for dynamic dispatch. These include things like invoking dynamic finders and DSL code in configuration blocks like constraints and mapping closures in domain classes. Care must be taken when deciding to statically compile code. There are benefits associated with static compilation but in order to take advantage of those benefits you are giving up the power and flexibility of dynamic dispatch. For example if code is statically compiled it cannot take advantage of runtime metaprogramming enhancements which may be provided by plugins. \ No newline at end of file diff --git a/src/en/guide/testing.gdoc b/src/en/guide/testing.gdoc index 6249b04c4b0..f0a569e9aed 100644 --- a/src/en/guide/testing.gdoc +++ b/src/en/guide/testing.gdoc @@ -1,7 +1,7 @@ Automated testing is a key part of Grails. Hence, Grails provides many ways to making testing easier from low level unit testing to high level functional tests. This section details the different capabilities that Grails offers for testing. {note} -Grails 1.3.x and below used the @grails.test.GrailsUnitTestCase@ class hierarchy for testing in a JUnit 3 style. Grails 2.0.x and above deprecates these test harnesses in favour of mixins that can be applied to a range of different kinds of tests (JUnit 3, Junit 4, Spock etc.) without subclassing +Grails 1.3.x and below used the @grails.test.GrailsUnitTestCase@ class hierarchy for testing in a JUnit 3 style. Grails 2.0.x and above deprecates these test harnesses in favour of mixins that can be applied to a range of different kinds of tests (JUnit 3, JUnit 4, Spock etc.) without subclassing {note} The first thing to be aware of is that all of the @create-\*@ and @generate-\*@ commands create @unit@ or @integration@ tests automatically. For example if you run the [create-controller|commandLine] command as follows: diff --git a/src/en/guide/testing/unitTesting/unitTestingControllers.gdoc b/src/en/guide/testing/unitTesting/unitTestingControllers.gdoc index 6f4e59255b0..a35a7bbe368 100644 --- a/src/en/guide/testing/unitTesting/unitTestingControllers.gdoc +++ b/src/en/guide/testing/unitTesting/unitTestingControllers.gdoc @@ -718,7 +718,7 @@ class SimpleControllerSpec extends Specification { } {code} -The testing framework also supports allowing Grails to create the command object instance automatically. To test this invoke the no-arg version of the controller action method. Grails will create an instance of the command object, perform data binding on it using the request parameters and validate the object just like it does in when the application is runnning. See the test below. +The testing framework also supports allowing Grails to create the command object instance automatically. To test this invoke the no-arg version of the controller action method. Grails will create an instance of the command object, perform data binding on it using the request parameters and validate the object just like it does in when the application is running. See the test below. {code:java} import grails.test.mixin.TestFor diff --git a/src/en/guide/theWebLayer/ajax/ajaxSupport/ajaxEvents.gdoc b/src/en/guide/theWebLayer/ajax/ajaxSupport/ajaxEvents.gdoc index 9679ee68468..617f7c55454 100644 --- a/src/en/guide/theWebLayer/ajax/ajaxSupport/ajaxEvents.gdoc +++ b/src/en/guide/theWebLayer/ajax/ajaxSupport/ajaxEvents.gdoc @@ -12,7 +12,7 @@ The above code will execute the "showProgress()" function which may show a progr * @onSuccess@ - The JavaScript function to call if successful * @onFailure@ - The JavaScript function to call if the call failed -* @on_ERROR_CODE@ - The JavaScript function to call to handle specified error codes (eg on404="alert('not found!')") +* @onERROR_CODE@ - The JavaScript function to call to handle specified error codes (e.g. @on404="alert('not found!')"@) * @onUninitialized@ - The JavaScript function to call the a Ajax engine failed to initialise * @onLoading@ - The JavaScript function to call when the remote function is loading the response * @onLoaded@ - The JavaScript function to call when the remote function is completed loading the response diff --git a/src/en/guide/theWebLayer/controllers/controllerExceptionHandling.gdoc b/src/en/guide/theWebLayer/controllers/controllerExceptionHandling.gdoc index 8c09eb26654..3911188a2a3 100644 --- a/src/en/guide/theWebLayer/controllers/controllerExceptionHandling.gdoc +++ b/src/en/guide/theWebLayer/controllers/controllerExceptionHandling.gdoc @@ -64,7 +64,7 @@ The exception handler method names can be any valid method name. The name is no The exception handler methods can do anything that a controller action can do including invoking @render@, @redirect@, returning a model, etc. -One way to share exception handler methods across multiple controllers is to use inheritance. Exception handler methods are inherited into sublcasses so an application could define the exception handlers in an abstract class that multiple controllers extend from. Another way to share exception handler methods across multiple controllers is to use a trait, as shown below... +One way to share exception handler methods across multiple controllers is to use inheritance. Exception handler methods are inherited into subclasses so an application could define the exception handlers in an abstract class that multiple controllers extend from. Another way to share exception handler methods across multiple controllers is to use a trait, as shown below... {code:java} // src/groovy/com/demo/DatabaseExceptionHandler.groovy diff --git a/src/en/guide/theWebLayer/controllers/dataBinding.gdoc b/src/en/guide/theWebLayer/controllers/dataBinding.gdoc index 5d999601e33..b2c08e5c3ca 100644 --- a/src/en/guide/theWebLayer/controllers/dataBinding.gdoc +++ b/src/en/guide/theWebLayer/controllers/dataBinding.gdoc @@ -125,7 +125,7 @@ def band = Band.get(someBandId) band.properties = bindingMap {code} -When binding to a @Map@ the structure of the binding @Map@ is the same as the structore of a @Map@ used for binding to a @List@ or a @Set@ and the index inside of square brackets corresponds to the key in the @Map@ being bound to. See the following code: +When binding to a @Map@ the structure of the binding @Map@ is the same as the structure of a @Map@ used for binding to a @List@ or a @Set@ and the index inside of square brackets corresponds to the key in the @Map@ being bound to. See the following code: {code:java} class Album { @@ -154,7 +154,7 @@ assert album.players.vocals.name == 'Peter Gabriel' assert album.players.keyboards.name == 'Tony Banks' {code} -When updating an exisiting @Map@, if the key specified in the binding @Map@ does not exist in the @Map@ being bound to then a new value will be created and added to the @Map@ with the specified key as in the following example: +When updating an existing @Map@, if the key specified in the binding @Map@ does not exist in the @Map@ being bound to then a new value will be created and added to the @Map@ with the specified key as in the following example: {code} @@ -219,7 +219,7 @@ def save() { This has the same effect as using the implicit constructor. -When binding an empty String (a String with no characters in it, not even spaces), the data binder will convert the empty String to null. This simplifies the most common case where the intent is to treat an empty form field as having the value null since there isn't a way to actually submit a null as a request parameter. When this behavior is not desireable the application may assign the value directly. +When binding an empty String (a String with no characters in it, not even spaces), the data binder will convert the empty String to null. This simplifies the most common case where the intent is to treat an empty form field as having the value null since there isn't a way to actually submit a null as a request parameter. When this behavior is not desirable the application may assign the value directly. The mass property binding mechanism will by default automatically trim all Strings at binding time. To disable this behavior set the @grails.databinding.trimStrings@ property to false in @grails-app/conf/Config.groovy@. @@ -578,7 +578,7 @@ The default formats that are used are "yyyy-MM-dd HH:mm:ss.S" and "yyyy-MM-dd'T' h4. Custom Formatted Converters -You may supply your own handler for the [BindingFormat|api:org.grails.databinding.BindingFormat] annotation by writing a class which implements the [FormattedValueConverter|api:org.grails.databinding.converters.FormattedValueConverter] interface and regiserting an instance of that class as a bean in the Spring application context. Below is an example of a trivial custom String formatter that might convert the case of a String based on the value assigned to the BindingFormat annotation. +You may supply your own handler for the [BindingFormat|api:org.grails.databinding.BindingFormat] annotation by writing a class which implements the [FormattedValueConverter|api:org.grails.databinding.converters.FormattedValueConverter] interface and registering an instance of that class as a bean in the Spring application context. Below is an example of a trivial custom String formatter that might convert the case of a String based on the value assigned to the BindingFormat annotation. {code:java} package com.myapp.converters @@ -721,7 +721,7 @@ beans = { } {code} -When the data binder binds to an instance of the @Gadget@ class it will check to see if there are request parameters with names @compressedShape@ and @expandedShape@ which have a value of "struct" and if they do exist, that will trigger the use of the @StructuredShapeEditor@. The individual components of the structure need to have parameter names of the form propertyName_structuredElementName. In the case of the @Gadget@ class above that would mean that the @compressedShape@ request parameter should have a value of "struct" and the @compressedShape_width@ and @compressedShape_height@ parameters should have values which represent the width and the height of the compressed @Shape@. Similarly, the @expandedShape@ request parameter should have a value of "struct" and the @expandedShape_width@ and @expandedShape_height@ parameters should have values which represent the width and the hight of the expanded @Shape@. +When the data binder binds to an instance of the @Gadget@ class it will check to see if there are request parameters with names @compressedShape@ and @expandedShape@ which have a value of "struct" and if they do exist, that will trigger the use of the @StructuredShapeEditor@. The individual components of the structure need to have parameter names of the form propertyName_structuredElementName. In the case of the @Gadget@ class above that would mean that the @compressedShape@ request parameter should have a value of "struct" and the @compressedShape_width@ and @compressedShape_height@ parameters should have values which represent the width and the height of the compressed @Shape@. Similarly, the @expandedShape@ request parameter should have a value of "struct" and the @expandedShape_width@ and @expandedShape_height@ parameters should have values which represent the width and the height of the expanded @Shape@. {code} // grails-app/controllers/demo/DemoController.groovy diff --git a/src/en/guide/theWebLayer/gsp/makingChangesToADeployedApplication.gdoc b/src/en/guide/theWebLayer/gsp/makingChangesToADeployedApplication.gdoc index 462e03803d9..5a00961f04b 100644 --- a/src/en/guide/theWebLayer/gsp/makingChangesToADeployedApplication.gdoc +++ b/src/en/guide/theWebLayer/gsp/makingChangesToADeployedApplication.gdoc @@ -25,7 +25,7 @@ One thing to bear in mind with this technique is that every time you modify a GS There are also some System properties to control GSP reloading: {table} *Name* | *Description* | *Default* -grails.gsp.enable.reload | altervative system property for enabling the GSP reload mode without changing Config.groovy | +grails.gsp.enable.reload | alternative system property for enabling the GSP reload mode without changing Config.groovy | grails.gsp.reload.interval | interval between checking the lastmodified time of the gsp source file, unit is milliseconds | 5000 grails.gsp.reload.granularity | the number of milliseconds leeway to give before deciding a file is out of date. this is needed because different roundings usually cause a 1000ms difference in lastmodified times | 1000 {table} diff --git a/src/en/guide/theWebLayer/gsp/resources.gdoc b/src/en/guide/theWebLayer/gsp/resources.gdoc index e2600665cfd..5c5bc315fb3 100644 --- a/src/en/guide/theWebLayer/gsp/resources.gdoc +++ b/src/en/guide/theWebLayer/gsp/resources.gdoc @@ -7,11 +7,11 @@ However modern applications with dependencies on multiple JavaScript and CSS lib The issues that the Asset-Pipeline plugin tackles are: * Reduced Dependence - The plugin has compression, minification, and cache-digests built in. -* Easy Debugging - Makes for easy debugging by keeping files seperate in development mode. +* Easy Debugging - Makes for easy debugging by keeping files separate in development mode. * Asset Bundling using require [directives|http://bertramdev.github.io/asset-pipeline/guide/usage.html#directives]. -* Web application performance tuning is difficult -* The need for a standard way to expose static assets in plugins and applications -* The need for extinsible processing to make languages like LESS or Coffee first class citizens. +* Web application performance tuning is difficult. +* The need for a standard way to expose static assets in plugins and applications. +* The need for extensible processing to make languages like LESS or Coffee first class citizens. The asset-pipeline allows you to define your javascript or css requirements right at the top of the file and they get compiled on War creation. diff --git a/src/en/guide/theWebLayer/gsp/tags/tagsAsMethodCalls.gdoc b/src/en/guide/theWebLayer/gsp/tags/tagsAsMethodCalls.gdoc index 16ca2e7ea47..e892becc118 100644 --- a/src/en/guide/theWebLayer/gsp/tags/tagsAsMethodCalls.gdoc +++ b/src/en/guide/theWebLayer/gsp/tags/tagsAsMethodCalls.gdoc @@ -14,7 +14,7 @@ This is particularly useful for using a tag within an attribute: {code} -In view technologies that don't support this feature you have to nest tags within tags, which becomes messy quickly and often has an adverse effect of WYSWIG tools such as Dreamweaver that attempt to render the mark-up as it is not well-formed: +In view technologies that don't support this feature you have to nest tags within tags, which becomes messy quickly and often has an adverse effect of WYSIWYG tools such as Dreamweaver that attempt to render the mark-up as it is not well-formed: {code:xml} " /> diff --git a/src/en/guide/upgradingFrom22.gdoc b/src/en/guide/upgradingFrom22.gdoc index cf718bf1c57..73e7e7fcb3a 100644 --- a/src/en/guide/upgradingFrom22.gdoc +++ b/src/en/guide/upgradingFrom22.gdoc @@ -40,7 +40,7 @@ mavenRepo("http://artifactory.mycompany.com/repo") { h4. Dependency Metadata Changes -In addition, the POM and dependency metadata for Grails 2.3 has been re-arranged and cleaned up so that only direct dependencies are specified for an application and all other dependencies are inherited transitvely. This has implications to the upgrade since, for example, Ehcache is now a transitive dependency of the Hibernate plugin, whilst before it was a direct dependency. If get a compilation error related to Ehcache, it is most likely that you don't have the Hibernate plugin installed and need to directly declare the Ehcache dependency: +In addition, the POM and dependency metadata for Grails 2.3 has been re-arranged and cleaned up so that only direct dependencies are specified for an application and all other dependencies are inherited transitively. This has implications to the upgrade since, for example, Ehcache is now a transitive dependency of the Hibernate plugin, whilst before it was a direct dependency. If get a compilation error related to Ehcache, it is most likely that you don't have the Hibernate plugin installed and need to directly declare the Ehcache dependency: {code} compile "net.sf.ehcache:ehcache-core:2.4.6" @@ -143,7 +143,7 @@ $ grails -> test-app $ grails -> test-app {code} -Test execution will be noticably faster and is the recommended way to run tests in Grails. On older hardware that does not include multiple cores (to run the separate JVMs) it is recommended you disable forked execution for tests to achieve faster test execution times: +Test execution will be noticeably faster and is the recommended way to run tests in Grails. On older hardware that does not include multiple cores (to run the separate JVMs) it is recommended you disable forked execution for tests to achieve faster test execution times: {code} forkConfig = [maxMemory: 1024, minMemory: 64, debug: false, maxPerm: 256] diff --git a/src/en/guide/upgradingFrom23.gdoc b/src/en/guide/upgradingFrom23.gdoc index b6483042ff9..7d48678bb06 100644 --- a/src/en/guide/upgradingFrom23.gdoc +++ b/src/en/guide/upgradingFrom23.gdoc @@ -141,7 +141,7 @@ class SomeController { // then obj1 will be populated with values parsed from // the body instead of with values in params. - // With Grails 2.4 obj1 will be pouplated with values + // With Grails 2.4 obj1 will be populated with values // in params. def obj1 = new SomeDomainClass(params) diff --git a/src/en/guide/validation/validatingConstraints.gdoc b/src/en/guide/validation/validatingConstraints.gdoc index 5f54ff4325e..e2ca64a973f 100644 --- a/src/en/guide/validation/validatingConstraints.gdoc +++ b/src/en/guide/validation/validatingConstraints.gdoc @@ -35,7 +35,7 @@ if (user.hasErrors()) { } {code} -The second phase of validation happens when you call [validate|domainClasses] or [save|domainClasses]. This is when Grails will validate the bound values againts the [constraints|domainClasses] you defined. For example, by default the [save|domainClasses] method calls @validate@ before executing, allowing you to write code like: +The second phase of validation happens when you call [validate|domainClasses] or [save|domainClasses]. This is when Grails will validate the bound values against the [constraints|domainClasses] you defined. For example, by default the [save|domainClasses] method calls @validate@ before executing, allowing you to write code like: {code:java} if (user.save()) { diff --git a/src/en/guide/webServices/REST/hypermedia/hal.gdoc b/src/en/guide/webServices/REST/hypermedia/hal.gdoc index 63d61444769..ccd9bc97d0a 100644 --- a/src/en/guide/webServices/REST/hypermedia/hal.gdoc +++ b/src/en/guide/webServices/REST/hypermedia/hal.gdoc @@ -150,7 +150,7 @@ Date: Thu, 17 Oct 2013 02:34:14 GMT } {code} -Notice that the key associated with the list of @Book@ objects in the rendered JSON is @book@ which is derived from the type of objects in the collecion, namely @Book@. In order to customize the value of this key assign a value to the @collectionName@ property on the @HalJsonCollectionRenderer@ bean as shown below: +Notice that the key associated with the list of @Book@ objects in the rendered JSON is @book@ which is derived from the type of objects in the collection, namely @Book@. In order to customize the value of this key assign a value to the @collectionName@ property on the @HalJsonCollectionRenderer@ bean as shown below: {code} import grails.rest.render.hal.* diff --git a/src/en/guide/webServices/REST/renderers/objectMarshallerInterface.gdoc b/src/en/guide/webServices/REST/renderers/objectMarshallerInterface.gdoc index 47915549507..d0feea14b75 100644 --- a/src/en/guide/webServices/REST/renderers/objectMarshallerInterface.gdoc +++ b/src/en/guide/webServices/REST/renderers/objectMarshallerInterface.gdoc @@ -70,7 +70,7 @@ With the above change the output would now be: The Stand {code} -h4. Outputing Markup Using the Converters API or Builder +h4. Outputting Markup Using the Converters API or Builder With the passed Converter object you can explicitly code to the Converters API to stream markup to the response: diff --git a/src/en/guide/webServices/REST/renderers/objectMarshallers.gdoc b/src/en/guide/webServices/REST/renderers/objectMarshallers.gdoc index 3dc3de1d2d0..647fb23b058 100644 --- a/src/en/guide/webServices/REST/renderers/objectMarshallers.gdoc +++ b/src/en/guide/webServices/REST/renderers/objectMarshallers.gdoc @@ -9,7 +9,7 @@ XML.registerObjectMarshaller Book, { Book book, XML xml -> } {code} -You can customize the formatting of an indvidual value this way too. For example the [JodaTime plugin|http://grails.org/plugin/jodatime] does the following to support rendering of JodaTime dates in JSON output: +You can customize the formatting of an individual value this way too. For example the [JodaTime plugin|http://grails.org/plugin/jodatime] does the following to support rendering of JodaTime dates in JSON output: {code} JSON.registerObjectMarshaller(DateTime) { diff --git a/src/en/ref/Command Line/integrate-with.gdoc b/src/en/ref/Command Line/integrate-with.gdoc index b2feb3b4a2e..01543793780 100644 --- a/src/en/ref/Command Line/integrate-with.gdoc +++ b/src/en/ref/Command Line/integrate-with.gdoc @@ -32,6 +32,6 @@ eventIntegrateWithStart = { Fired Events: * @IntegrateWithStart@ - Fired when the script is first run -* @Integrate[NAME]Start@ - Fired when each integration starts (eg. IntegrateEclipseStart) -* @Integrate[NAME]End@ - Fired when each integration ends (eg. IntegrateIntellijEnd) +* @Integrate[NAME]Start@ - Fired when each integration starts (e.g. IntegrateEclipseStart) +* @Integrate[NAME]End@ - Fired when each integration ends (e.g. IntegrateIntellijEnd) * @IntegrateWithEnd@ - Fired when the script finishes diff --git a/src/en/ref/Tags/actionSubmit.gdoc b/src/en/ref/Tags/actionSubmit.gdoc index 00e349b3722..5281afeff99 100644 --- a/src/en/ref/Tags/actionSubmit.gdoc +++ b/src/en/ref/Tags/actionSubmit.gdoc @@ -71,7 +71,7 @@ This isn't too much of a problem when the form URL does not include an action na where the action specified in the mapping is either the default action of the controller, or the action specified in the @@ tag. -Also note that this tag relies on the multipart resolver to be able to inspect parameters included with mulitpart requests. If you disable the resolver by setting @grails.disableCommonsMultipart@ to true in @Config.groovy@, @actionSubmit@ will not work. +Also note that this tag relies on the multipart resolver to be able to inspect parameters included with multipart requests. If you disable the resolver by setting @grails.disableCommonsMultipart@ to true in @Config.groovy@, @actionSubmit@ will not work. h2. Source diff --git a/src/en/ref/Tags/currencySelect.gdoc b/src/en/ref/Tags/currencySelect.gdoc index e3460d7506f..dbde5fdd143 100644 --- a/src/en/ref/Tags/currencySelect.gdoc +++ b/src/en/ref/Tags/currencySelect.gdoc @@ -2,7 +2,7 @@ h1. currencySelect h2. Purpose -Generates an HTML select tag with currency symbols (eg. 'EUR', 'USD' etc.). +Generates an HTML select tag with currency symbols (e.g. 'EUR', 'USD', etc.). h2. Examples diff --git a/src/en/ref/Tags/datePicker.gdoc b/src/en/ref/Tags/datePicker.gdoc index e4fc66fa6a9..514803ad4dc 100644 --- a/src/en/ref/Tags/datePicker.gdoc +++ b/src/en/ref/Tags/datePicker.gdoc @@ -40,7 +40,7 @@ Attributes *** minute = 00 * @noSelection@ (optional) - A single-entry Map detailing the key and value to use for the "no selection made" choice in the select box. If there is no current selection this will be shown as it is first in the list, and if submitted with this selected, the key that you provide will be submitted. Typically this will be blank. * @years@ (optional) - A list or range of years to display, in the order specified. i.e. specify 2007..1900 for a reverse order list going back to 1900. If this attribute is not specified, a range of years from the current year + 100 to current year - 100 will be shown. -* @relativeYears@ (optional) - A range of int representing values relative to @value@. For example, a @relativeYears@ of [-2..7] and a @value@ of today will render a list of 10 years starting with 2 years ago through 7 years in the future. This can be useful for things like credit card expiration dates or birthdates which should be bound relative to today. +* @relativeYears@ (optional) - A range of int representing values relative to @value@. For example, a @relativeYears@ of [-2..7] and a @value@ of today will render a list of 10 years starting with 2 years ago through 7 years in the future. This can be useful for things like credit card expiration dates or birth dates which should be bound relative to today. h2. Source diff --git a/src/en/ref/Tags/formRemote.gdoc b/src/en/ref/Tags/formRemote.gdoc index 52f1cbea8cc..d50cd099793 100644 --- a/src/en/ref/Tags/formRemote.gdoc +++ b/src/en/ref/Tags/formRemote.gdoc @@ -77,7 +77,7 @@ Events * @onSuccess@ (optional) - The JavaScript function to call if successful * @onFailure@ (optional) - The JavaScript function to call if the call fails -* @on_ERROR_CODE@ (optional) - The JavaScript function to call to handle the specified error code (eg on404="alert('not found!')") +* @onERROR_CODE@ (optional) - The JavaScript function to call to handle the specified error code (e.g. @on404="alert('not found!')"@) * @onUninitialized@ (optional) - The JavaScript function to call if Ajax fails to initialise * @onLoading@ (optional) - The JavaScript function to call when the remote function loads the response * @onLoaded@ (optional) - The JavaScript function to call when the remote function completes loading the response diff --git a/src/en/ref/Tags/formatNumber.gdoc b/src/en/ref/Tags/formatNumber.gdoc index 4a5ad1b6b9c..c77d632f442 100644 --- a/src/en/ref/Tags/formatNumber.gdoc +++ b/src/en/ref/Tags/formatNumber.gdoc @@ -42,7 +42,7 @@ h2. Description Attributes -* @number@ (required) - The number object to formate +* @number@ (required) - The number object to format * @format@ (optional) - The formatting pattern to use for the number, see [DecimalFormat|api:java.text.DecimalFormat] * @formatName@ (optional) - Look up @format@ from the default MessageSource / ResourceBundle (i18n/*.properties file) with this key. Look up @format@ from the default MessageSource / ResourceBundle (i18n/*.properties file) with this key. If @format@ and @formatName@ are empty, @format@ is looked up with '@default.number.format@' key. If the key is missing, '0' formatting pattern is used. * @type@ (optional) - The type of formatter to use: 'number', 'currency' or 'percent' . @format@ or @formatName@ aren't used when @type@ is specified. diff --git a/src/en/ref/Tags/radioGroup.gdoc b/src/en/ref/Tags/radioGroup.gdoc index 0bffbe86761..353066c2ce6 100644 --- a/src/en/ref/Tags/radioGroup.gdoc +++ b/src/en/ref/Tags/radioGroup.gdoc @@ -48,7 +48,7 @@ Attributes * @name@ (required) - The name of the group * @values@ (required) - The list of values for the radio buttons * @value@ (optional) - The selected value -* @labels@ (optional) - Labels for each value contained in the @values@ list. If this is ommitted the label property on the iterator variable (see below) will default to 'Radio ' + value. +* @labels@ (optional) - Labels for each value contained in the @values@ list. If this is omitted the label property on the iterator variable (see below) will default to 'Radio ' + value. h2. Source diff --git a/src/en/ref/Tags/remoteField.gdoc b/src/en/ref/Tags/remoteField.gdoc index 45a5d57b3f4..9cedd3859ff 100644 --- a/src/en/ref/Tags/remoteField.gdoc +++ b/src/en/ref/Tags/remoteField.gdoc @@ -54,7 +54,7 @@ Events * @onSuccess@ (optional) - The JavaScript function to call if successful * @onFailure@ (optional) - The JavaScript function to call if the call fails -* @on_ERROR_CODE@ (optional) - The JavaScript function to call to handle the specified error code (eg on404="alert('not found!')") +* @onERROR_CODE@ (optional) - The JavaScript function to call to handle the specified error code (e.g. @on404="alert('not found!')"@) * @onUninitialized@ (optional) - The JavaScript function to call if Ajax fails to initialise * @onLoading@ (optional) - The JavaScript function to call when the remote function loads the response * @onLoaded@ (optional) - The JavaScript function to call when the remote function completes loading the response diff --git a/src/en/ref/Tags/remoteFunction.gdoc b/src/en/ref/Tags/remoteFunction.gdoc index 123dcd2dd84..47a0a74e55e 100644 --- a/src/en/ref/Tags/remoteFunction.gdoc +++ b/src/en/ref/Tags/remoteFunction.gdoc @@ -73,7 +73,7 @@ Events * @onSuccess@ (optional) - The JavaScript function to call if successful * @onFailure@ (optional) - The JavaScript function to call if the call fails -* @on_ERROR_CODE@ (optional) - The JavaScript function to call to handle the specified error code (eg on404="alert('not found!')") +* @onERROR_CODE@ (optional) - The JavaScript function to call to handle the specified error code (e.g. @on404="alert('not found!')"@) * @onUninitialized@ (optional) - The JavaScript function to call if Ajax fails to initialise * @onLoading@ (optional) - The JavaScript function to call when the remote function loads the response * @onLoaded@ (optional) - The JavaScript function to call when the remote function completes loading the response diff --git a/src/en/ref/Tags/remoteLink.gdoc b/src/en/ref/Tags/remoteLink.gdoc index 0859f40590a..71e82a8cf2d 100644 --- a/src/en/ref/Tags/remoteLink.gdoc +++ b/src/en/ref/Tags/remoteLink.gdoc @@ -78,7 +78,7 @@ Events * @onSuccess@ (optional) - The JavaScript function to call if successful * @onFailure@ (optional) - The JavaScript function to call if the call fails -* @on_ERROR_CODE@ (optional) - The JavaScript function to call to handle the specified error code (eg on404="alert('not found!')"). With Prototype, this prevents execution of @onSuccess@ and @onFailure@. +* @onERROR_CODE@ (optional) - The JavaScript function to call to handle the specified error code (e.g. @on404="alert('not found!')"@). With Prototype, this prevents execution of @onSuccess@ and @onFailure@. * @onUninitialized@ (optional) - The JavaScript function to call if Ajax fails to initialise * @onLoading@ (optional) - The JavaScript function to call when the remote function loads the response * @onLoaded@ (optional) - The JavaScript function to call when the remote function completes loading the response diff --git a/src/en/ref/Tags/select.gdoc b/src/en/ref/Tags/select.gdoc index 55bdad2f9e0..d4b3cfef0ba 100644 --- a/src/en/ref/Tags/select.gdoc +++ b/src/en/ref/Tags/select.gdoc @@ -84,7 +84,7 @@ If you specify an @optionKey@ then be aware that you should use that property in name="book" from="${bookList}" /> {code} -In this case, @value@ should contain the ID of @favouriteBook@ rather than the book object itself because @optionKey@ is set to the @id@ property. +In this case, @value@ should contain the ID of @favoriteBook@ rather than the book object itself because @optionKey@ is set to the @id@ property. h2. Source diff --git a/src/en/ref/Tags/submitToRemote.gdoc b/src/en/ref/Tags/submitToRemote.gdoc index 093c0fdaee8..4fd8ed461a9 100644 --- a/src/en/ref/Tags/submitToRemote.gdoc +++ b/src/en/ref/Tags/submitToRemote.gdoc @@ -50,7 +50,7 @@ Events * @onSuccess@ (optional) - The JavaScript function to call if successful * @onFailure@ (optional) - The JavaScript function to call if the call fails -* @on_ERROR_CODE@ (optional) - The JavaScript function to call to handle the specified error code (eg on404="alert('not found!')") +* @onERROR_CODE@ (optional) - The JavaScript function to call to handle the specified error code (e.g. @on404="alert('not found!')"@) * @onUninitialized@ (optional) - The JavaScript function to call if Ajax fails to initialise * @onLoading@ (optional) - The JavaScript function to call when the remote function loads the response * @onLoaded@ (optional) - The JavaScript function to call when the remote function completes loading the response From 71dc6db4dc96a24ff9995a8884f8bb5dc54b478a Mon Sep 17 00:00:00 2001 From: Lari Hotari Date: Tue, 29 Jul 2014 21:34:00 -0500 Subject: [PATCH 011/230] gopivotal.com -> pivotal.io --- resources/doc.properties | 2 +- src/en/guide/conf/docengine.gdoc | 4 ++-- src/es/guide/conf/docengine.gdoc | 8 ++++---- src/fr/guide/conf/docengine.gdoc | 4 ++-- src/pt_PT/guide/conf/docengine.gdoc | 4 ++-- src/th/guide/conf/docengine.gdoc | 4 ++-- src/zh_CN/guide/conf/docengine.gdoc | 4 ++-- src/zh_TW/guide/conf/docengine.gdoc | 4 ++-- 8 files changed, 17 insertions(+), 17 deletions(-) diff --git a/resources/doc.properties b/resources/doc.properties index 5de240adff5..7e2325e2bc5 100644 --- a/resources/doc.properties +++ b/resources/doc.properties @@ -2,7 +2,7 @@ title=The Grails Framework subtitle=See the light - agile, industrial strength, rapid web application development made easy authors=Graeme Rocher, Peter Ledbrook, Marc Palmer, Jeff Brown, Luke Daley, Burt Beckwith, Lari Hotari copyright=Copies of this document may be made for your own use and for distribution to others, provided that you do not charge any fee for such copies and further provided that each copy contains this Copyright Notice, whether distributed in print or electronically. -footer=Sponsored by Pivotal +footer=Sponsored by Pivotal # aliases are used in links to bind to a more specific topic name such as [GSP|guide:gsp] alias.resources=6.2.5 Static Resources alias.ajax=6.7 Ajax diff --git a/src/en/guide/conf/docengine.gdoc b/src/en/guide/conf/docengine.gdoc index 69047ba85ff..bca94666cab 100644 --- a/src/en/guide/conf/docengine.gdoc +++ b/src/en/guide/conf/docengine.gdoc @@ -122,13 +122,13 @@ h5. Linking There are several ways to create links with the documentation generator. A basic external link can either be defined using confluence or textile style markup: {code} -[Pivotal|http://www.gopivotal.com/oss] +[Pivotal|http://www.pivotal.io/oss] {code} or {code} -"Pivotal":http://www.gopivotal.com/oss +"Pivotal":http://www.pivotal.io/oss {code} For links to other sections inside the user guide you can use the @guide:@ prefix with the name of the section you want to link to: diff --git a/src/es/guide/conf/docengine.gdoc b/src/es/guide/conf/docengine.gdoc index 2684ba24453..ccd4de8a110 100644 --- a/src/es/guide/conf/docengine.gdoc +++ b/src/es/guide/conf/docengine.gdoc @@ -170,13 +170,13 @@ h5. Linking There are several ways to create links with the documentation generator. A basic external link can either be defined using confluence or textile style markup: {code} -[Pivotal|http://www.gopivotal.com/oss] +[Pivotal|http://www.pivotal.io/oss] {code} or {code} -"Pivotal":http://www.gopivotal.com/oss +"Pivotal":http://www.pivotal.io/oss {code} {hidden} @@ -185,13 +185,13 @@ h5. Enlazando Hay varias formas de crear vínculos con el generador de documentación. Un enlace externo básico puede definirse mediante el estilo marcado de Confluence o Textile: {code} -[Pivotal|http://www.gopivotal.com/oss] +[Pivotal|http://www.pivotal.io/oss] {code} o {code} -"Pivotal":http://www.gopivotal.com/oss +"Pivotal":http://www.pivotal.io/oss {code} {hidden} diff --git a/src/fr/guide/conf/docengine.gdoc b/src/fr/guide/conf/docengine.gdoc index 1134d336706..0d20f9c74dc 100644 --- a/src/fr/guide/conf/docengine.gdoc +++ b/src/fr/guide/conf/docengine.gdoc @@ -97,13 +97,13 @@ h5. Linking There are several ways to create links with the documentation generator. A basic external link can either be defined using confluence or textile style markup: {code} -[Pivotal|http://www.gopivotal.com/oss] +[Pivotal|http://www.pivotal.io/oss] {code} or {code} -"Pivotal":http://www.gopivotal.com/oss +"Pivotal":http://www.pivotal.io/oss {code} For links to other sections inside the user guide you can use the @guide:@ prefix with the name of the section you want to link to: diff --git a/src/pt_PT/guide/conf/docengine.gdoc b/src/pt_PT/guide/conf/docengine.gdoc index 1134d336706..0d20f9c74dc 100644 --- a/src/pt_PT/guide/conf/docengine.gdoc +++ b/src/pt_PT/guide/conf/docengine.gdoc @@ -97,13 +97,13 @@ h5. Linking There are several ways to create links with the documentation generator. A basic external link can either be defined using confluence or textile style markup: {code} -[Pivotal|http://www.gopivotal.com/oss] +[Pivotal|http://www.pivotal.io/oss] {code} or {code} -"Pivotal":http://www.gopivotal.com/oss +"Pivotal":http://www.pivotal.io/oss {code} For links to other sections inside the user guide you can use the @guide:@ prefix with the name of the section you want to link to: diff --git a/src/th/guide/conf/docengine.gdoc b/src/th/guide/conf/docengine.gdoc index 1134d336706..0d20f9c74dc 100644 --- a/src/th/guide/conf/docengine.gdoc +++ b/src/th/guide/conf/docengine.gdoc @@ -97,13 +97,13 @@ h5. Linking There are several ways to create links with the documentation generator. A basic external link can either be defined using confluence or textile style markup: {code} -[Pivotal|http://www.gopivotal.com/oss] +[Pivotal|http://www.pivotal.io/oss] {code} or {code} -"Pivotal":http://www.gopivotal.com/oss +"Pivotal":http://www.pivotal.io/oss {code} For links to other sections inside the user guide you can use the @guide:@ prefix with the name of the section you want to link to: diff --git a/src/zh_CN/guide/conf/docengine.gdoc b/src/zh_CN/guide/conf/docengine.gdoc index 3b84970a101..391a1f1c63b 100644 --- a/src/zh_CN/guide/conf/docengine.gdoc +++ b/src/zh_CN/guide/conf/docengine.gdoc @@ -99,13 +99,13 @@ h5. Linking There are several ways to create links with the documentation generator. A basic external link can either be defined using confluence or textile style markup: {code} -[Pivotal|http://www.gopivotal.com/oss] +[Pivotal|http://www.pivotal.io/oss] {code} or {code} -"Pivotal":http://www.gopivotal.com/oss +"Pivotal":http://www.pivotal.io/oss {code} For links to other sections inside the user guide you can use the @guide:@ prefix with the name of the section you want to link to: diff --git a/src/zh_TW/guide/conf/docengine.gdoc b/src/zh_TW/guide/conf/docengine.gdoc index 3b84970a101..391a1f1c63b 100644 --- a/src/zh_TW/guide/conf/docengine.gdoc +++ b/src/zh_TW/guide/conf/docengine.gdoc @@ -99,13 +99,13 @@ h5. Linking There are several ways to create links with the documentation generator. A basic external link can either be defined using confluence or textile style markup: {code} -[Pivotal|http://www.gopivotal.com/oss] +[Pivotal|http://www.pivotal.io/oss] {code} or {code} -"Pivotal":http://www.gopivotal.com/oss +"Pivotal":http://www.pivotal.io/oss {code} For links to other sections inside the user guide you can use the @guide:@ prefix with the name of the section you want to link to: From 329846f206bb5195ae095ef2ed5711a21eaf97c4 Mon Sep 17 00:00:00 2001 From: Jeff Scott Brown Date: Sun, 3 Aug 2014 15:11:13 -0500 Subject: [PATCH 012/230] use grails 2.4.4.BUILD-SNAPSHOT --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index b06d7990921..1733adab2ca 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,6 @@ apply plugin: "base" -version = System.getProperty("grails.version") ?: "2.4.3.BUILD-SNAPSHOT" +version = System.getProperty("grails.version") ?: "2.4.4.BUILD-SNAPSHOT" archivesBaseName = "grails-docs" @@ -22,7 +22,7 @@ buildscript { } dependencies { - classpath "org.grails:grails-docs:2.4.3.BUILD-SNAPSHOT" + classpath "org.grails:grails-docs:2.4.4.BUILD-SNAPSHOT" classpath 'org.codehaus.groovy:groovy-all:2.3.0' } } From f44d2a9f0e07dc91e312aee9446c235f33128162 Mon Sep 17 00:00:00 2001 From: Lari Hotari Date: Wed, 6 Aug 2014 12:23:12 +0300 Subject: [PATCH 013/230] fix docs for g:each tag - after commit 8805bc6ef g:each tag was changed to use a for loop --- src/en/ref/Tags/each.gdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/en/ref/Tags/each.gdoc b/src/en/ref/Tags/each.gdoc index 37e994b0b0a..4294b67ee6d 100644 --- a/src/en/ref/Tags/each.gdoc +++ b/src/en/ref/Tags/each.gdoc @@ -2,7 +2,7 @@ h1. each h2. Purpose -Uses the Groovy JDK [each|http://groovy.codehaus.org/groovy-jdk/java/lang/Object.html#each(groovy.lang.Closure)] method to iterate over each element of the specified object. +Uses a "for(var in collection)" loop to iterate over each element of the specified object. h2. Examples From ed4b3f88ff270bf8364fb42d52c487111fe35741 Mon Sep 17 00:00:00 2001 From: Lari Hotari Date: Wed, 6 Aug 2014 12:51:17 +0300 Subject: [PATCH 014/230] update groovy API doc url --- resources/doc.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/doc.properties b/resources/doc.properties index 8327e3adb16..dfea64f9d61 100644 --- a/resources/doc.properties +++ b/resources/doc.properties @@ -88,7 +88,7 @@ api.org.hibernate=http://docs.jboss.org/hibernate/core/3.6/javadocs api.org.springframework=http://docs.spring.io/spring/docs/4.0.x/javadoc-api api.javax.servlet=http://download.oracle.com/javaee/1.4/api api.java.=http://docs.oracle.com/javase/6/docs/api -api.groovy.=http://beta.groovy-lang.org/docs/groovy-2.3.0/html/api +api.groovy.=http://docs.groovy-lang.org/docs/latest/html/api api.org.codehaus.groovy.grails=http://grails.org/doc/2.4.x/api api.grails.=http://grails.org/doc/2.4.x/api api.org.grails.=http://grails.org/doc/2.4.x/api From 5405326ae4f7b27d613d42d7623aef90f7b68fd8 Mon Sep 17 00:00:00 2001 From: Jeff Scott Brown Date: Tue, 19 Aug 2014 09:41:23 -0500 Subject: [PATCH 015/230] GRAILS-11671 - document DirtiesRuntime annotation --- src/en/guide/testing/unitTesting.gdoc | 29 ++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/src/en/guide/testing/unitTesting.gdoc b/src/en/guide/testing/unitTesting.gdoc index 90c775db8b9..4fe5795f6b1 100644 --- a/src/en/guide/testing/unitTesting.gdoc +++ b/src/en/guide/testing/unitTesting.gdoc @@ -182,11 +182,38 @@ class MockedBeanSpec extends Specification { } {code} +h4. The DirtiesRuntime annotation + +Test methods may be marked with the @[grails.test.runtime.DirtiesRuntime|api:grails.test.runtime.DirtiesRuntime]@ annotation to indicate that the test modifies the runtime in ways which might be problematic for other tests and as such the runtime should be refreshed after this test method runs. + +{code} +import grails.test.mixin.TestFor +import spock.lang.Specification +import grails.test.runtime.DirtiesRuntime + +@TestFor(PersonController) +class PersonControllerSpec extends Specification { + + @DirtiesRuntime + void "a test method which modifies the runtime"() { + when: + Person.metaClass.someMethod = { ... } + // ... + + then: + // ... + } + + void "a test method which should not be affected by the previous test method"() { + // ... + } +} +{code} h4. Sharing test runtime grailsApplication instance and beans for several test classes It's possible to share a single grailsApplication instance and beans for several test classes. -This feature is activated by the @[SharedRuntime|api:grails.test.runtime.SharedRuntime]@ annotation. This annotation takes an optional class parameter +This feature is activated by the @[SharedRuntime|api:grails.test.runtime.SharedRuntime]@ annotation. This annotation takes an optional class parameter implements @[SharedRuntimeConfigurer|api:grails.test.runtime.SharedRuntimeConfigurer]@ interface. All test classes referencing the same SharedRuntimeConfigurer implementation class will share the same runtime during a single test run. The value class for SharedRuntimeConfigurer annotation can also implement @[TestEventInterceptor|api:grails.test.runtime.TestEventInterceptor]@ . In this case the instance of the class From c81cb075a09e118f530e4d033cb729aa03630c3a Mon Sep 17 00:00:00 2001 From: Marcin Swierczynski Date: Tue, 2 Sep 2014 19:56:43 +0200 Subject: [PATCH 016/230] Fix improper example referral in Example C of ManyToOneAndOneToOne section --- .../domainClasses/gormAssociation/manyToOneAndOneToOne.gdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/en/guide/GORM/domainClasses/gormAssociation/manyToOneAndOneToOne.gdoc b/src/en/guide/GORM/domainClasses/gormAssociation/manyToOneAndOneToOne.gdoc index 08dcb6637c3..dc17ed95654 100644 --- a/src/en/guide/GORM/domainClasses/gormAssociation/manyToOneAndOneToOne.gdoc +++ b/src/en/guide/GORM/domainClasses/gormAssociation/manyToOneAndOneToOne.gdoc @@ -64,7 +64,7 @@ class Nose { } {code} -Note that using this property puts the foreign key on the inverse table to the previous example, so in this case the foreign key column is stored in the @nose@ table inside a column called @face_id@. Also, @hasOne@ only works with bidirectional relationships. +Note that using this property puts the foreign key on the inverse table to the example A, so in this case the foreign key column is stored in the @nose@ table inside a column called @face_id@. Also, @hasOne@ only works with bidirectional relationships. Finally, it's a good idea to add a unique constraint on one side of the one-to-one relationship: From c6f3568f3c3fc3e26f9e3944acf8c4fecb032fc1 Mon Sep 17 00:00:00 2001 From: pbchekin Date: Thu, 9 Oct 2014 10:41:07 -0700 Subject: [PATCH 017/230] Update logging.gdoc Added missing comma in example of using 'additivity' for a logger --- src/en/guide/conf/config/logging.gdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/en/guide/conf/config/logging.gdoc b/src/en/guide/conf/config/logging.gdoc index 7f91a320fc1..804f9792f49 100644 --- a/src/en/guide/conf/config/logging.gdoc +++ b/src/en/guide/conf/config/logging.gdoc @@ -413,7 +413,7 @@ log4j = { ... } - info additivity: false + info additivity: false, stdout: \["grails.app.controllers.BookController", "grails.app.services.BookService"\] } From 1699f0369cb656a247bb93b6d0ba8a6985d899b1 Mon Sep 17 00:00:00 2001 From: chapmajs Date: Tue, 14 Oct 2014 11:34:40 -0400 Subject: [PATCH 018/230] Add a note about singleton controllers I've wasted several days on the change introduced here: https://jira.grails.org/browse/GRAILS-10113 This addition to the Grails documentation would've saved a lot of headache. --- src/en/guide/services/scopedServices.gdoc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/en/guide/services/scopedServices.gdoc b/src/en/guide/services/scopedServices.gdoc index e8d8f2052b8..6f5079d848f 100644 --- a/src/en/guide/services/scopedServices.gdoc +++ b/src/en/guide/services/scopedServices.gdoc @@ -19,3 +19,7 @@ To enable one of the scopes, add a static scope property to your class whose val {code:java} static scope = "flow" {code} + +{note} +For new Grails apps since 2.3, default controller scope is @singleton@, resulting in @prototype@ scope services that are effectively per-controller singletons. If non-singleton services are required, controller scope should be changed as well. +{note} From f58eee242d3e225337094c3d3b63fbfaee836bf3 Mon Sep 17 00:00:00 2001 From: Silvio Wangler Date: Thu, 30 Oct 2014 08:03:19 +0100 Subject: [PATCH 019/230] Replaced invalid link http://textile.sitemonks.com/ with valid Textile Markup hyperlink --- src/en/guide/conf/docengine.gdoc | 2 +- src/es/guide/conf/docengine.gdoc | 4 ++-- src/fr/guide/conf/docengine.gdoc | 2 +- src/pt_PT/guide/conf/docengine.gdoc | 2 +- src/th/guide/conf/docengine.gdoc | 2 +- src/zh_CN/guide/conf/docengine.gdoc | 2 +- src/zh_TW/guide/conf/docengine.gdoc | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/en/guide/conf/docengine.gdoc b/src/en/guide/conf/docengine.gdoc index 022278895d9..b612f19038c 100644 --- a/src/en/guide/conf/docengine.gdoc +++ b/src/en/guide/conf/docengine.gdoc @@ -1,6 +1,6 @@ Since Grails 1.2, the documentation engine that powers the creation of this documentation has been available for your own Grails projects. -The documentation engine uses a variation on the [Textile|http://textile.sitemonks.com/] syntax to automatically create project documentation with smart linking, formatting etc. +The documentation engine uses a variation on the [Textile|http://txstyle.org/] syntax to automatically create project documentation with smart linking, formatting etc. h4. Creating project documentation diff --git a/src/es/guide/conf/docengine.gdoc b/src/es/guide/conf/docengine.gdoc index ccd4de8a110..32b2fb2c1e8 100644 --- a/src/es/guide/conf/docengine.gdoc +++ b/src/es/guide/conf/docengine.gdoc @@ -2,7 +2,7 @@ Since Grails 1.2, the documentation engine that powers the creation of this documentation has been available for your own Grails projects. -The documentation engine uses a variation on the [Textile|http://textile.sitemonks.com/] syntax to automatically create project documentation with smart linking, formatting etc. +The documentation engine uses a variation on the [Textile|http://txstyle.org/] syntax to automatically create project documentation with smart linking, formatting etc. h4. Creating project documentation @@ -12,7 +12,7 @@ To use the engine you need to follow a few conventions. First, you need to creat Desde Grails 1.2, el motor de documentación usado para la creación de esta documentación ha estado disponible para sus propios proyectos de Grails. -El motor de documentación utiliza una variación de la sintaxis de [Textile|http://textile.sitemonks.com/] para crear automáticamente la documentación del proyecto con enlaces, formato, etc.. +El motor de documentación utiliza una variación de la sintaxis de [Textile|http://txstyle.org/] para crear automáticamente la documentación del proyecto con enlaces, formato, etc.. h4. Creación de documentación del proyecto diff --git a/src/fr/guide/conf/docengine.gdoc b/src/fr/guide/conf/docengine.gdoc index 0d20f9c74dc..00c48dc8602 100644 --- a/src/fr/guide/conf/docengine.gdoc +++ b/src/fr/guide/conf/docengine.gdoc @@ -1,6 +1,6 @@ Since Grails 1.2, the documentation engine that powers the creation of this documentation has been available for your own Grails projects. -The documentation engine uses a variation on the [Textile|http://textile.sitemonks.com/] syntax to automatically create project documentation with smart linking, formatting etc. +The documentation engine uses a variation on the [Textile|http://txstyle.org/] syntax to automatically create project documentation with smart linking, formatting etc. h4. Creating project documentation diff --git a/src/pt_PT/guide/conf/docengine.gdoc b/src/pt_PT/guide/conf/docengine.gdoc index 0d20f9c74dc..00c48dc8602 100644 --- a/src/pt_PT/guide/conf/docengine.gdoc +++ b/src/pt_PT/guide/conf/docengine.gdoc @@ -1,6 +1,6 @@ Since Grails 1.2, the documentation engine that powers the creation of this documentation has been available for your own Grails projects. -The documentation engine uses a variation on the [Textile|http://textile.sitemonks.com/] syntax to automatically create project documentation with smart linking, formatting etc. +The documentation engine uses a variation on the [Textile|http://txstyle.org/] syntax to automatically create project documentation with smart linking, formatting etc. h4. Creating project documentation diff --git a/src/th/guide/conf/docengine.gdoc b/src/th/guide/conf/docengine.gdoc index 0d20f9c74dc..00c48dc8602 100644 --- a/src/th/guide/conf/docengine.gdoc +++ b/src/th/guide/conf/docengine.gdoc @@ -1,6 +1,6 @@ Since Grails 1.2, the documentation engine that powers the creation of this documentation has been available for your own Grails projects. -The documentation engine uses a variation on the [Textile|http://textile.sitemonks.com/] syntax to automatically create project documentation with smart linking, formatting etc. +The documentation engine uses a variation on the [Textile|http://txstyle.org/] syntax to automatically create project documentation with smart linking, formatting etc. h4. Creating project documentation diff --git a/src/zh_CN/guide/conf/docengine.gdoc b/src/zh_CN/guide/conf/docengine.gdoc index 391a1f1c63b..a222b8be798 100644 --- a/src/zh_CN/guide/conf/docengine.gdoc +++ b/src/zh_CN/guide/conf/docengine.gdoc @@ -1,6 +1,6 @@ Since Grails 1.2, the documentation engine that powers the creation of this documentation has been available for your own Grails projects. -The documentation engine uses a variation on the [Textile|http://textile.sitemonks.com/] syntax to automatically create project documentation with smart linking, formatting etc. +The documentation engine uses a variation on the [Textile|http://txstyle.org/] syntax to automatically create project documentation with smart linking, formatting etc. h4. Creating project documentation diff --git a/src/zh_TW/guide/conf/docengine.gdoc b/src/zh_TW/guide/conf/docengine.gdoc index 391a1f1c63b..a222b8be798 100644 --- a/src/zh_TW/guide/conf/docengine.gdoc +++ b/src/zh_TW/guide/conf/docengine.gdoc @@ -1,6 +1,6 @@ Since Grails 1.2, the documentation engine that powers the creation of this documentation has been available for your own Grails projects. -The documentation engine uses a variation on the [Textile|http://textile.sitemonks.com/] syntax to automatically create project documentation with smart linking, formatting etc. +The documentation engine uses a variation on the [Textile|http://txstyle.org/] syntax to automatically create project documentation with smart linking, formatting etc. h4. Creating project documentation From 75cf4285fda624d5fe349b13d13627452a3ad252 Mon Sep 17 00:00:00 2001 From: "Anders D. Johnson" Date: Sun, 23 Nov 2014 16:32:26 -0600 Subject: [PATCH 020/230] fix spring links with trailing period --- src/en/guide/spring.gdoc | 2 +- src/es/guide/spring.gdoc | 2 +- src/fr/guide/spring.gdoc | 2 +- src/pt_PT/guide/spring.gdoc | 2 +- src/th/guide/spring.gdoc | 2 +- src/zh_CN/guide/spring.gdoc | 2 +- src/zh_TW/guide/spring.gdoc | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/en/guide/spring.gdoc b/src/en/guide/spring.gdoc index f6c31537aeb..198b183ba65 100644 --- a/src/en/guide/spring.gdoc +++ b/src/en/guide/spring.gdoc @@ -1 +1 @@ -This section is for advanced users and those who are interested in how Grails integrates with and builds on the "Spring Framework":http://www.springframework.org/. It is also useful for [plugin developers|guide:plugins] considering doing runtime configuration Grails. +This section is for advanced users and those who are interested in how Grails integrates with and builds on the [Spring Framework|http://www.springframework.org/]. It is also useful for [plugin developers|guide:plugins] considering doing runtime configuration Grails. diff --git a/src/es/guide/spring.gdoc b/src/es/guide/spring.gdoc index f6c31537aeb..198b183ba65 100644 --- a/src/es/guide/spring.gdoc +++ b/src/es/guide/spring.gdoc @@ -1 +1 @@ -This section is for advanced users and those who are interested in how Grails integrates with and builds on the "Spring Framework":http://www.springframework.org/. It is also useful for [plugin developers|guide:plugins] considering doing runtime configuration Grails. +This section is for advanced users and those who are interested in how Grails integrates with and builds on the [Spring Framework|http://www.springframework.org/]. It is also useful for [plugin developers|guide:plugins] considering doing runtime configuration Grails. diff --git a/src/fr/guide/spring.gdoc b/src/fr/guide/spring.gdoc index f6c31537aeb..198b183ba65 100644 --- a/src/fr/guide/spring.gdoc +++ b/src/fr/guide/spring.gdoc @@ -1 +1 @@ -This section is for advanced users and those who are interested in how Grails integrates with and builds on the "Spring Framework":http://www.springframework.org/. It is also useful for [plugin developers|guide:plugins] considering doing runtime configuration Grails. +This section is for advanced users and those who are interested in how Grails integrates with and builds on the [Spring Framework|http://www.springframework.org/]. It is also useful for [plugin developers|guide:plugins] considering doing runtime configuration Grails. diff --git a/src/pt_PT/guide/spring.gdoc b/src/pt_PT/guide/spring.gdoc index f6c31537aeb..198b183ba65 100644 --- a/src/pt_PT/guide/spring.gdoc +++ b/src/pt_PT/guide/spring.gdoc @@ -1 +1 @@ -This section is for advanced users and those who are interested in how Grails integrates with and builds on the "Spring Framework":http://www.springframework.org/. It is also useful for [plugin developers|guide:plugins] considering doing runtime configuration Grails. +This section is for advanced users and those who are interested in how Grails integrates with and builds on the [Spring Framework|http://www.springframework.org/]. It is also useful for [plugin developers|guide:plugins] considering doing runtime configuration Grails. diff --git a/src/th/guide/spring.gdoc b/src/th/guide/spring.gdoc index f6c31537aeb..198b183ba65 100644 --- a/src/th/guide/spring.gdoc +++ b/src/th/guide/spring.gdoc @@ -1 +1 @@ -This section is for advanced users and those who are interested in how Grails integrates with and builds on the "Spring Framework":http://www.springframework.org/. It is also useful for [plugin developers|guide:plugins] considering doing runtime configuration Grails. +This section is for advanced users and those who are interested in how Grails integrates with and builds on the [Spring Framework|http://www.springframework.org/]. It is also useful for [plugin developers|guide:plugins] considering doing runtime configuration Grails. diff --git a/src/zh_CN/guide/spring.gdoc b/src/zh_CN/guide/spring.gdoc index f6c31537aeb..198b183ba65 100644 --- a/src/zh_CN/guide/spring.gdoc +++ b/src/zh_CN/guide/spring.gdoc @@ -1 +1 @@ -This section is for advanced users and those who are interested in how Grails integrates with and builds on the "Spring Framework":http://www.springframework.org/. It is also useful for [plugin developers|guide:plugins] considering doing runtime configuration Grails. +This section is for advanced users and those who are interested in how Grails integrates with and builds on the [Spring Framework|http://www.springframework.org/]. It is also useful for [plugin developers|guide:plugins] considering doing runtime configuration Grails. diff --git a/src/zh_TW/guide/spring.gdoc b/src/zh_TW/guide/spring.gdoc index f6c31537aeb..198b183ba65 100644 --- a/src/zh_TW/guide/spring.gdoc +++ b/src/zh_TW/guide/spring.gdoc @@ -1 +1 @@ -This section is for advanced users and those who are interested in how Grails integrates with and builds on the "Spring Framework":http://www.springframework.org/. It is also useful for [plugin developers|guide:plugins] considering doing runtime configuration Grails. +This section is for advanced users and those who are interested in how Grails integrates with and builds on the [Spring Framework|http://www.springframework.org/]. It is also useful for [plugin developers|guide:plugins] considering doing runtime configuration Grails. From 12d9973af2b7718713aaf4ee322639fa4fb79e8d Mon Sep 17 00:00:00 2001 From: "Anders D. Johnson" Date: Sun, 23 Nov 2014 20:41:32 -0600 Subject: [PATCH 021/230] fix nicknames in mapping for basic collections GORM example --- .../domainClasses/gormAssociation/basicCollectionTypes.gdoc | 2 +- .../domainClasses/gormAssociation/basicCollectionTypes.gdoc | 2 +- .../domainClasses/gormAssociation/basicCollectionTypes.gdoc | 2 +- .../domainClasses/gormAssociation/basicCollectionTypes.gdoc | 2 +- .../domainClasses/gormAssociation/basicCollectionTypes.gdoc | 2 +- .../domainClasses/gormAssociation/basicCollectionTypes.gdoc | 2 +- .../domainClasses/gormAssociation/basicCollectionTypes.gdoc | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/en/guide/GORM/domainClasses/gormAssociation/basicCollectionTypes.gdoc b/src/en/guide/GORM/domainClasses/gormAssociation/basicCollectionTypes.gdoc index 50ab3c7aece..9384099a744 100644 --- a/src/en/guide/GORM/domainClasses/gormAssociation/basicCollectionTypes.gdoc +++ b/src/en/guide/GORM/domainClasses/gormAssociation/basicCollectionTypes.gdoc @@ -15,7 +15,7 @@ class Person { static hasMany = [nicknames: String] static mapping = { - hasMany joinTable: [name: 'bunch_o_nicknames', + nicknames joinTable: [name: 'bunch_o_nicknames', key: 'person_id', column: 'nickname', type: "text"] diff --git a/src/es/guide/GORM/domainClasses/gormAssociation/basicCollectionTypes.gdoc b/src/es/guide/GORM/domainClasses/gormAssociation/basicCollectionTypes.gdoc index 50ab3c7aece..9384099a744 100644 --- a/src/es/guide/GORM/domainClasses/gormAssociation/basicCollectionTypes.gdoc +++ b/src/es/guide/GORM/domainClasses/gormAssociation/basicCollectionTypes.gdoc @@ -15,7 +15,7 @@ class Person { static hasMany = [nicknames: String] static mapping = { - hasMany joinTable: [name: 'bunch_o_nicknames', + nicknames joinTable: [name: 'bunch_o_nicknames', key: 'person_id', column: 'nickname', type: "text"] diff --git a/src/fr/guide/GORM/domainClasses/gormAssociation/basicCollectionTypes.gdoc b/src/fr/guide/GORM/domainClasses/gormAssociation/basicCollectionTypes.gdoc index 50ab3c7aece..9384099a744 100644 --- a/src/fr/guide/GORM/domainClasses/gormAssociation/basicCollectionTypes.gdoc +++ b/src/fr/guide/GORM/domainClasses/gormAssociation/basicCollectionTypes.gdoc @@ -15,7 +15,7 @@ class Person { static hasMany = [nicknames: String] static mapping = { - hasMany joinTable: [name: 'bunch_o_nicknames', + nicknames joinTable: [name: 'bunch_o_nicknames', key: 'person_id', column: 'nickname', type: "text"] diff --git a/src/pt_PT/guide/GORM/domainClasses/gormAssociation/basicCollectionTypes.gdoc b/src/pt_PT/guide/GORM/domainClasses/gormAssociation/basicCollectionTypes.gdoc index 50ab3c7aece..9384099a744 100644 --- a/src/pt_PT/guide/GORM/domainClasses/gormAssociation/basicCollectionTypes.gdoc +++ b/src/pt_PT/guide/GORM/domainClasses/gormAssociation/basicCollectionTypes.gdoc @@ -15,7 +15,7 @@ class Person { static hasMany = [nicknames: String] static mapping = { - hasMany joinTable: [name: 'bunch_o_nicknames', + nicknames joinTable: [name: 'bunch_o_nicknames', key: 'person_id', column: 'nickname', type: "text"] diff --git a/src/th/guide/GORM/domainClasses/gormAssociation/basicCollectionTypes.gdoc b/src/th/guide/GORM/domainClasses/gormAssociation/basicCollectionTypes.gdoc index 50ab3c7aece..9384099a744 100644 --- a/src/th/guide/GORM/domainClasses/gormAssociation/basicCollectionTypes.gdoc +++ b/src/th/guide/GORM/domainClasses/gormAssociation/basicCollectionTypes.gdoc @@ -15,7 +15,7 @@ class Person { static hasMany = [nicknames: String] static mapping = { - hasMany joinTable: [name: 'bunch_o_nicknames', + nicknames joinTable: [name: 'bunch_o_nicknames', key: 'person_id', column: 'nickname', type: "text"] diff --git a/src/zh_CN/guide/GORM/domainClasses/gormAssociation/basicCollectionTypes.gdoc b/src/zh_CN/guide/GORM/domainClasses/gormAssociation/basicCollectionTypes.gdoc index 50ab3c7aece..9384099a744 100644 --- a/src/zh_CN/guide/GORM/domainClasses/gormAssociation/basicCollectionTypes.gdoc +++ b/src/zh_CN/guide/GORM/domainClasses/gormAssociation/basicCollectionTypes.gdoc @@ -15,7 +15,7 @@ class Person { static hasMany = [nicknames: String] static mapping = { - hasMany joinTable: [name: 'bunch_o_nicknames', + nicknames joinTable: [name: 'bunch_o_nicknames', key: 'person_id', column: 'nickname', type: "text"] diff --git a/src/zh_TW/guide/GORM/domainClasses/gormAssociation/basicCollectionTypes.gdoc b/src/zh_TW/guide/GORM/domainClasses/gormAssociation/basicCollectionTypes.gdoc index 50ab3c7aece..9384099a744 100644 --- a/src/zh_TW/guide/GORM/domainClasses/gormAssociation/basicCollectionTypes.gdoc +++ b/src/zh_TW/guide/GORM/domainClasses/gormAssociation/basicCollectionTypes.gdoc @@ -15,7 +15,7 @@ class Person { static hasMany = [nicknames: String] static mapping = { - hasMany joinTable: [name: 'bunch_o_nicknames', + nicknames joinTable: [name: 'bunch_o_nicknames', key: 'person_id', column: 'nickname', type: "text"] From 62c22341763725a86723192673d8ba55b8e03470 Mon Sep 17 00:00:00 2001 From: Jeff Scott Brown Date: Mon, 22 Dec 2014 19:08:42 -0600 Subject: [PATCH 022/230] start laying out placeholders for 3.0 docs --- build.gradle | 4 ++-- src/en/guide/introduction/whatsNew30.gdoc | 9 +++++++++ src/en/guide/toc.yml | 1 + 3 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 src/en/guide/introduction/whatsNew30.gdoc diff --git a/build.gradle b/build.gradle index 1733adab2ca..b68991f188f 100644 --- a/build.gradle +++ b/build.gradle @@ -1,12 +1,12 @@ apply plugin: "base" -version = System.getProperty("grails.version") ?: "2.4.4.BUILD-SNAPSHOT" +version = System.getProperty("grails.version") ?: "3.0.0.BUILD-SNAPSHOT" archivesBaseName = "grails-docs" ext.checkOutDir = "${buildDir.path}/checkout" ext.outputDir = "${buildDir.path}/docs" -ext.githubBranch = "2.4.x" +ext.githubBranch = "master" ext.explicitGrailsHome = System.getProperty("grails.home") ext.grailsHome = explicitGrailsHome ? file(explicitGrailsHome).absolutePath : "$checkOutDir/grails-src" diff --git a/src/en/guide/introduction/whatsNew30.gdoc b/src/en/guide/introduction/whatsNew30.gdoc new file mode 100644 index 00000000000..54077a0fe24 --- /dev/null +++ b/src/en/guide/introduction/whatsNew30.gdoc @@ -0,0 +1,9 @@ +h4. Groovy 2.4 + +Grails 3.0 comes with Groovy 2.4 which includes many new features and enhancements. + +For more information on Groovy 2.3, see the (TBD). + +h4. Spring 4.2 + +Grails 3.0 comes with Spring 4.2 which includes many new features and enhancements. See the (TBD). diff --git a/src/en/guide/toc.yml b/src/en/guide/toc.yml index 769f58d4220..370f9b714b8 100644 --- a/src/en/guide/toc.yml +++ b/src/en/guide/toc.yml @@ -1,5 +1,6 @@ introduction: title: Introduction + whatsNew30: What's new in Grails 3.0? whatsNew24: What's new in Grails 2.4? whatsNew23: What's new in Grails 2.3? whatsNew22: What's new in Grails 2.2? From 988bb9d24bb78ca07ad9d385ece3dc278472747c Mon Sep 17 00:00:00 2001 From: Jeff Scott Brown Date: Mon, 22 Dec 2014 19:17:27 -0600 Subject: [PATCH 023/230] add some notes about Validateable trait --- .../unitTesting/unitTestingDomains.gdoc | 79 +++---------------- .../controllers/commandObjects.gdoc | 19 ++--- 2 files changed, 19 insertions(+), 79 deletions(-) diff --git a/src/en/guide/testing/unitTesting/unitTestingDomains.gdoc b/src/en/guide/testing/unitTesting/unitTestingDomains.gdoc index d53766c8044..1eeaa070f68 100644 --- a/src/en/guide/testing/unitTesting/unitTestingDomains.gdoc +++ b/src/en/guide/testing/unitTesting/unitTestingDomains.gdoc @@ -1,8 +1,8 @@ h4. Overview -Domain class interaction can be tested without involving a real database connection using @DomainClassUnitTestMixin@ or by using the @HibernateTestMixin@. +Domain class interaction can be tested without involving a real database connection using @DomainClassUnitTestMixin@ or by using the @HibernateTestMixin@. -The GORM implementation in DomainClassUnitTestMixin is using a simple in-memory @ConcurrentHashMap@ implementation. Note that this has limitations compared to a real GORM implementation. +The GORM implementation in DomainClassUnitTestMixin is using a simple in-memory @ConcurrentHashMap@ implementation. Note that this has limitations compared to a real GORM implementation. A large, commonly-used portion of the GORM API can be mocked using @DomainClassUnitTestMixin@ including: @@ -12,7 +12,7 @@ A large, commonly-used portion of the GORM API can be mocked using @DomainClassU * Query-by-example * GORM Events -@HibernateTestMixin@ uses Hibernate 4 and a H2 in-memory database. This makes it possible to use all GORM features also in Grails unit tests. +@HibernateTestMixin@ uses Hibernate 4 and a H2 in-memory database. This makes it possible to use all GORM features also in Grails unit tests. All features of GORM for Hibernate can be tested within a @HibernateTestMixin@ unit test including: @@ -21,7 +21,7 @@ All features of GORM for Hibernate can be tested within a @HibernateTestMixin@ u * dirty checking methods * any direct interaction with Hibernate -The implementation behind @HibernateTestMixin@ takes care of setting up the Hibernate with the in-memory H2 database. It only configures the given domain classes for use in a unit test. The @Domain annotation is used to tell which domain classes should be configured. +The implementation behind @HibernateTestMixin@ takes care of setting up the Hibernate with the in-memory H2 database. It only configures the given domain classes for use in a unit test. The @Domain annotation is used to tell which domain classes should be configured. h4. DomainClassUnitTestMixin Basics @@ -155,21 +155,19 @@ The @mockDomain@ method also includes an additional parameter that lets you pass h4. Testing Constraints -There are 4 types of validateable classes: +There are 3 types of validateable classes: # Domain classes -# Classes marked with the @Validateable@ annotation +# Classes which implement the @Validateable@ trait # Command Objects which have been made validateable automatically -# Classes configured to be validateable via the @grails.validateable.classes@ property in @Config.groovy@ -The first 3 are easily testable in a unit test with no special configuration necessary as long as the test method is marked with @TestFor@ or explicitly applies the @GrailsUnitTestMixin@ using @TestMixin@. See the examples below. +These are all easily testable in a unit test with no special configuration necessary as long as the test method is marked with @TestFor@ or explicitly applies the @GrailsUnitTestMixin@ using @TestMixin@. See the examples below. {code:java} // src/groovy/com/demo/MyValidateable.groovy package com.demo -@grails.validation.Validateable -class MyValidateable { +class MyValidateable implements grails.validation.trait.Validateable { String name Integer age @@ -367,65 +365,6 @@ class MyCommandObjectSpec extends Specification { } {code} -For validateable classes which are not one of the first 3 types listed above but are configured with the @grails.validateable.classes@ property in @Config.groovy@, one additional step is required to test validation. @GrailsUnitTestMixin@ provides a method named @mockForConstraintsTests@ that will mock validation support for these classes. See the example below. - -{code:java} -// src/groovy/com/demo/Book.groovy -package com.demo - -class Book { - String title - String author - - static constraints = { - author minSize: 5 - } -} -{code} - -{code:java} -// grails-app/conf/Config.groovy -grails.validateable.classes = [com.demo.Book] - -// ... -{code} - -{code:java} -// test/unit/com/demo/BookSpec.groovy -package com.demo - -import grails.test.mixin.TestMixin -import grails.test.mixin.support.GrailsUnitTestMixin -import spock.lang.Specification - -@TestMixin(GrailsUnitTestMixin) -class BookSpec extends Specification { - - void 'Test validation'() { - given: - mockForConstraintsTests Book - - when: 'the author name has only 4 characters' - def book = new Book() - book.author = 'Jeff' - - then: 'validation should fail' - !book.validate() - book.hasErrors() - book.errors['author'] == 'minSize' - - when: 'the author name has 5 characters' - book.author = 'Jacob' - - then: 'validation should pass' - book.validate() - !book.hasErrors() - } -} -{code} - -Note that the @mockForConstraintsTests@ method changes the behavior of the errors object such that something like @book.errors['author']@ will evaluate to the name of the failed constraint, not a @org.springframework.validation.FieldError@ object. This is convenient for unit tests. If your unit test really does want a reference to the @org.springframework.validation.FieldError@ object use something like @book.errors.getFieldError('author')@. - That's it for testing constraints. One final thing we would like to say is that testing the constraints in this way catches a common error: typos in the "constraints" property name which is a mistake that is easy to make and equally easy to overlook. A unit test for your constraints will highlight the problem straight away. @@ -472,7 +411,7 @@ HibernateTestMixin is only supported with hibernate4 plugin versions >= 4.3.5.4 h4. Configuring domain classes for HibernateTestMixin tests -The @grails.test.mixin.gorm.Domain@ annotation is used to configure the list of domain classes to configure for Hibernate sessionFactory instance that gets configured when the unit test runtime is initialized. +The @grails.test.mixin.gorm.Domain@ annotation is used to configure the list of domain classes to configure for Hibernate sessionFactory instance that gets configured when the unit test runtime is initialized. @Domain@ annotations will be collected from several locations: * the annotations on the test class diff --git a/src/en/guide/theWebLayer/controllers/commandObjects.gdoc b/src/en/guide/theWebLayer/controllers/commandObjects.gdoc index 1727d13d846..bd5a4918b37 100644 --- a/src/en/guide/theWebLayer/controllers/commandObjects.gdoc +++ b/src/en/guide/theWebLayer/controllers/commandObjects.gdoc @@ -9,8 +9,7 @@ h4. Declaring Command Objects Command object classes are defined just like any other class. {code:java} -@grails.validation.Validateable -class LoginCommand { +class LoginCommand implements grails.validation.trait.Validateable { String username String password @@ -21,19 +20,22 @@ class LoginCommand { } {code} -In this example, the command object is marked with the @Validateable@ annotation. The @Validateable@ annotation allows the definition of [constraints|guide:constraints] just like in [domain classes|guide:GORM]. If the command object is defined in the same source file as the controller that is using it, Grails will automatically mark it as @Validateable@. It is not required that command object classes be validateable. +In this example, the command object class implements the @Validateable@ trait. The @Validateable@ trait allows the definition of [constraints|guide:constraints] just like in [domain classes|guide:GORM]. If the command object is defined in the same source file as the controller that is using it, Grails will automatically make it @Validateable@. It is not required that command object classes be validateable. -By default, all @Validateable@ object properties are @nullable: false@ which matches the behavior of GORM domain objects. If you want a @Validateable@ that has @nullable: true@ properties by default, you can specify @nullable: true@ on the annotation: +By default, all @Validateable@ object properties are @nullable: false@ which matches the behavior of GORM domain objects. If you want a @Validateable@ that has @nullable: true@ properties by default, you can specify this by defining a @defaultNullable@ method in the class: {code:java} -@grails.validation.Validateable(nullable=true) -class AuthorSearchCommand { +class AuthorSearchCommand implements grails.validation.trait.Validateable { String name Integer age + + static boolean defaultNullable() { + true + } } {code} -In this example, both @name@ and @age@ will allow null values during validation. +In this example, both @name@ and @age@ will allow null values during validation. h4. Using Command Objects @@ -131,8 +133,7 @@ h4. Command Objects and Dependency Injection Command objects can participate in dependency injection. This is useful if your command object has some custom validation logic which uses a Grails [service|guide:services]: {code} -@grails.validation.Validateable -class LoginCommand { +class LoginCommand implements grails.validation.trait.Validateable { def loginService From 3e45ca856c72a1d450e688a851a9da36f0caad38 Mon Sep 17 00:00:00 2001 From: Jeff Scott Brown Date: Mon, 22 Dec 2014 19:37:01 -0600 Subject: [PATCH 024/230] remove the 2.x whatsNew sections --- src/en/guide/introduction/whatsNew.gdoc | 2 +- .../introduction/whatsNew/coreFeatures.gdoc | 12 +- .../developmentEnvironmentFeatures.gdoc | 113 +------ .../whatsNew/persistenceFeatures.gdoc | 102 +----- .../whatsNew/testingFeatures.gdoc | 38 +-- .../introduction/whatsNew/webFeatures.gdoc | 177 +---------- src/en/guide/introduction/whatsNew21.gdoc | 73 ----- src/en/guide/introduction/whatsNew22.gdoc | 82 ----- src/en/guide/introduction/whatsNew23.gdoc | 218 ------------- src/en/guide/introduction/whatsNew24.gdoc | 291 ------------------ src/en/guide/introduction/whatsNew30.gdoc | 9 - src/en/guide/toc.yml | 9 +- 12 files changed, 12 insertions(+), 1114 deletions(-) delete mode 100644 src/en/guide/introduction/whatsNew21.gdoc delete mode 100644 src/en/guide/introduction/whatsNew22.gdoc delete mode 100644 src/en/guide/introduction/whatsNew23.gdoc delete mode 100644 src/en/guide/introduction/whatsNew24.gdoc delete mode 100644 src/en/guide/introduction/whatsNew30.gdoc diff --git a/src/en/guide/introduction/whatsNew.gdoc b/src/en/guide/introduction/whatsNew.gdoc index d9c2f99da1a..b9c9b6fbc86 100644 --- a/src/en/guide/introduction/whatsNew.gdoc +++ b/src/en/guide/introduction/whatsNew.gdoc @@ -1,2 +1,2 @@ -This section covers the new features that are present in 2.0 and is broken down into sections covering the build system, core APIs, the web tier, persistence enhancements and improvements in testing. Note there are many more small enhancements and improvements, these sections just cover some of the highlights. +This section covers the new features that are present in 3.0 and is broken down into sections covering the build system, core APIs, the web tier, persistence enhancements and improvements in testing. Note there are many more small enhancements and improvements, these sections just cover some of the highlights. diff --git a/src/en/guide/introduction/whatsNew/coreFeatures.gdoc b/src/en/guide/introduction/whatsNew/coreFeatures.gdoc index 9b88b99565d..54077a0fe24 100644 --- a/src/en/guide/introduction/whatsNew/coreFeatures.gdoc +++ b/src/en/guide/introduction/whatsNew/coreFeatures.gdoc @@ -1,11 +1,9 @@ -h4. Binary Plugins +h4. Groovy 2.4 -Grails plugins can now be packaged as JAR files and published to standard maven repositories. This even works for GSP and static resources (with resources plugin 1.0.1). See the section on [Binary plugins|guide:binaryPlugins] for more information. +Grails 3.0 comes with Groovy 2.4 which includes many new features and enhancements. -h4. Groovy 1.8 +For more information on Groovy 2.3, see the (TBD). -Grails 2.0 comes with Groovy 1.8 which includes many new [features and enhancements|http://docs.codehaus.org/display/GROOVY/Groovy+1.8+release+notes] +h4. Spring 4.2 -h4. Spring 3.1 Profile Support - -Grails' existing environment support has been bridged into the Spring 3.1 profile support. For example when running with a custom Grails environment called "production", a Spring profile of "production" is activated so that you can use Spring's bean configuration APIs to configure beans for a specific profile. \ No newline at end of file +Grails 3.0 comes with Spring 4.2 which includes many new features and enhancements. See the (TBD). diff --git a/src/en/guide/introduction/whatsNew/developmentEnvironmentFeatures.gdoc b/src/en/guide/introduction/whatsNew/developmentEnvironmentFeatures.gdoc index 05ce53c7ef0..2f4f6266cd7 100644 --- a/src/en/guide/introduction/whatsNew/developmentEnvironmentFeatures.gdoc +++ b/src/en/guide/introduction/whatsNew/developmentEnvironmentFeatures.gdoc @@ -1,112 +1 @@ -h4. Interactive Mode and Console Enhancements - -Grails 2.0 features brand new console output that is more concise and user friendly to consume. An example of the new output when running tests can be seen below: - -!test-output.png! - -In general Grails makes its best effort to display update information on a single line and only present the information that is crucial. This means that while in previous versions of Grails the [war|commandLine] command produced many lines of output, in Grails 2.0 only 1 line of output is produced: - -!war-output.png! - -In addition simply typing 'grails' at the command line activates the new interactive mode which features TAB completion, command history and keeps the JVM running to ensure commands execute much quicker than otherwise - -!interactive-output.png! - -For more information on the new features of the console refer to the section of the user guide that covers the [console and interactive mode|guide:interactiveMode]. - -h4. Reloading Agent - -Grails 2.0 reloading mechanism no longer uses class loaders, but instead uses a JVM agent to reload changes to class files. This results in greatly improved reliability when reloading changes and also ensures that the class files stored in disk remain consistent with the class files loaded in memory, which reduces the need to run the [clean|commandLine] command. - -h4. New Test Report and Documentation Templates - -There are new templates for displaying test results that are clearer and more user friendly than the previous reports: - -!test-template.png! - -In addition, the Grails documentation engine has received a facelift with a new template for presenting Grails application and plugin documentation: - -!doc-template.png! - -See the section on the [documentation engine|guide:docengine] for more usage info. - -h4. Use a TOC for Project Docs - -The old documentation engine relied on you putting section numbers into the gdoc filenames. Although convenient, this effectively made it difficult to restructure your user guide by inserting new chapters and sections. In addition, any such restructuring or renaming of section titles resulted in breaking changes to the URLs. - -You can now use logical names for your gdoc files and define the structure and section titles in a YAML table-of-contents file, as described in the section on the [documentation engine|guide:docengine]. The logical names appear in the URLs, so as long as you don't change those, your URLs will always remain the same no matter how much restructuring or changing of titles you do. - -Grails 2.0 even provides a [migrate-docs|commandLine] command to aid you in migrating existing gdoc user guides. - -h4. Enhanced Error Reporting and Diagnosis - -Error reporting and problem diagnosis has been greatly improved with a new errors view that analyses stack traces and recursively displays problem areas in your code: - -!errors-view.png! - -In addition stack trace filtering has been further enhanced to display only relevant trace information: - -{code} - Line | Method -->> 9 | getValue in Book.groovy -- - - - - - - - - - - - - - - - - - - - - - - - - -| 7 | getBookValue in BookService.groovy -| 886 | runTask . . in ThreadPoolExecutor.java -| 908 | run in '' -^ 662 | run . . . . in Thread.java -{code} - -h4. H2 Database and Console - -Grails 2.0 now uses the H2 database instead of HSQLDB, and enables the H2 database console in development mode (at the URI /dbconsole) so that the in-memory database can be easily queried from the browser: - -!h2-console.png! - -h4. Plugin Usage Tracking - -To enhance community awareness of the most popular plugins an opt-in plugin usage tracking system has been included where users can participate in providing feedback to the plugin community on which plugins are most popular. - -This will help drive the roadmap and increase support of key plugins while reducing the need to support older or less popular plugins thus helping plugin development teams focus their efforts. - - -h4. Dependency Resolution Improvements - -There are numerous improvements to dependency resolution handling via Ivy including: - -* Grails now makes a best effort to cache the previous resolve and avoid resolving again unless you change @BuildConfig.groovy@. -* Plugins dependencies now appear in the dependency report generated by @grails dependency-report@ -* Plugins published with the release plugin now publish their transitive plugin dependencies in the generated POM which are later resolved. -* It is now possible to customize the ivy cache directory via @BuildConfig.groovy@ - -{code} -grails.project.dependency.resolution = { - cacheDir "target/ivy-cache" -} -{code} - -* You can change the ivy cache directory for all projects via @settings.groovy@ - -{code} -grails.dependency.cache.dir = "\${userHome}/.ivy2/cache" -{code} - -* It is now possible to completely disable resolution from inherited repositories (repositories defined by other plugins): - -{code} -grails.project.dependency.resolution = { - - repositories { - inherits false // Whether to inherit repository definitions from plugins - ... - } - ... -} -{code} - -* It is now possible to easily disable checksum validation errors: - -{code} -grails.project.dependency.resolution = { - checksums false // whether to verify checksums or not -} -{code} +h4. TBD \ No newline at end of file diff --git a/src/en/guide/introduction/whatsNew/persistenceFeatures.gdoc b/src/en/guide/introduction/whatsNew/persistenceFeatures.gdoc index 3b1e2faabd6..2f4f6266cd7 100644 --- a/src/en/guide/introduction/whatsNew/persistenceFeatures.gdoc +++ b/src/en/guide/introduction/whatsNew/persistenceFeatures.gdoc @@ -1,101 +1 @@ -h4. The GORM API - -The GORM API has been formalized into a set of classes (@GormStaticApi@, @GormInstanceApi@ and @GormValidationApi@) that get statically wired into every domain class at the byte code level. The result is better code completion for IDEs, better integration with Java and the potential for more GORM implementations for other types of data stores. - -h4. Detached Criteria and Where Queries - -Grails 2.0 features support for [DetachedCriteria|guide:detachedCriteria] which are criteria queries that are not associated with any session or connection and thus can be more easily reused and composed: - -{code} -def criteria = new DetachedCriteria(Person).build { - eq 'lastName', 'Simpson' -} -def results = criteria.list(max:4, sort:"firstName") -{code} - -To support the addition of [DetachedCriteria|guide:detachedCriteria] queries and encourage their use a new @where@ method and DSL has been introduced to greatly reduce the complexity of criteria queries: - -{code} -def query = Person.where { - (lastName != "Simpson" && firstName != "Fred") || (firstName == "Bart" && age > 9) -} -def results = query.list(sort:"firstName") -{code} - -See the documentation on [DetachedCriteria|guide:detachedCriteria] and [Where Queries|guide:whereQueries] for more information. - -h4. New findOrCreate and findOrSave Methods - -Domain classes have support for the findOrCreateWhere, findOrSaveWhere, findOrCreateBy and findOrSaveBy query methods which behave just like findWhere and findBy methods except that they should never return null. If a matching instance cannot be found in the database then a new instance is created, populated with values represented in the query parameters and returned. In the case of findOrSaveWhere and findOrSaveBy, the instance is saved before being returned. - -{code} -def book = Book.findOrCreateWhere(author: 'Douglas Adams', title: "The Hitchhiker's Guide To The Galaxy") -def book = Book.findOrSaveWhere(author: 'Daniel Suarez', title: 'Daemon') -def book = Book.findOrCreateByAuthorAndTitle('Daniel Suarez', 'Daemon') -def book = Book.findOrSaveByAuthorAndTitle('Daniel Suarez', 'Daemon') -{code} - -h4. Abstract Inheritance - -GORM now supports abstract inheritance trees which means you can define queries and associations linking to abstract classes: - -{code} -abstract class Media { - String title - ... -} -class Book extends Media { -} -class Album extends Media { - -} -class Account { - static hasMany = [purchasedMedia:Media] -} - -.. - -def allMedia = Media.list() -{code} - -h4. Multiple Data Sources Support - -It is now possible to define multiple datasources in @DataSource.groovy@ and declare one or more datasources a particular domain uses by default: - -{code} -class ZipCode { - - String code - - static mapping = { - datasource 'ZIP_CODES' - } -} -{code} - -If multiple datasources are specified for a domain then you can use the name of a particular datasource as a namespace in front of any regular GORM method: - -{code} -def zipCode = ZipCode.auditing.get(42) -{code} - -For more information see the section on [Multiple Data Sources|guide:multipleDatasources] in the user guide. - -h4. Database Migrations - -A new [database migration plugin|http://grails.org/plugin/database-migration] has been designed and built for Grails 2.0 allowing you to apply migrations to your database, rollback changes and diff your domain model with the current state of the database. - -h4. Database Reverse Engineering - -A new [database reverse engineering|http://www.grails.org/plugin/db-reverse-engineer] plugin has been designed and built for Grails 2.0 that allows you to generate a domain model from an existing database schema. - -h4. Hibernate 3.6 - -Grails 2.0 is now built on Hibernate 3.6 - -h4. Bag Collections - -You can now use Hibernate [Bag|http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html/collections.html]s for mapped collections to avoid the memory and performance issues of loading large collections to enforce @Set@ uniqueness or @List@ order. - -For more information see the section on [Sets, Lists and Maps|guide:sets,ListsAndMaps] in the user guide. - +h4. TBD \ No newline at end of file diff --git a/src/en/guide/introduction/whatsNew/testingFeatures.gdoc b/src/en/guide/introduction/whatsNew/testingFeatures.gdoc index 625d8aa1c23..2f4f6266cd7 100644 --- a/src/en/guide/introduction/whatsNew/testingFeatures.gdoc +++ b/src/en/guide/introduction/whatsNew/testingFeatures.gdoc @@ -1,37 +1 @@ -h4. New Unit Testing Console Output - -Test output from the test-app command has been improved: - -!test-output.png! - -h4. New Unit Testing API - -There is a new unit testing API based on mixins that supports JUnit 3, 4 and Spock style tests (with Spock 0.6 and above). Example: - -{code:java} -import grails.test.mixin.TestFor - -@TestFor(SimpleController) -class SimpleControllerTests { - void testIndex() { - controller.home() - - assert view == "/simple/homePage" - assert model.title == "Hello World" - } -} -{code} - -The [documentation on testing|guide:testing] has also been re-written around this new framework. - -h4. Unit Testing GORM - -A new in-memory GORM implementation is present that supports many more features of the GORM API making unit testing of criteria queries, named queries and other previously unsupported methods possible. - -h4. Faster Unit Testing with Interactive Mode - -The new interactive mode (activated by typing 'grails') greatly improves the execution time of running unit and integration tests. - -h4. Unit Test Scaffolding - -A unit test is now generated for scaffolded controllers \ No newline at end of file +h4. TBD \ No newline at end of file diff --git a/src/en/guide/introduction/whatsNew/webFeatures.gdoc b/src/en/guide/introduction/whatsNew/webFeatures.gdoc index 5c3307a99c2..2f4f6266cd7 100644 --- a/src/en/guide/introduction/whatsNew/webFeatures.gdoc +++ b/src/en/guide/introduction/whatsNew/webFeatures.gdoc @@ -1,176 +1 @@ -h4. Controller Actions as Methods - -It is now possible to define controller actions as methods instead of using closures as in previous versions of Grails. In fact this is now the preferred way of expressing an action. For example: - -{code} -// action as a method -def index() { - -} -// action as a closure -def index = { - -} -{code} - -h4. Binding Primitive Method Action Arguments - -It is now possible to bind form parameters to action arguments where the name of the form element matches the argument name. For example given the following form: - -{code:xml} - - - - -{code} - -You can define an action that declares arguments for each input and automatically converts the parameters to the appropriate type: - -{code} -def save(String name, int age) { - // remaining -} -{code} - -h4. Static Resource Abstraction - -A new [static resource abstraction|guide:resources] is included that allows declarative handling of JavaScript, CSS and image resources including automatic ordering, compression, caching and gzip handling. - -h4. Servlet 3.0 Async Features - -Grails now supports Servlet 3.0 including the Asynchronous programming model defined by the specification: - -{code} -def index() { - def ctx = startAsync() - ctx.start { - new Book(title:"The Stand").save() - render template:"books", model:[books:Book.list()] - ctx.complete() - } -} -{code} - -h4. Link Generation API - -A general purpose @LinkGenerator@ class is now available that is usable anywhere within a Grails application and not just within the context of a controller. For example if you need to generate links in a service or an asynchronous background job outside the scope of a request: - -{code} -LinkGenerator grailsLinkGenerator - -def generateLink() { - grailsLinkGenerator.link(controller:"book", action:"list") -} -{code} - -h4. Page Rendering API - -Like the @LinkGenerator@ the new @PageRenderer@ can be used to render GSP pages outside the scope of a web request, such as in a scheduled job or web service. The @PageRenderer@ class features a very similar API to the @render@ method found within controllers: - -{code} -grails.gsp.PageRenderer groovyPageRenderer - -void welcomeUser(User user) { - def contents = groovyPageRenderer.render(view:"/emails/welcomeLetter", model:[user: user]) - sendEmail { - to user.email - body contents - } -} -{code} - -The @PageRenderer@ service also allows you to pre-process GSPs into HTML templates: - -{code} -new File("/path/to/welcome.html").withWriter { w -> - groovyPageRenderer.renderTo(view:"/page/content", w) -} -{code} - -h4. Filter Exclusions - -Filters may now express controller, action and uri exclusions to offer more options for expressing to which requests a particular filter should be applied. - -{code} - -filter1(actionExclude: 'log*') { - before = { - // ... - } -} -filter2(controllerExclude: 'auth') { - before = { - // ... - } -} - -filter3(uriExclude: '/secure*') { - before = { - // ... - } -} -{code} - -h4. Performance Improvements - -Performance of GSP page rendering has once again been improved by optimizing the GSP compiler to inline method calls where possible. - -h4. HTML5 Scaffolding - -There is a new HTML5-based scaffolding UI: - -!scaffolding-ui.png! - -h4. jQuery by Default - -The jQuery plugin is now the default JavaScript library installed into a Grails application. For backwards compatibility a [Prototype plugin|http://grails.org/plugin/prototype] is available. Refer to the [documentation|http://grails.org/plugin/prototype] on the Prototype plugin for installation instructions. - -h4. Easy Date Parsing - -A new @date@ method has been added to the @params@ object to allow easy, null-safe parsing of dates: - -{code} -def val = params.date('myDate', 'dd-MM-yyyy') - -// or a list for formats -def val = params.date('myDate', ['yyyy-MM-dd', 'yyyyMMdd', 'yyMMdd']) - -// or the format read from messages.properties via the key 'date.myDate.format' -def val = params.date('myDate') -{code} - -h4. Customizable URL Formats - -The default URL Mapping mechanism supports camel case names in the URLs. The default URL for accessing an action named @addNumbers@ in a controller named @MathHelperController@ would be something like @/mathHelper/addNumbers@. Grails allows for the customization of this pattern and provides an implementation which replaces the camel case convention with a hyphenated convention that would support URLs like @/math-helper/add-numbers@. To enable hyphenated URLs assign a value of "hyphenated" to the @grails.web.url.converter@ property in @grails-app/conf/Config.groovy@. - -{code:java} -// grails-app/conf/Config.groovy - -grails.web.url.converter = 'hyphenated' -{code} - -Arbitrary strategies may be plugged in by providing a class which implements the [UrlConverter|api:grails.web.UrlConverter] interface and adding an instance of that class to the Spring application context with the bean name of @grails.web.UrlConverter.BEAN_NAME@. If Grails finds a bean in the context with that name, it will be used as the default converter and there is no need to assign a value to the @grails.web.url.converter@ config property. - -{code:java} -// src/groovy/com/myapplication/MyUrlConverterImpl.groovy - -package com.myapplication - -class MyUrlConverterImpl implements grails.web.UrlConverter { - - String toUrlElement(String propertyOrClassName) { - // return some representation of a property or class name that should be used in URLs... - } -} -{code} - -{code:java} -// grails-app/conf/spring/resources.groovy - -beans = { - "\${grails.web.UrlConverter.BEAN_NAME}"(com.myapplication.MyUrlConverterImpl) -} -{code} - -h4. Web Flow input and output -It is now possible to provide input arguments when calling a subflow. Flows can also return output values that can be used in a calling flow. +h4. TBD \ No newline at end of file diff --git a/src/en/guide/introduction/whatsNew21.gdoc b/src/en/guide/introduction/whatsNew21.gdoc deleted file mode 100644 index 2714610490f..00000000000 --- a/src/en/guide/introduction/whatsNew21.gdoc +++ /dev/null @@ -1,73 +0,0 @@ -h4. Maven Improvements / Multi Module Build Support - -Grails' Maven support has been improved in a number of significant ways. Firstly it is now possible to specify plugins within your @pom.xml@ file: - -{code} - - org.grails.plugins - hibernate - 2.1.0 - zip - compile - -{code} - -The Maven plugin now resolves plugins as well as jar dependencies (previously jar dependencies were resolved by Maven and plugins by Ivy). Ivy is completely disabled leaving all dependency resolution up to Maven ensuring that evictions work as expected. - -There is also a new Grails @create-multi-project-build@ script which features initial support for Maven (Gradle coming in a future release). This script can be run from a parent directory containing Grails applications and plugins and it will generate a Maven multi-module build. - -Enabling Maven in a project has been made easier with the inclusion of the @create-pom@ command: - -{code} -grails create-app myapp -cd myapp -grails create-pom com.mycompany -mvn package -{code} - -To create a multi-module Maven build follow these steps: - -{code} -grails create-app myapp -grails create-plugin plugin-a -grails create-plugin plugin-b -grails create-multi-project-build com.mycompany:parent:1.0-SNAPSHOT -mvn install -{code} - -h4. Grails Wrapper - -The Grails Wrapper allows a Grails application to build without having to install Grails and configure a GRAILS_HOME environment variable. The wrapper includes a small shell script and a couple of small bootstrap jar files that typically would be checked in to source code control along with the rest of the project. The first time the wrapper is executed it will download and configure a Grails installation. This wrapper makes it more simple to setup a development environment, configure CI and manage upgrades to future versions of Grails. When the application is upgraded to the next version of Grails, the wrapper is updated and checked in to the source code control system and the next time developers update their workspace and run the wrapper, they will automatically be using the correct version of Grails. - -See the [Wrapper Documentation|guide:wrapper] for more details. - -h4. Debug Option - -The @grails@ command now supports a @-debug@ option which will startup the remote debug agent. This behavior used to be provided by the @grails-debug@ command. @grails-debug@ is still available but is deprecated and may be removed from a future release. - -{code} -grails -debug run-app -{code} - -h4. Grails Command Aliases - -The @alias@ command may be used to define aliases for grails commands. - -The following command creates an alias named @rit@ (short for "run integration tests"): - -{code} -grails alias rit test-app integration: -{code} - -See the [alias|commandLine] docs for more info. - -h4. Cache Plugin - -Grails 2.1 installs the [cache plugin|http://grails.org/plugin/cache] by default. This plugin provides powerful and easy to use cache functionality to applications and plugins. The main plugin provides basic map backed caching support. For more robust caching options one of the implementation plugins should be installed and configured. See the [cache-redis docs|http://grails-plugins.github.com/grails-cache-redis/] and the [cache-ehcache docs|http://grails-plugins.github.com/grails-cache-ehcache/] for details. - -See [the main plugin documentation|http://grails-plugins.github.com/grails-cache/] for details on how to configure and use the plugin. - -h4. New GORM Methods - -In Grails 2.1.1 domain classes now have static methods named @first@ and @last@ to retrieve the first and last instances from the datastore. See the [first|domainClasses] and [last|domainClasses] documentation for details. - diff --git a/src/en/guide/introduction/whatsNew22.gdoc b/src/en/guide/introduction/whatsNew22.gdoc deleted file mode 100644 index c43e02ffea3..00000000000 --- a/src/en/guide/introduction/whatsNew22.gdoc +++ /dev/null @@ -1,82 +0,0 @@ -h4. Namespace Support - -Grails 2.2 includes improved support for managing naming conflicts between artifacts provided by an application and its plugins. - -Bean names for Service artifacts provided by a plugin are now prefixed with the plugin name. For example, if a Service named @com.publishing.AuthorService@ is provided by -a plugin named @PublishingUtilities@ and another Service named @com.bookutils.AuthorService@ is provided by a plugin named @BookUtilities@, the bean names for those services -will be @publishingUtilitiesAuthorService@ and @bookUtilitiesAuthorService@ respectively. If a plugin provides a Service that does not have a name which conflicts with any -other Service, then a bean alias will automatically be created that does not contain the prefix and the alias will refer to the bean referenced by the prefixed name. Service -artifacts provided directly by the application will have no prefix added to the relevant bean name. See the [dependency injection and services|guide:dependencyInjectionServices] docs. - -Domain classes provided by a plugin will have their default database table name prefixed with the plugin name if the @grails.gorm.table.prefix.enabled@ config property is -set to @true@. For example, if the @PublishingUtilities@ plugin provides a domain class named @Book@, the default table name for that domain class will be -@PUBLISHING_UTILITIES_BOOK@ if the @grails.gorm.table.prefix.enabled@ config property is set to @true@. - -URL Mappings may now include a @plugin@ attribute to indicate that the controller referenced in the mapping is provided by a particular plugin. - -{code:java} -static mappings = { - - // requests to /bookAuthors will be handled by the - // AuthorController provided by the BookUtilities plugin - "/bookAuthors" { - controller = 'author' - plugin = 'bookUtilities' - } - - // requests to /publishingAuthors will be handled by the - // AuthorController provided by the Publishing plugin - "/publishingAuthors" { - controller = 'author' - plugin = 'publishing' - } -} -{code} - -See the [namespaced controllers|guide:namespacedControllers] docs for more information. - -Controller methods and GSP Tags which accept a controller name as a parameter now support an optional parameter indicating -that the controller is provided by a specific plugin. - -{code:java} -Manage Users -{code} - -{code:java} -class DemoController { - def index() { - redirect controller: 'user', action: 'list', plugin: 'springSecurity' - } -} -{code} - -h4. Forked Tomcat Execution - -Grails 2.2 supports forked JVM execution of the Tomcat container in development mode. This has several benefits including: - -* Reduced memory consumption, since the Grails build system can exit -* Isolation of the build classpath from the runtime classpath -* The ability to deploy other Grails/Spring applications in parallel without conflicting dependencies - -See the [documentation|guide:forkedMode] on using forked mode for more information. - -h4. SQL Projections In Criteria Queries - -Grails 2.2 adds new functionality to criteria queries to provide access to Hibernate's SQL projection API. - -{code:java} -// Use SQL projections to retrieve the perimeter and area of all of the Box instances... -def c = Box.createCriteria() - -def results = c.list { - projections { - sqlProjection '(2 * (width + height)) as perimeter, (width * height) as area', ['perimeter', 'area'], [INTEGER, INTEGER] - } -} -{code} - -See the [Criteria|guide:criteria] section for more information. - -h4. Groovy 2 - -Grails 2.2 ships with Groovy 2.0, which has a [bunch of new features|http://www.infoq.com/articles/new-groovy-20] itself. diff --git a/src/en/guide/introduction/whatsNew23.gdoc b/src/en/guide/introduction/whatsNew23.gdoc deleted file mode 100644 index cbd29d3965f..00000000000 --- a/src/en/guide/introduction/whatsNew23.gdoc +++ /dev/null @@ -1,218 +0,0 @@ -h4. Improved Dependency Management - -The default dependency resolution engine used by Grails has been changed to [Aether|http://eclipse.org/aether], the dependency resolution engine used by Maven. Which engine you use can be configured in @BuildConfig@: - -{code} -grails.project.dependency.resolver = "maven" // or ivy -{code} - -Using Aether dependency resolution in Grails results in the same behavior as when using the Maven build tool, meaning improved snapshot handling, understanding of custom packaging types and so on. - -In addition, the [dependency-report|commandLine] command has been updated to print the dependency graph of the console, which helps in diagnosing dependency resolution failures. See the chapter on [Dependency Resolution|guide:dependencyResolution] for more information. - - -h4. Data Binder - -Grails 2.3 includes a new data binding mechanism which is more flexible and easier to maintain than the data binder used in previous versions. The new data binder includes numerous enhancements including: - -* Custom date formats on a per field basis using [BindingFormat|api:org.grails.databinding.BindingFormat] -* User defined data converters using [ValueConverter|api:org.grails.databinding.converters.ValueConverter] -* User defined formatted data converters using [BindingFormat|api:org.grails.databinding.BindingFormat] and [FormattedValueConverter|api:org.grails.databinding.converters.FormattedValueConverter] -* Custom binding on a per class basis using [BindUsing|api:org.grails.databinding.BindUsing] -* Custom binding on a per field basis using [BindUsing|api:org.grails.databinding.BindUsing] -* By default all blank and empty Strings will be converted to null during data binding (configurable) - -See the [Data Binding|guide:dataBinding] section for details. - -The legacy data binder may be used by assigning @true@ to the @grails.databinding.useSpringBinder@ property in @grails-app/conf/Config.groovy@. Note that the legacy binder does not support any of the new features provided by the new data binder. - -h4. Binding Request Body To Command Objects - -If a request is made to a controller action which accepts a command object and the request includes a body, the body will be parsed and used to do data binding to the command object. This simplifies use cases where a request includes a JSON or XML body (for example) that can be bound to a command object. See the [Command Objects|guide:commandObjects] documentation for more details. - -h4. Domain Classes As Command Objects - -When a domain class is used as a command object and there is an @id@ request parameter, the framework will retrieve the instance of the domain class from the database using the @id@ request parameter. See the [Command Objects|guide:commandObjects] documentation for more details. - -h4. Forked Execution - -All major commands can now be forked into a separate JVM, thus isolating the build path from the runtime / test paths. Forked execution can be controlled via the @BuildConfig@: - -{code} -grails.project.fork = [ - test: [maxMemory: 768, minMemory: 64, debug: false, maxPerm: 256, daemon:true], // configure settings for the test-app JVM - run: [maxMemory: 768, minMemory: 64, debug: false, maxPerm: 256], // configure settings for the run-app JVM - war: [maxMemory: 768, minMemory: 64, debug: false, maxPerm: 256], // configure settings for the run-war JVM - console: [maxMemory: 768, minMemory: 64, debug: false, maxPerm: 256]// configure settings for the Console UI JVM -] -{code} - -See the documentation on [Forked Mode|guide:forkedMode] for more information. - -h4. Test Runner Daemon - -To speed up testing when using forked execution a new daemon will start-up in the background to run tests when using interactive mode. You can restart the daemon with the @restart-daemon@ command from interactive mode: - -{code} -\$ grails> restart-daemon -{code} - -h4. Server-Side REST Improvements - -Grails' [REST support|guide:REST] has been significantly improved with the addition of the following features: - -* Rich [REST URL Mapping support|guide:restfulMappings] with supports for resource mappings, singular resource mappings, nested resources, versioning and more -* New extensible response rendering and binding APIs -* Support for HAL, Atom and Hypermedia (HATEAOS) -* Scaffolding for REST controllers - -See the [user guide|guide:REST] for more information. - -h4. New Scaffolding 2.0 Plugin - -Grails' Scaffolding feature has been split into a [separate plugin|http://grails.org/plugin/scaffolding]. Version 2.0 of the plugin includes support for generating REST controllers, Async controllers, and Spock unit tests. - -h4. URL Mappings May Specify A Redirect - -URL Mappings may now specify that a redirect should be triggered when the mapping matches an incoming request: - -{code:java} -class UrlMappings { - static mappings = { - "/viewBooks"(redirect: '/books/list') - "/viewAuthors"(redirect: [controller: 'author', action: 'list']) - "/viewPublishers"(redirect: [controller: 'publisher', action: 'list', permanent: true]) - - // ... - } -} -{code} - -See the [user guide|guide:redirectMappings] for more information. - -h4. Async support - -Grails 2.3 features new [Asynchronous Programming APIs|guide:async] that allow for asynchronous processing of requests and integrate seamlessly with GORM. Example: - -{code} -import static grails.async.Promises.* -... -def index() { - tasks books: Book.async.list(), - totalBooks: Book.async.count(), - otherValue: { - // do hard work - } -} -{code} - -See [the documentation|guide:async] for further information. - -h4. Encoding / Escaping Improvements - -Grails 2.3 features dedicated support for [Cross Site Scripting (XSS) prevention|guide:xssPrevention], including : - -* Defaulting to HTML escaping all GSP expressions and scriptlets -* Context sensitive encoding switching for tags -* Double encoding prevention -* Optional automatic encoding of all data in a GSP page not considered safe - -See the documentation on [Cross Site Scripting (XSS) prevention|guide:xssPrevention] for more information. - -h4. Hibernate 3 and 4 support - -The GORM for Hibernate 3 support for Grails has been extracted into a separate project, allowing new support for Hibernate 4 as a separate plugin. - -h4. Controller Exception Handling - -Controllers may define exception handler methods which will automatically be invoked any time an action in that controller throws an exception. - -{code:java} -// grails-app/controllers/demo/DemoController.groovy -package demo - -class DemoController { - - def someAction() { - // do some work - } - - def handleSQLException(SQLException e) { - render 'A SQLException Was Handled' - } - - def handleBatchUpdateException(BatchUpdateException e) { - redirect controller: 'logging', action: 'batchProblem' - } - - def handleNumberFormatException(NumberFormatException nfe) { - [problemDescription: 'A Number Was Invalid'] - } -} -{code} - -See the [controller exception handling|guide:controllerExceptionHandling] docs for more information. - -h4. Namespaced Controllers - -Controllers may now be defined in a namespace which allows for multiple controllers to be defined with the same name in different packages. - -{code} -// grails-app/controllers/com/app/reporting/AdminController.groovy -package com.app.reporting - -class AdminController { - - static namespace = 'reports' - - // ... -} -{code} - -{code} -// grails-app/controllers/com/app/security/AdminController.groovy -package com.app.security - -class AdminController { - - static namespace = 'users' - - // ... -} -{code} - - -{code} -// grails-app/conf/UrlMappings.groovy -class UrlMappings { - - static mappings = { - '/userAdmin' { - controller = 'admin' - namespace = 'users' - } - - '/reportAdmin' { - controller = 'admin' - namespace = 'reports' - } - - "/\$namespace/\$controller/\$action?"() - } -} -{code} - -{code} -Click For Report Admin -Click For User Admin -{code} - -See the [namespaced controllers|guide:namespacedControllers] docs for more information. - -h4. Command Line - -The @create-app@ command will now by default generate the command line grailsw wrapper for newly created applications. The @--skip-wrapper@ switch may be used to prevent the wrapper from being generated. - -{code} -grails create-app appname --skip-wrapper -{code} diff --git a/src/en/guide/introduction/whatsNew24.gdoc b/src/en/guide/introduction/whatsNew24.gdoc deleted file mode 100644 index 77482a878b6..00000000000 --- a/src/en/guide/introduction/whatsNew24.gdoc +++ /dev/null @@ -1,291 +0,0 @@ -h4. Groovy 2.3 - -Grails 2.4 comes with Groovy 2.3 which includes many new features and enhancements. - -For more information on Groovy 2.3, see the [comprehensive release notes|http://groovy.codehaus.org/Groovy+2.3+release+notes]. - -h4. Spring 4.0 - -Grails 2.4 comes with Spring 4.0.4 which includes many new features and enhancements. See the [Spring documentation|http://docs.spring.io/spring/docs/4.0.x/spring-framework-reference/html/new-in-4.0.html]. - -h4. Hibernate 4.3 - -Grails 2.4 now uses Hibernate 4.3.5 by default (Hibernate 3 is still available as an optional install). - -h4. Standalone GORM and GSP - -GORM and GSP can now be used outside of Grails. See the following guides / examples for more information: - -* [Accessing Data with GORM|https://spring.io/guides/gs/accessing-data-gorm/] -* [Accessing MongoDB Data with GORM|https://spring.io/guides/gs/accessing-data-gorm-mongodb/] -* [GSP in Spring Boot Example Application|https://github.com/grails/grails-boot/tree/master/sample-apps/gsp/gsp-example] - -h4. The Asset-Pipeline replaces Resources to serve static assets. - -The asset-pipeline provides a new, easier to manage, faster means of managing your JavaScript, CSS, and images, while also bringing compiled client languages in to the fray as first-class citizens (e.g. CoffeeScript, LESS, SASS). - -All your assets should now live in the @grails-app/assets@ subfolders. Three folders are made for you by default: - -* javascript -* stylesheets -* images - -Now, defining manifests are done directly in your JavaScript files, or CSS by using require directives! - -{code} -//= require jquery -//= require_self -//= require file_a -//= require_tree . - -console.log('some javascript'); -{code} - -Easily add your assets to your GSP files: - -{code} - - - -{code} - -Enjoy developing with on the fly asset processing, asset compiling on WAR, and much more. See the [docs|http://bertramdev.github.com/asset-pipeline] for more info. - -h4. Static Compilation - -Groovy is a dynamically dispatched, dynamically typed language by default but also has great support for static type checking and static compilation. See [these notes on Groovy static compilation|http://docs.codehaus.org/display/GroovyJSR/GEP+10+-+Static+compilation]. In general, Grails supports Groovy's static compilation but there are a lot of special situations which are common in a Grails app which cannot be statically compiled. For example, if a method marked with @\@CompileStatic@ contains code which invokes a GORM dynamic finder the code will not compile because the Groovy compiler cannot verify that the dynamic finder is valid. Grails 2.4 improves on this by allowing code to be statically compiled and still do things like invoke GORM dynamic finders. - -The [grails.compiler.GrailsCompileStatic|api:grails.compiler.GrailsCompileStatic] annotation behaves much like the [groovy.transform.CompileStatic|api:groovy.transform.CompileStatic] annotation and provides special handling to recognize Grails specific constructs. - -The following controller is marked with @\@GrailsCompileStatic@. All of the code that can be statically compiled will be statically compiled. When the compiler encounters code which can not be statically validated, normally that would result in a compile error. The Grails compiler will allow certain things to be considered valid and dynamically dispatch those instructions. - -{code:java} -// grails-app/controllers/com/demo/PersonController.groovy -package com.demo - -import grails.compiler.GrailsCompileStatic - -@GrailsCompileStatic -class PersonController { - - def showKids() { - def kids = Person.findAllByAgeLessThan(16) - - // ... - } -} -{code} - -There may be situations where most of the code in a class should be statically compiled but a specific method should be left to dynamic compilation. See the following example. - -{code:java} -import grails.compiler.GrailsCompileStatic -import groovy.transform.TypeCheckingMode - -@GrailsCompileStatic -class SomeClass { - - def update() { - // this method will be statically compiled - } - - @GrailsCompileStatic(TypeCheckingMode.SKIP) - def save() { - // this method will not be statically compiled - } - - def delete() { - // this method will be statically compiled - } -} -{code} - - -The [grails.compiler.GrailsTypeChecked|api:grails.compiler.GrailsTypeChecked] annotation behaves much like the [groovy.transform.TypeChecked|api:groovy.transform.TypeChecked] annotation and provides special handling to recognize Grails specific constructs. - -See the [static compilation and type checking|guide:staticTypeCheckingAndCompilation] section for more details. - -h4. More Advanced Subqueries in GORM - -The support for subqueries has been extended. You can now use @in@ with nested subqueries: - -{code} -def results = Person.where { - firstName in where { age < 18 }.firstName -}.list() -{code} - -Criteria and where queries can be seamlessly mixed: - -{code} -def results = Person.withCriteria { - notIn "firstName", Person.where { age < 18 }.firstName -} -{code} - -Subqueries can be used with projections: - -{code} -def results = Person.where { - age > where { age > 18 }.avg('age') -} -{code} - -Correlated queries that span two domain classes can be used: - -{code} -def employees = Employee.where { - region.continent in ['APAC', "EMEA"] -}.id() - -def results = Sale.where { - employee in employees && total > 100000 -}.employee.list() -{code} - -And support for aliases (cross query references) using simple variable declarations has been added to where queries: - -{code} -def query = Employee.where { - def em1 = Employee - exists Sale.where { - def s1 = Sale - def em2 = employee - return em2.id == em1.id - }.id() -} -def results = query.list() -{code} - -h4. GORM for Hibernate in Unit tests - -It is no longer necessary to create integration tests in order to test GORM interactions with Hibernate. You can now instead use @HibernateTestMixin@: - -{code} -import grails.test.mixin.TestMixin -import grails.test.mixin.gorm.Domain -import grails.test.mixin.hibernate.HibernateTestMixin -import spock.lang.Specification - - -@Domain(Person) -@TestMixin(HibernateTestMixin) -class PersonSpec extends Specification { - - void "Test count people"() { - expect: "Test execute Hibernate count query" - Person.count() == 0 - sessionFactory != null - transactionManager != null - session != null - } -} -{code} - -This library dependency is required in grails-app/conf/BuildConfig.groovy for adding support for HibernateTestMixin -{code} - dependencies { - test "org.grails:grails-datastore-test-support:1.0-grails-2.4" - } -{code} - -HibernateTestMixin is only supported with hibernate4 plugin versions >= 4.3.5.4 . -{code} - plugins { - runtime ':hibernate4:4.3.5.4' - } -{code} - - -h4. Views For Namespaced Controllers - -The views for namespaced controllers may now be defined in the @grails-app/views///@ directory. See the [Models And Views|guide:modelsAndViews] section for more details. - -h4. Improved Programmatic Transactions - -Transaction attributes may now be specified when invoking @withTransaction@. - -{code:java} - -// the keys in the Map must correspond to properties -// of org.springframework.transaction.support.DefaultTransactionDefinition - -Account.withTransaction([propagationBehavior: TransactionDefinition.PROPAGATION_REQUIRES_NEW, - isolationLevel: TransactionDefinition.ISOLATION_REPEATABLE_READ]) { - // ... -} -{code} - -See the [withTransaction|domainClasses] docs for more information. - -h4. New Maven Plugin - -The Maven plugin has been rewritten to use [Aether for dependency resolution|http://wiki.eclipse.org/Aether/Using_Aether_in_Maven_Plugins] and can now be used with both Grails 2.3.x and Grails 2.4.x without releasing a new version of the plugin. - -This means that the Maven plugin version number is no longer tied to the version number of Grails and new releases of the Maven plugin will not come out with each new Grails release. Instead, users can continue to use the 2.4.0 version of the plugin for any version of Grails going forward. - -h4. Unit Testing improvements - -There is a Grails "unit testing runtime" that is based on the previous TestMixin based solution. It now separates the TestMixin classes and the actual runtime that handles the lifecycle of the Grails unit testing runtime. State of the runtime is not kept in static fields of the TestMixin classes anymore. The Groovy AST transformation behind the TestMixin annotation integrates to JUnit and Spock test classes by adding JUnit Rule fields to the class. In the previous solution, Before/BeforeClass and After/AfterClass annotations on AST added mix-in methods were used for the integration. - -Some of the main features: - -* The programming model remains the same for unit testing of Grails applications -* Setup/teardown method ordering is now deterministic because the integration is now using a single JUnit Rule field and the test runtime uses eventing internally to setup and teardown resources -* There are doWithSpring and doWithConfig callbacks for unit tests - these callback methods get called before the grailsApplication instance in the unit test runtime gets initialized. -* It's possible to register a Spock Mock as a bean to the application context of the Grails unit test runtime application - you can replace a collaborator bean with a mock -* It's possible to reuse a single application context for several test classes and control that so that tests can be made faster when required -* The Grails unit testing runtime has an event-based plugin architecture. It's possible to add new test runtime "features" with new [test runtime plugin|api:grails.test.runtime.TestPlugin] classes. The test runtime plugin API is due to change. Changes will be made based on feedback from the Grails community. The main interfaces of the API are currently documented in the javadocs: [TestPlugin|api:grails.test.runtime.TestPlugin], [TestEventInterceptor|api:grails.test.runtime.TestEventInterceptor] and [TestEvent|api:grails.test.runtime.TestEvent]. Custom test plugins are currently limited since there isn't a solution for scanning for available test plugins. It's now possible to add custom test plugins in a static initialization block of a test class by calling [TestRuntimeFactory.addPluginClass|api:grails.test.runtime.TestRuntimeFactory] . - -See the updated [unit testing chapter|guide:unitTesting] in the manual for more information of the new features like doWithSpring and doWithConfig. - -h4. Improved Unit Testing Support For allowedMethods - -The allowedMethods property is now respected in unit tests. - -{code:java} -// grails-app/controllers/com/demo/DemoController.groovypackage com.demo - -class DemoController { - - static allowedMethods = [save: 'POST', update: 'PUT', delete: 'DELETE'] - - def save() { - render 'Save was successful!' - } - - // ... -} -{code} - -{code:java} -// test/unit/com/demo/DemoControllerSpec.groovy -package com.demo - -import grails.test.mixin.TestFor -import spock.lang.Specification -import static javax.servlet.http.HttpServletResponse.* - -@TestFor(DemoController) -class DemoControllerSpec extends Specification { - - void "test a valid request method"() { - when: - request.method = 'POST' - controller.save() - - then: - response.status == SC_OK - response.text == 'Save was successful!' - } - - void "test an invalid request method"() { - when: - request.method = 'DELETE' - controller.save() - - then: - response.status == SC_METHOD_NOT_ALLOWED - } -} -{code} diff --git a/src/en/guide/introduction/whatsNew30.gdoc b/src/en/guide/introduction/whatsNew30.gdoc deleted file mode 100644 index 54077a0fe24..00000000000 --- a/src/en/guide/introduction/whatsNew30.gdoc +++ /dev/null @@ -1,9 +0,0 @@ -h4. Groovy 2.4 - -Grails 3.0 comes with Groovy 2.4 which includes many new features and enhancements. - -For more information on Groovy 2.3, see the (TBD). - -h4. Spring 4.2 - -Grails 3.0 comes with Spring 4.2 which includes many new features and enhancements. See the (TBD). diff --git a/src/en/guide/toc.yml b/src/en/guide/toc.yml index 370f9b714b8..ecc772e43b2 100644 --- a/src/en/guide/toc.yml +++ b/src/en/guide/toc.yml @@ -1,14 +1,9 @@ introduction: title: Introduction - whatsNew30: What's new in Grails 3.0? - whatsNew24: What's new in Grails 2.4? - whatsNew23: What's new in Grails 2.3? - whatsNew22: What's new in Grails 2.2? - whatsNew21: What's new in Grails 2.1? whatsNew: - title: What's new in Grails 2.0? - developmentEnvironmentFeatures: Development Environment Features + title: What's new in Grails 3.0? coreFeatures: Core Features + developmentEnvironmentFeatures: Development Environment Features webFeatures: Web Features persistenceFeatures: Persistence Features testingFeatures: Testing Features From 1251a021a432de7bde6d42a4bc28b63faa4738ae Mon Sep 17 00:00:00 2001 From: Graeme Rocher Date: Thu, 8 Jan 2015 17:12:44 +0100 Subject: [PATCH 025/230] Start updating the documentation for Grails 3.0 --- quick-publish.sh | 2 +- src/en/guide/commandLine.gdoc | 55 +- src/en/guide/commandLine/antAndMaven.gdoc | 258 ---------- .../guide/commandLine/buildCustomising.gdoc | 72 --- .../commandLine/creatingCustomScripts.gdoc | 42 ++ .../commandLine/creatingGantScripts.gdoc | 54 -- src/en/guide/commandLine/events.gdoc | 66 --- src/en/guide/commandLine/forkedMode.gdoc | 129 ----- src/en/guide/commandLine/interactiveMode.gdoc | 2 - src/en/guide/commandLine/profiles.gdoc | 113 +++++ .../commandLine/reusingGrailsScripts.gdoc | 88 ++-- src/en/guide/commandLine/wrapper.gdoc | 27 - src/en/guide/conf/config.gdoc | 113 ++--- src/en/guide/conf/config/builtInOptions.gdoc | 27 +- src/en/guide/conf/config/configGORM.gdoc | 13 +- src/en/guide/conf/config/logging.gdoc | 479 +----------------- src/en/guide/conf/configExternalized.gdoc | 33 -- .../conf/dataSource/JNDIDataSources.gdoc | 42 -- .../automaticDatabaseMigration.gdoc | 13 +- .../conf/dataSource/multipleDatasources.gdoc | 142 +++--- src/en/guide/conf/dependencyResolution.gdoc | 86 +--- .../changingDependencies.gdoc | 101 ---- .../configurationsAndDependencies.gdoc | 134 ----- .../debuggingResolution.gdoc | 20 - .../dependencyReports.gdoc | 33 -- .../dependencyRepositories.gdoc | 109 ---- .../dependencyResolutionCaching.gdoc | 27 - .../inheritedDependencies.gdoc | 13 - .../mavenIntegration.gdoc | 14 - .../dependencyResolution/mavendeploy.gdoc | 101 ---- .../pluginDependencies.gdoc | 91 ---- .../pluginJARDependencies.gdoc | 40 -- .../providingDefaultDependencies.gdoc | 25 - src/en/guide/conf/environments.gdoc | 24 +- src/en/guide/conf/versioning.gdoc | 16 +- .../conventionOverConfiguration.gdoc | 8 +- .../deployingAnApplication.gdoc | 18 +- .../downloadingAndInstalling.gdoc | 8 +- src/en/guide/gettingStarted/requirements.gdoc | 6 +- .../supportedJavaEEContainers.gdoc | 28 +- .../gettingStarted/testingAnApplication.gdoc | 2 +- .../gettingStarted/usingInteractiveMode.gdoc | 2 +- src/en/guide/toc.yml | 28 +- src/en/guide/upgradingFrom2.gdoc | 1 + src/en/guide/upgradingFrom22.gdoc | 197 ------- src/en/guide/upgradingFrom23.gdoc | 237 --------- 46 files changed, 393 insertions(+), 2746 deletions(-) delete mode 100644 src/en/guide/commandLine/antAndMaven.gdoc delete mode 100644 src/en/guide/commandLine/buildCustomising.gdoc create mode 100644 src/en/guide/commandLine/creatingCustomScripts.gdoc delete mode 100644 src/en/guide/commandLine/creatingGantScripts.gdoc delete mode 100644 src/en/guide/commandLine/events.gdoc delete mode 100644 src/en/guide/commandLine/forkedMode.gdoc create mode 100644 src/en/guide/commandLine/profiles.gdoc delete mode 100644 src/en/guide/commandLine/wrapper.gdoc delete mode 100644 src/en/guide/conf/configExternalized.gdoc delete mode 100644 src/en/guide/conf/dataSource/JNDIDataSources.gdoc delete mode 100644 src/en/guide/conf/dependencyResolution/changingDependencies.gdoc delete mode 100644 src/en/guide/conf/dependencyResolution/configurationsAndDependencies.gdoc delete mode 100644 src/en/guide/conf/dependencyResolution/debuggingResolution.gdoc delete mode 100644 src/en/guide/conf/dependencyResolution/dependencyReports.gdoc delete mode 100644 src/en/guide/conf/dependencyResolution/dependencyRepositories.gdoc delete mode 100644 src/en/guide/conf/dependencyResolution/dependencyResolutionCaching.gdoc delete mode 100644 src/en/guide/conf/dependencyResolution/inheritedDependencies.gdoc delete mode 100644 src/en/guide/conf/dependencyResolution/mavenIntegration.gdoc delete mode 100644 src/en/guide/conf/dependencyResolution/mavendeploy.gdoc delete mode 100644 src/en/guide/conf/dependencyResolution/pluginDependencies.gdoc delete mode 100644 src/en/guide/conf/dependencyResolution/pluginJARDependencies.gdoc delete mode 100644 src/en/guide/conf/dependencyResolution/providingDefaultDependencies.gdoc create mode 100644 src/en/guide/upgradingFrom2.gdoc delete mode 100644 src/en/guide/upgradingFrom22.gdoc delete mode 100644 src/en/guide/upgradingFrom23.gdoc diff --git a/quick-publish.sh b/quick-publish.sh index 5d7e1251e15..9bd7c704130 100755 --- a/quick-publish.sh +++ b/quick-publish.sh @@ -1 +1 @@ -./gradlew -Ddisable.groovydocs=true -Dgrails.home=../grails-master docs \ No newline at end of file +./gradlew -Ddisable.groovydocs=true -Dgrails.home=../dev docs \ No newline at end of file diff --git a/src/en/guide/commandLine.gdoc b/src/en/guide/commandLine.gdoc index dda06676b30..72697e04e8e 100644 --- a/src/en/guide/commandLine.gdoc +++ b/src/en/guide/commandLine.gdoc @@ -1,35 +1,26 @@ -Grails' command line system is built on [Gant|http://gant.codehaus.org/] - a simple Groovy wrapper around [Apache Ant|http://ant.apache.org]. +Grails 3.0's command line system differs greatly from previous versions of Grails and features APIs for invoking Gradle for build related tasks, as well as performing code generation. -However, Grails takes it further through the use of convention and the @grails@ command. When you type: +When you type: {code} grails [command name] {code} -Grails searches in the following directories for Gant scripts to execute: +Grails searches the [profile repository|https://github.com/grails/grails-profile-repository] based on the profile of the current application. If the profile is for a web application then commmands a read from the web profile and the base profile which it inherits from. -* @USER_HOME/.grails/scripts@ -* @PROJECT_HOME/scripts@ -* @PROJECT_HOME/plugins/*/scripts@ -* @GRAILS_HOME/scripts@ +Since command behavior is profile specific the web profile my provide different behavior for the @run-app@ command then say a profile for running batch applications. -Grails will also convert command names that are in lower case form such as run-app into camel case. So typing +When you type the following command: {code} grails run-app {code} -Results in a search for the following files: +It results in a search for the following files: -* @USER_HOME/.grails/scripts/RunApp.groovy@ * @PROJECT_HOME/scripts/RunApp.groovy@ -* @PLUGINS_HOME/*/scripts/RunApp.groovy@ -* @GLOBAL_PLUGINS_HOME/*/scripts/RunApp.groovy@ -* @GRAILS_HOME/scripts/RunApp.groovy@ - -If multiple matches are found Grails will give you a choice of which one to execute. - -When Grails executes a Gant script, it invokes the "default" target defined in that script. If there is no default, Grails will quit with an error. +* @PROFILE_REPOSITORY_PATH/profiles/web/commands/run-app.groovy@ (if the web profile is active) +* @PROFILE_REPOSITORY_PATH/profiles/web/commands/run-app.yml@ (for YAML defined commands) To get a list of all commands and some help about the available commands type: @@ -40,18 +31,17 @@ grails help which outputs usage instructions and the list of commands Grails is aware of: {code} -Usage (optionals marked with *): -grails [environment]* [target] [arguments]* - -Examples: -grails dev run-app -grails create-app books - -Available Targets (type grails help 'target-name' for more info): -grails bootstrap -grails bug-report -grails clean -grails compile +grails [environment]* [target] [arguments]*' + +| Examples: +$ grails dev run-app +$ grails create-app books + +| Available Commands (type grails help 'command-name' for more info): +| Command Name Command Description +---------------------------------------------------------------------------------------------------- +clean Cleans a Grails application's compiled sources +compile Compiles a Grails application ... {code} @@ -59,13 +49,6 @@ grails compile Refer to the Command Line reference in the Quick Reference menu of the reference guide for more information about individual commands {note} -It's often useful to provide custom arguments to the JVM when running Grails commands, in particular with @run-app@ where you may for example want to set a higher maximum heap size. The Grails command will use any JVM options provided in the general @JAVA_OPTS@ environment variable, but you can also specify a Grails-specific environment variable too: - -{code} -export GRAILS_OPTS="-Xmx1G -Xms256m -XX:MaxPermSize=256m" -grails run-app -{code} - h4. non-interactive mode When you run a script manually and it prompts you for information, you can answer the questions and continue running the script. But when you run a script as part of an automated process, for example a continuous integration build server, there's no way to "answer" the questions. So you can pass the @\-\-non-interactive@ switch to the script command to tell Grails to accept the default answer for any questions, for example whether to install a missing plugin. diff --git a/src/en/guide/commandLine/antAndMaven.gdoc b/src/en/guide/commandLine/antAndMaven.gdoc deleted file mode 100644 index ef7c881d333..00000000000 --- a/src/en/guide/commandLine/antAndMaven.gdoc +++ /dev/null @@ -1,258 +0,0 @@ -If all the other projects in your team or company are built using a standard build tool such as Ant or Maven, you become the black sheep of the family when you use the Grails command line to build your application. Fortunately, you can easily integrate the Grails build system into the main build tools in use today (well, the ones in use in Java projects at least). - - -h3. Maven Integration - -Grails provides integration with "Maven 3":http://maven.apache.org with a Maven plugin. - -h4. Preparation - -In order to use the Maven plugin, all you need is Maven 3 installed and set up. This is because *you no longer need to install Grails separately to use it with Maven!* - -{note} -The Maven 3 integration for Grails has been designed and tested for Maven 3.1.0 and above. It will not work with earlier versions. -{note} - - -h4. Creating a Grails Maven Project - -Using the @create-pom@ command you can generate a valid Maven @pom.xml@ file for any existing Grails project. The below presents an example: - -{code} -$ grails create-app myapp -$ cd myapp -$ grails create-pom com.mycompany -{code} - -The @create-pom@ command expects a group id as an argument. The name and the version are taken from the @application.properties@ of the application. The Maven plugin will keep the version in the @pom.xml@ in sync with the version in @application.properties@. - -The following standard Maven commands are then possible: - -* @compile@ - Compiles a Grails project -* @package@ - Builds a WAR file from the Grails project. -* @install@ - Builds a WAR file (or plugin zip/jar if a plugin) and installs it into your local Maven cache -* @test@ - Runs the tests of a Grails project -* @clean@ - Cleans the Grails project - -Other standard Maven commands will likely work too. - -You can also use some of the Grails commands that have been wrapped as Maven goals: - -* @grails:create-controller@ - Calls the [create-controller|commandLine] command -* @grails:create-domain-class@ - Calls the [create-domain-class|commandLine] command -* @grails:create-integration-test@ - Calls the [create-integration-test|commandLine] command -* @grails:create-pom@ - Creates a new Maven POM for an existing Grails project -* @grails:create-script@ - Calls the [create-script|commandLine] command -* @grails:create-service@ - Calls the [create-service|commandLine] command -* @grails:create-taglib@ - Calls the [create-tag-lib|commandLine] command -* @grails:create-unit-test@ - Calls the [create-unit-test|commandLine] command -* @grails:exec@ - Executes an arbitrary Grails command line script -* @grails:generate-all@ - Calls the [generate-all|commandLine] command -* @grails:generate-controller@ - Calls the [generate-controller|commandLine] command -* @grails:generate-views@ - Calls the [generate-views|commandLine] command -* @grails:install-templates@ - Calls the [install-templates|commandLine] command -* @grails:list-plugins@ - Calls the [list-plugins|commandLine] command -* @grails:package@ - Calls the [package|commandLine] command -* @grails:run-app@ - Calls the [run-app|commandLine] command - -For a complete, up to date list, run @mvn grails:help@ - -h4. Defining Plugin Dependencies - -All Grails plugins are published to a standard Maven repository located at [http://repo.grails.org/grails/plugins/]. When using the Maven plugin for Grails you must ensure that this repository is declared in your list of remote repositories: - -{code:xml} - - grails-plugins - grails-plugins - http://repo.grails.org/grails/plugins - -{code} - -With this done you can declare plugin dependencies within your @pom.xml@ file: - -{code:xml} - - org.grails.plugins - database-migration - 1.1 - runtime - zip - -{code} - -Note that the @type@ element must be set to @zip@. - -h4. Specifying the Grails Version to Use - -The 2.4.0 version of the Maven plugin works with different versions of Grails. By default it tries to auto-detect the version of Grails to use from the @grails-dependencies@ dependency definition found in the @pom.xml@: - -{code:xml} - - org.grails - grails-dependencies - 2.4.0 - -{code} - -If you change the version of @grails-dependencies@ then a different version of Grails will be used. However, you can also explicitly define the Grails version to be used in the plugin @configuration@: - -{code} - - org.grails - grails-maven-plugin - 2.4.0 - - 2.4.0 - - true - -{code} - -h4. Debugging Grails Execution - -The Maven plugin will run Grails commands in a separate process, meaning that the Grails process occupies a separate JVM as the Maven process. - -To debug the Grails process you need to configure the @forkDebug@ option in the plugin's @configuration@ tag: - -{code} - - org.grails - grails-maven-plugin - 2.4.0 - - true - - true - -{code} - -With this configuration in place the JVM executed in Maven will load in debug mode. - -If you need to customize the memory of the forked process the following elements are available: - -* @forkMaxMemory@ - The maximum amount of heap (default 1024) -* @forkMinMemory@ - The minimum amount of heap (default 512) -* @forkPermGen@ - The amount of permgen (default 256) - - -h4. Multi Module Maven Builds - -The Maven plugin can be used to power multi-module Grails builds. The easiest way to set this is up is with the @create-multi-project-build@ command: - -{code} -$ grails create-app myapp -$ grails create-plugin plugin1 -$ grails create-plugin plugin2 -$ grails create-multi-project-build org.mycompany:parent:1.0 -{code} - -Running @mvn install@ will build all projects together. To enable the 'grails' command to read the POMs you can modify @BuildConfig.groovy@ to use the POM and resolve dependencies from your Maven local cache: - -{code} -grails.project.dependency.resolution = { - ... - pom true - repositories { - ... - mavenLocal() - } -} -{code} - -By reading the @pom.xml@ file you can do an initial @mvn install@ from the parent project to build all plugins and install them into your local maven cache and then @cd@ into your project and use the regular @grails run-app@ command to run your application. All previously built plugins will be resolved from the local Maven cache. - -h4. Adding Grails commands to phases - -The standard POM created for you by Grails already attaches the appropriate core Grails commands to their corresponding build phases, so "compile" goes in the "compile" phase and "war" goes in the "package" phase. That doesn't help though when you want to attach a plugin's command to a particular phase. The classic example is functional tests. How do you make sure that your functional tests (using which ever plugin you have decided on) are run during the "integration-test" phase? - -Fear not: all things are possible. In this case, you can associate the command to a phase using an extra "execution" block: - -{code:xml} - - org.grails - grails-maven-plugin - 2.4.0 - true - - - - ... - - - - - functional-tests - integration-test - - exec - - - functional-tests - - - - -{code} - -This also demonstrates the @grails:exec@ goal, which can be used to run any Grails command. Simply pass the name of the command as the @command@ system property, and optionally specify the arguments with the @args@ property: - -{code} -mvn grails:exec -Dcommand=create-webtest -Dargs=Book -{code} - -h4. Raising issues - -If you come across any problems with the Maven integration, please raise a [JIRA issue|http://jira.grails.org/browse/MAVEN]. - - -h3. Ant Integration - -When you create a Grails application with the [create-app|commandLine] command, Grails doesn't automatically create an Ant @build.xml@ file but you can generate one with the [integrate-with|commandLine] command: - -bc. -grails integrate-with --ant - -This creates a @build.xml@ file containing the following targets: - -* @clean@ - Cleans the Grails application -* @compile@ - Compiles your application's source code -* @test@ - Runs the unit tests -* @run@ - Equivalent to "grails run-app" -* @war@ - Creates a WAR file -* @deploy@ - Empty by default, but can be used to implement automatic deployment - -Each of these can be run by Ant, for example: - -{code:java} -ant war -{code} - -The build file is configured to use "Apache Ivy":http://ant.apache.org/ivy/ for dependency management, which means that it will automatically download all the requisite Grails JAR files and other dependencies on demand. You don't even have to install Grails locally to use it! That makes it particularly useful for continuous integration systems such as [CruiseControl|http://cruisecontrol.sourceforge.net/] or [Jenkins|http://jenkins-ci.org/]. - -It uses the Grails [Ant task|api:grails.ant.GrailsTask] to hook into the existing Grails build system. The task lets you run any Grails script that's available, not just the ones used by the generated build file. To use the task, you must first declare it: -{code} - -{code} - -This raises the question: what should be in "grails.classpath"? The task itself is in the "grails-bootstrap" JAR artifact, so that needs to be on the classpath at least. You should also include the "groovy-all" JAR. With the task defined, you just need to use it! The following table shows you what attributes are available: -{table} - Attribute | Description | Required - home | The location of the Grails installation directory to use for the build. | Yes, unless classpath is specified. - classpathref | Classpath to load Grails from. Must include the "grails-bootstrap" artifact and should include "grails-scripts". | Yes, unless @home@ is set or you use a @classpath@ element. - script | The name of the Grails script to run, e.g. "TestApp". | Yes. - args | The arguments to pass to the script, e.g. "-unit -xml". | No. Defaults to "". - environment | The Grails environment to run the script in. | No. Defaults to the script default. - includeRuntimeClasspath | Advanced setting: adds the application's runtime classpath to the build classpath if true. | No. Defaults to @true@. -{table} - -The task also supports the following nested elements, all of which are standard Ant path structures: - -* @classpath@ - The build classpath (used to load Gant and the Grails scripts). -* @compileClasspath@ - Classpath used to compile the application's classes. -* @runtimeClasspath@ - Classpath used to run the application and package the WAR. Typically includes everything in @compileClasspath. -* @testClasspath@ - Classpath used to compile and run the tests. Typically includes everything in @runtimeClasspath@. - -How you populate these paths is up to you. If you use the @home@ attribute and put your own dependencies in the @lib@ directory, then you don't even need to use any of them. For an example of their use, take a look at the generated Ant build file for new apps. diff --git a/src/en/guide/commandLine/buildCustomising.gdoc b/src/en/guide/commandLine/buildCustomising.gdoc deleted file mode 100644 index 5d056f5afa7..00000000000 --- a/src/en/guide/commandLine/buildCustomising.gdoc +++ /dev/null @@ -1,72 +0,0 @@ -Grails is most definitely an opinionated framework and it prefers convention to configuration, but this doesn't mean you _can't_ configure it. In this section, we look at how you can influence and modify the standard Grails build. - -h3. The defaults - -The core of the Grails build configuration is the @grails.util.BuildSettings@ class, which contains quite a bit of useful information. It controls where classes are compiled to, what dependencies the application has, and other such settings. - -Here is a selection of the configuration options and their default values: -{table} -*Property* | *Config option* | *Default value* -grailsWorkDir | grails.work.dir | $USER_HOME/.grails/ -projectWorkDir | grails.project.work.dir | /projects/ -classesDir | grails.project.class.dir | /classes -testClassesDir | grails.project.test.class.dir | /test-classes -testReportsDir | grails.project.test.reports.dir | /test/reports -resourcesDir | grails.project.resource.dir | /resources -projectPluginsDir | grails.project.plugins.dir | /plugins -globalPluginsDir | grails.global.plugins.dir | /global-plugins -verboseCompile | grails.project.compile.verbose | @false@ -{table} - -The @BuildSettings@ class has some other properties too, but they should be treated as read-only: -{table} -*Property* | *Description* -baseDir | The location of the project. -userHome | The user's home directory. -grailsHome | The location of the Grails installation in use (may be @null@). -grailsVersion | The version of Grails being used by the project. -grailsEnv | The current Grails environment. -config | The configuration settings defined in the project's @BuildConfig.groovy@ file. Access properties in the same way as you access runtime settings: @grailsSettings.config.foo.bar.hello@. -compileDependencies | A list of compile-time project dependencies as @File@ instances. -testDependencies | A list of test-time project dependencies as @File@ instances. -runtimeDependencies | A list of runtime-time project dependencies as @File@ instances. -{table} - -Of course, these properties aren't much good if you can't get hold of them. Fortunately that's easy to do: an instance of @BuildSettings@ is available to your scripts as the @grailsSettings@ script variable. You can also access it from your code by using the @grails.util.BuildSettingsHolder@ class, but this isn't recommended. - -h3. Overriding the defaults - -All of the properties in the first table can be overridden by a system property or a configuration option - simply use the "config option" name. For example, to change the project working directory, you could either run this command: -{code} -grails -Dgrails.project.work.dir=work compile -{code} -or add this option to your @grails-app/conf/BuildConfig.groovy@ file: -{code} -grails.project.work.dir = "work" -{code} -Note that the default values take account of the property values they depend on, so setting the project working directory like this would also relocate the compiled classes, test classes, resources, and plugins. - -What happens if you use both a system property and a configuration option? Then the system property wins because it takes precedence over the @BuildConfig.groovy@ file, which in turn takes precedence over the default values. - -The @BuildConfig.groovy@ file is a sibling of @grails-app/conf/Config.groovy@ - the former contains options that only affect the build, whereas the latter contains those that affect the application at runtime. It's not limited to the options in the first table either: you will find build configuration options dotted around the documentation, such as ones for specifying the port that the embedded servlet container runs on or for determining what files get packaged in the WAR file. - -h3. Available build settings - -{table} - Name | Description - grails.server.port.http | Port to run the embedded servlet container on ("run-app" and "run-war"). Integer. - grails.server.port.https | Port to run the embedded servlet container on for HTTPS ("run-app \-\-https" and "run-war \-\-https"). Integer. - grails.config.base.webXml | Path to a custom web.xml file to use for the application (alternative to using the web.xml template). - grails.compiler.dependencies | Legacy approach to adding extra dependencies to the compiler classpath. Set it to a closure containing "fileset()" entries. These entries will be processed by an @AntBuilder@ so the syntax is the Groovy form of the corresponding XML elements in an Ant build file, e.g. @fileset(dir: "$basedir/lib", includes: "\*\*/\*.class")@. - grails.testing.patterns | A list of Ant path patterns that let you control which files are included in the tests. The patterns should not include the test case suffix, which is set by the next property. - grails.testing.nameSuffix | By default, tests are assumed to have a suffix of "Tests". You can change it to anything you like but setting this option. For example, another common suffix is "Test". - grails.project.war.file | A string containing the file path of the generated WAR file, along with its full name (include extension). For example, "target/my-app.war". - grails.war.dependencies | A closure containing "fileset()" entries that allows you complete control over what goes in the WAR's "WEB-INF/lib" directory. - grails.war.copyToWebApp | A closure containing "fileset()" entries that allows you complete control over what goes in the root of the WAR. It overrides the default behaviour of including everything under "web-app". - grails.war.resources | A closure that takes the location of the staging directory as its first argument. You can use any Ant tasks to do anything you like. It is typically used to remove files from the staging directory before that directory is jar'd up into a WAR. - grails.project.web.xml | The location to generate Grails' web.xml to -{table} - -h3. Reloading Agent Cache Directory - -Grails uses an agent based reloading system in the development environment that allows source code changes to be picked up while the application is running. This reloading agent caches information needed to carry out the reloading efficiently. By default this information is stored under @\\/.grails\/.slcache\/@. The @GRAILS_AGENT_CACHE_DIR@ environment variable may be assigned a value to cause this cache information to be stored somewhere else. Note that this is an operating system environment variable, not a JVM system property or a property which may be defined in @BuildConfig.groovy@. This setting must be defined as an environment variable because the agent cache directory must be configured very early in the JVM startup process, before any Grails code is executed. diff --git a/src/en/guide/commandLine/creatingCustomScripts.gdoc b/src/en/guide/commandLine/creatingCustomScripts.gdoc new file mode 100644 index 00000000000..d6d4db79168 --- /dev/null +++ b/src/en/guide/commandLine/creatingCustomScripts.gdoc @@ -0,0 +1,42 @@ + +You can create your own Command scripts by running the [create-script|commandLine] command from the root of your project. For example the following command: + +{code} +grails create-script hello-world +{code} + + + +Will create a script called @src/main/scripts/hello-world.groovy@. Each Command script is extends from the [GroovyScriptCommmand|api:org.grails.cli.profile.commands.script.GroovyScriptCommmand] class and hence has all of the methods of that class available to it. + +{note} +In general Grails scripts should be used for scripting the Gradle based build system and code generation. Scripts cannot load application classes and in fact should not since Gradle is required to construct the application classpath. +{note} + +See below for an example script that prints 'Hello World': + +{code} +description "Example description", "grails hello-world" + +println "Hello World" +{code} + +The @description@ method is used to define the output seen by @grails help@ and to aid users of the script. The following is a more complete example of providing a description taken from the @generate-all@ command: + +{code} +description( "Generates a controller that performs CRUD operations and the associated views" ) { + usage "grails generate-all [DOMAIN CLASS]" + flag name:'force', description:"Whether to overwrite existing files" + argument name:'Domain Class', description:'The name of the domain class' +} +{code} + +As you can see this description profiles usage instructions, a flag and an argument. This allows the command to be used as follows: + +{code} +grails generate-all MyClass --force +{code} + + + + diff --git a/src/en/guide/commandLine/creatingGantScripts.gdoc b/src/en/guide/commandLine/creatingGantScripts.gdoc deleted file mode 100644 index e8321222127..00000000000 --- a/src/en/guide/commandLine/creatingGantScripts.gdoc +++ /dev/null @@ -1,54 +0,0 @@ -You can create your own Gant scripts by running the [create-script|commandLine] command from the root of your project. For example the following command: - -{code} -grails create-script compile-sources -{code} - -Will create a script called @scripts/CompileSources.groovy@. A Gant script itself is similar to a regular Groovy script except that it supports the concept of "targets" and dependencies between them: - -{code:title=scripts/CompileSources.groovy} -target(default:"The default target is the one that gets executed by Grails") { - depends(clean, compile) -} - -target(clean:"Clean out things") { - ant.delete(dir:"output") -} - -target(compile:"Compile some sources") { - ant.mkdir(dir:"mkdir") - ant.javac(srcdir:"src/java", destdir:"output") -} -{code} - -As demonstrated in the script above, there is an implicit @ant@ variable (an instance of @groovy.util.AntBuilder@) that allows access to the [Apache Ant API|http://ant.apache.org/manual/index.html]. -{note} -In previous versions of Grails (1.0.3 and below), the variable was @Ant@, i.e. with a capital first letter. -{note} - -You can also "depend" on other targets using the @depends@ method demonstrated in the @default@ target above. - -h3. The default target - -In the example above, we specified a target with the explicit name "default". This is one way of defining the default target for a script. An alternative approach is to use the @setDefaultTarget()@ method: - -{code:title=scripts/CompileSources.groovy} -target("clean-compile": "Performs a clean compilation on the app source") { - depends(clean, compile) -} - -target(clean:"Clean out things") { - ant.delete(dir:"output") -} - -target(compile:"Compile some sources") { - ant.mkdir(dir:"mkdir") - ant.javac(srcdir:"src/java", destdir:"output") -} - -setDefaultTarget("clean-compile") -{code} - -This lets you call the default target directly from other scripts if you wish. Also, although we have put the call to @setDefaultTarget()@ at the end of the script in this example, it can go anywhere as long as it comes _after_ the target it refers to ("clean-compile" in this case). - -Which approach is better? To be honest, you can use whichever you prefer - there don't seem to be any major advantages in either case. One thing we would say is that if you want to allow other scripts to call your "default" target, you should move it into a shared script that doesn't have a default target at all. We'll talk some more about this in the next section. diff --git a/src/en/guide/commandLine/events.gdoc b/src/en/guide/commandLine/events.gdoc deleted file mode 100644 index 56fc3028a4b..00000000000 --- a/src/en/guide/commandLine/events.gdoc +++ /dev/null @@ -1,66 +0,0 @@ -Grails provides the ability to hook into scripting events. These are events triggered during execution of Grails target and plugin scripts. - -The mechanism is deliberately simple and loosely specified. The list of possible events is not fixed in any way, so it is possible to hook into events triggered by plugin scripts, for which there is no equivalent event in the core target scripts. - -h4. Defining event handlers - -Event handlers are defined in scripts called @_Events.groovy@. Grails searches for these scripts in the following locations: - -* @USER_HOME/.grails/scripts@ - user-specific event handlers -* @PROJECT_HOME/scripts@ - applicaton-specific event handlers -* @PLUGINS_HOME/*/scripts@ - plugin-specific event handlers -* @GLOBAL_PLUGINS_HOME/*/scripts@ - event handlers provided by global plugins - -Whenever an event is fired, _all_ the registered handlers for that event are executed. Note that the registration of handlers is performed automatically by Grails, so you just need to declare them in the relevant @_Events.groovy@ file. - -Event handlers are blocks defined in @_Events.groovy@, with a name beginning with "event". The following example can be put in your /scripts directory to demonstrate the feature: - -{code} -eventCreatedArtefact = { type, name -> - println "Created $type $name" -} - -eventStatusUpdate = { msg -> - println msg -} - -eventStatusFinal = { msg -> - println msg -} -{code} - -You can see here the three handlers @eventCreatedArtefact@, @eventStatusUpdate@, @eventStatusFinal@. Grails provides some standard events, which are documented in the command line reference guide. For example the [compile|commandLine] command fires the following events: - -* @CompileStart@ - Called when compilation starts, passing the kind of compile - source or tests -* @CompileEnd@ - Called when compilation is finished, passing the kind of compile - source or tests - -h4. Triggering events - -To trigger an event simply include the Init.groovy script and call the event() closure: - -{code} -includeTargets << grailsScript("_GrailsEvents") - -event("StatusFinal", ["Super duper plugin action complete!"]) -{code} - -h4. Common Events - -Below is a table of some of the common events that can be leveraged: - -{table} -Event | Parameters | Description - StatusUpdate | message | Passed a string indicating current script status/progress - StatusError | message | Passed a string indicating an error message from the current script - StatusFinal | message | Passed a string indicating the final script status message, i.e. when completing a target, even if the target does not exit the scripting environment - CreatedArtefact | artefactType,artefactName | Called when a create-xxxx script has completed and created an artefact - CreatedFile | fileName | Called whenever a project source filed is created, not including files constantly managed by Grails - Exiting | returnCode | Called when the scripting environment is about to exit cleanly - PluginInstalled | pluginName | Called after a plugin has been installed - CompileStart | kind | Called when compilation starts, passing the kind of compile - source or tests - CompileEnd | kind | Called when compilation is finished, passing the kind of compile - source or tests - DocStart | kind | Called when documentation generation is about to start - javadoc or groovydoc - DocEnd | kind | Called when documentation generation has ended - javadoc or groovydoc - SetClasspath | rootLoader | Called during classpath initialization so plugins can augment the classpath with rootLoader.addURL(...). Note that this augments the classpath *after* event scripts are loaded so you cannot use this to load a class that your event script needs to import, although you can do this if you load the class by name. - PackagingEnd | none | Called at the end of packaging (which is called prior to the Tomcat server being started and after web.xml is generated) -{table} diff --git a/src/en/guide/commandLine/forkedMode.gdoc b/src/en/guide/commandLine/forkedMode.gdoc deleted file mode 100644 index 6d21d61c2d3..00000000000 --- a/src/en/guide/commandLine/forkedMode.gdoc +++ /dev/null @@ -1,129 +0,0 @@ -h4. Forked Execution - -Since Grails 2.3, the @run-app@, @run-war@, @test-app@ and @console@ commands are now executed in a forked JVM in order to isolate the build classpath from the runtime classpath. - -Forked execution is configured via the @grails-app/conf/BuildConfig.groovy@ file. The following is the default configuration: - -{code} -grails.project.fork = [ - test: [maxMemory: 768, minMemory: 64, debug: false, maxPerm: 256, daemon:true], // configure settings for the test-app JVM - run: [maxMemory: 768, minMemory: 64, debug: false, maxPerm: 256], // configure settings for the run-app JVM - war: [maxMemory: 768, minMemory: 64, debug: false, maxPerm: 256], // configure settings for the run-war JVM - console: [maxMemory: 768, minMemory: 64, debug: false, maxPerm: 256]// configure settings for the Console UI JVM -] -{code} - -The memory requirements of the forked JVM can be tweaked as per the requirements of the application. - -h4. Forked Test Execution - -When running the [test-app|commandLine] command, a separate JVM is launched to execute this tests. This will have a notable impact on the speed of execution of the tests when running the command directly: - -{code} -grails test-app -{code} - -To mitigate this, Grails 2.3 and above include a feature that launches a background JVM on standby to run tests when using interactive mode. In other words, running @test-app@ from interactive mode will result in faster test execution times: - -{code} -$ grails -$ grails> test-app -{code} - -It is recommended that forked execution is used for tests, however it does require modern hardware due to the use of multiple JVMs. You can therefore disable forked execution by setting the @grails.project.fork.test@ setting to @false@: - -{code} -forkConfig = [maxMemory: 1024, minMemory: 64, debug: false, maxPerm: 256] -grails.project.fork = [ - test: false, - ... -] -{code} - -h4. Using the Test Runner Daemon to Speed-up Test Execution - -The default configuration for the testing is to activate a daemon to run tests using the @daemon@ argument: - -{code} -grails.project.fork = [ - test: [maxMemory: 768, minMemory: 64, debug: false, maxPerm: 256, daemon:true], // configure settings for the test-app JVM - ... -{code} - -This only works in interactive mode, so if you start Grails with the 'grails' command and then using @test-app@ the daemon will be used: - -{code} -$ grails -$ grails> test-app -{code} - -This has the effect of speeding-up test executions times. You can disable the daemon by setting @daemon@ to @false@. If the @daemon@ becomes unresponsive you can restart it with @restart-daemon@: - -{code} -$ grails> restart-daemon -{code} - - -h4. Debugging and Forked Execution (\--debug vs \--debug-fork) - -An important consideration when using forked execution is that the @debug@ argument will allow a remote debugger to be attached to the build JVM but not the JVM that your application is running in. To debug your application you should use the @debug-fork@ argument: - -{code} -grails test-app --debug-fork -{code} - -Or for run-app: - -{code} -grails run-app --debug-fork -{code} - - -h4. Forked Tomcat Execution - -Grails 2.2 and above support forked JVM execution of the Tomcat container in development mode. This has several benefits including: - -* Reduced memory consumption, since the Grails build system can exit -* Isolation of the build classpath from the runtime classpath -* The ability to deploy other Grails/Spring applications in parallels without conflicting dependencies - -To enable forked execution you can set the @grails.project.fork.run@ property to @true@: - -{code} -grails.project.fork.run=true -{code} - -Then just us the regular @run-app@ command as per normal. Note that in forked mode the @grails@ process will exit and leave the container running in the background. To stop the server there is a new @stop-app@ command: - -{code} -grails stop-app -{code} - -To customize the JVM arguments passed to the forked JVM you can specify a map instead: - -{code} -grails.project.fork.run= [maxMemory:1024, minMemory:64, debug:false, maxPerm:256, jvmArgs: '..arbitrary JVM arguments..'] -{code} - -h4. Auto-deploying additional WAR files in Forked Mode - -Since forked execution isolates classpaths more effectively than embedded execution you can deploy additional WAR files (such as other Grails or Spring applications) to the container. - -The easiest way to do so is to drop the WAR files into the @src/autodeploy@ directory (if it doesn't exist you can create it). - -You can customize the location of the autodeploy directory by specifying an alternative location in @BuildConfig.groovy@: - -{code} -grails.project.autodeploy.dir="/path/to/my/war/files" -{code} - -h4. Customizing the Forked Tomcat instance - -If you want to programmatically customize the forked [Tomcat|http://tomcat.apache.org/tomcat-7.0-doc/api/org/apache/catalina/startup/Tomcat.html] instance you can do so by implementing a class named @org.grails.plugins.tomcat.ForkedTomcatCustomizer@ which provides a method with the following signature: - -{code} -void customize(Tomcat tomcat) { - // your code here -} -{code} - diff --git a/src/en/guide/commandLine/interactiveMode.gdoc b/src/en/guide/commandLine/interactiveMode.gdoc index 96e79feeaf8..028538a9d07 100644 --- a/src/en/guide/commandLine/interactiveMode.gdoc +++ b/src/en/guide/commandLine/interactiveMode.gdoc @@ -18,6 +18,4 @@ If you need to run an external process whilst interactive mode is running you ca Note that with \! (bang) commands, you get file path auto completion - ideal for external commands that operate on the file system such as 'ls', 'cat', 'git', etc. -The @stop-app@ command will stop an application that has been run with the @run-app@ command. - To exit interactive mode enter the @exit@ command. Note that if the Grails application has been run with @run-app@ normally it will terminate when the interactive mode console exits because the JVM will be terminated. An exception to this would be if the application were running in forked mode which means the application is running in a different JVM. In that case the application will be left running after the interactive mode console terminates. If you want to exit interactive mode and stop an application that is running in forked mode, use the @quit@ command. The @quit@ command will stop the running application and then close interactive mode. diff --git a/src/en/guide/commandLine/profiles.gdoc b/src/en/guide/commandLine/profiles.gdoc new file mode 100644 index 00000000000..ec17927643d --- /dev/null +++ b/src/en/guide/commandLine/profiles.gdoc @@ -0,0 +1,113 @@ +When you create a Grails application with the [create-app|commandLine] command by default the "web" profile is used: + +{code} +grails create-app myapp +{code} + +You can specify a different profile with the profile argument: + +{code} +grails create-app myapp --profile=web-plugin +{code} + +Profiles encapsulate the project commands, templates and plugins that are designed to work for a given profile. They are stored in the [Grails Profile Repository|https://github.com/grails/grails-profile-repository] on Github. + +This repository is checked out locally and stored in the @USER_HOME/.grails/repository@ directory. + +h4. Understanding a Profile's Structure + +A profile is a simple directory that contains a @profile.yml@ file and directorys containing the "commands", "skeleton" and "templates" defined by the profile. Example: + +{code} +web + * commands + * create-controller.yml + * run-app.groovy + ... + * skeleton + * grails-app + * controllers + ... + * build.gradle + * templates + * artifacts + * Controller.groovy + * profile.yml +{code} + +The above example is a snippet of structure of the 'web' profile. The @profile.yml@ file is defined as follows: + +{code} +description: Profile for Web applications +extends: base +{code} + +As you can see it contains the description of the profile and a definition of which profiles this profile extends, since one profile can extend from another. + +When the @create-app@ command runs it takes the skeleton of the parent profiles and copies the skeletons into a new project structure. Child profiles overwrite files from the parent profile so if the parent defines a @build.gradle@ then the child profile will override the parent. + +h4. Defining Profile Commands + +A profile can define new commands that apply only to that profile using YAML or Groovy scripts. Below is an example of the [create-controller|commandLine] command defined in YAML: + +{code} +description: + - Creates a controller + - usage: 'create-controller [controller name]' + - completer: org.grails.cli.interactive.completers.DomainClassCompleter + - argument: "Controller Name" + description: "The name of the controller" +steps: + - command: render + template: templates/artifacts/Controller.groovy + destination: grails-app/controllers/@artifact.package.path@/@artifact.name@Controller.groovy + - command: render + template: templates/testing/Controller.groovy + destination: src/test/groovy/@artifact.package.path@/@artifact.name@ControllerSpec.groovy + - command: mkdir + location: grails-app/views/@artifact.propertyName@ +{code} + +Commands defined in YAML must define one or many steps. Each step is a command in itself. The available step types are: + +* @render@ - To render a template to a given destination (as seen in the previous example) +* @mkdir@ - To make a directory specified by the @location@ parameter +* @execute@ - To execute a command specified by the @class@ parameter. Must be a class that implements the [Command|api:org.grails.cli.profile.Command] interface. +* @gradle@ - To execute one or many Gradle tasks specified by the @tasks@ parameter. + +For example to invoke a Gradle task, you can define the following YAML: + +{code} +description: Creates a WAR file for deployment to a container (like Tomcat) +minArguments: 0 +usage: | + war +steps: + - command: gradle + tasks: + - war +{code} + +If you need more flexiblity than what the declarative YAML approach provides you can create Groovy script commands. Each Command script is extends from the [GroovyScriptCommmand|api:org.grails.cli.profile.commands.script.GroovyScriptCommmand] class and hence has all of the methods of that class available to it. + +The following is an example of the [create-script|commandLine] command written in Groovy: + +{code} +description( "Creates a Grails script" ) { + usage "grails create-script [SCRIPT NAME]" + argument name:'Script Name', description:"The name of the script to create" + flag name:'force', description:"Whether to overwrite existing files" +} + +def scriptName = args[0] +def model = model(scriptName) +def overwrite = flag('force') ? true : false + +render template: template('artifacts/Script.groovy'), + destination: file("src/main/scripts/${model.lowerCaseName}.groovy"), + model: model, + overwrite: overwrite +{code} + +For more information on creating Groovy commands see the following section on creating custom Grails scripts. + diff --git a/src/en/guide/commandLine/reusingGrailsScripts.gdoc b/src/en/guide/commandLine/reusingGrailsScripts.gdoc index 2f67a2642f6..8b4e3845069 100644 --- a/src/en/guide/commandLine/reusingGrailsScripts.gdoc +++ b/src/en/guide/commandLine/reusingGrailsScripts.gdoc @@ -1,80 +1,54 @@ -Grails ships with a lot of command line functionality out of the box that you may find useful in your own scripts (See the command line reference in the reference guide for info on all the commands). Of particular use are the [compile|commandLine], [package|commandLine] and [bootstrap|commandLine] scripts. +Grails ships with a lot of command line functionality out of the box that you may find useful in your own scripts (See the command line reference in the reference guide for info on all the commands). -The [bootstrap|commandLine] script for example lets you bootstrap a Spring [ApplicationContext|api:org.springframework.context.ApplicationContext] instance to get access to the data source and so on (the integration tests use this): +Any script you create an invoke another Grails script simply by invoking a method: {code} - -includeTargets << grailsScript("_GrailsBootstrap") - -target ('default': "Database stuff") { - depends(configureProxy, packageApp, classpath, loadApp, configureApp) - - Connection c - try { - c = appCtx.getBean('dataSource').getConnection() - // do something with connection - } - finally { - c?.close() - } -} +testApp() {code} -h3. Pulling in targets from other scripts +The above will invoke the @test-app@ command. You can also pass arguments using the method arguments: -Gant lets you pull in all targets (except "default") from another Gant script. You can then depend upon or invoke those targets as if they had been defined in the current script. The mechanism for doing this is the @includeTargets@ property. Simply "append" a file or class to it using the left-shift operator: {code} -includeTargets << new File("/path/to/my/script.groovy") -includeTargets << gant.tools.Ivy +testApp('--debug-jvm') {code} -Don't worry too much about the syntax using a class, it's quite specialised. If you're interested, look into the Gant documentation. - -h3. Core Grails targets -As you saw in the example at the beginning of this section, you use neither the File- nor the class-based syntax for @includeTargets@ when including core Grails targets. Instead, you should use the special @grailsScript()@ method that is provided by the Grails command launcher (note that this is not available in normal Gant scripts, just Grails ones). +h4. Invoking Gradle -The syntax for the @grailsScript()@ method is pretty straightforward: simply pass it the name of the Grails script to include, without any path information. Here is a list of Grails scripts that you could reuse: -{table} - *Script* | *Description* - \_GrailsSettings | You really should include this! Fortunately, it is included automatically by all other Grails scripts except \_GrailsProxy, so you usually don't have to include it explicitly. - \_GrailsEvents | Include this to fire events. Adds an @event(String eventName, List args)@ method. Again, included by almost all other Grails scripts. - \_GrailsClasspath | Configures compilation, test, and runtime classpaths. If you want to use or play with them, include this script. Again, included by almost all other Grails scripts. - \_GrailsProxy | If you don't have direct access to the internet and use a proxy, include this script to configure access through your proxy. - \_GrailsArgParsing | Provides a @parseArguments@ target that does what it says on the tin: parses the arguments provided by the user when they run your script. Adds them to the @argsMap@ property. - \_GrailsTest | Contains all the shared test code. Useful if you want to add any extra tests. - \_GrailsRun | Provides all you need to run the application in the configured servlet container, either normally (@runApp@/@runAppHttps@) or from a WAR file (@runWar@/@runWarHttps@). - {table} +Instead of invoking another Grails CLI command you can invoke Gradle directory using the @gradle@ property. -There are many more scripts provided by Grails, so it is worth digging into the scripts themselves to find out what kind of targets are available. Anything that starts with an "\_" is designed for reuse. +{code} +gradle.compileGroovy() +{code} -h3. Script architecture +h4. Invoking Ant -You maybe wondering what those underscores are doing in the names of the Grails scripts. That is Grails' way of determining that a script is _internal_, or in other words that it has not corresponding "command". So you can't run "grails \_grails-settings" for example. That is also why they don't have a default target. +You can also invoke Ant tasks from scripts which can help if you need to writing code generation and automation tasks: -Internal scripts are all about code sharing and reuse. In fact, we recommend you take a similar approach in your own scripts: put all your targets into an internal script that can be easily shared, and provide simple command scripts that parse any command line arguments and delegate to the targets in the internal script. For example if you have a script that runs some functional tests, you can split it like this: {code} -./scripts/FunctionalTests.groovy: +ant.mkdir(dir:"path") +{code} -includeTargets << new File("${basedir}/scripts/_FunctionalTests.groovy") +h4. Template Generation -target(default: "Runs the functional tests for this project.") { - depends(runFunctionalTests) -} +Plugins and applications that need to define template generation tasks can do so using scripts. A example of this is the Scaffolding plugin which defines the @generate-all@ and @generate-controllers@ commands. -./scripts/_FunctionalTests.groovy: +Every Grails script implements the [TemplateRenderer|api:org.grails.cli.profile.commands.templates.TemplateRenderer] interface which makes it trivial to render templates to the users project workspace. -includeTargets << grailsScript("_GrailsTest") +The following is an example of the [create-script|commandLine] command written in Groovy: -target(runFunctionalTests: "Run functional tests.") { - depends(...) - ... -} {code} +description( "Creates a Grails script" ) { + usage "grails create-script [SCRIPT NAME]" + argument name:'Script Name', description:"The name of the script to create" + flag name:'force', description:"Whether to overwrite existing files" +} -Here are a few general guidelines on writing scripts: +def scriptName = args[0] +def model = model(scriptName) +def overwrite = flag('force') ? true : false -* Split scripts into a "command" script and an internal one. -* Put the bulk of the implementation in the internal script. -* Put argument parsing into the "command" script. -* To pass arguments to a target, create some script variables and initialise them before calling the target. -* Avoid name clashes by using closures assigned to script variables instead of targets. You can then pass arguments direct to the closures. +render template: template('artifacts/Script.groovy'), + destination: file("src/main/scripts/${model.lowerCaseName}.groovy"), + model: model, + overwrite: overwrite +{code} diff --git a/src/en/guide/commandLine/wrapper.gdoc b/src/en/guide/commandLine/wrapper.gdoc deleted file mode 100644 index 98d5f96ec29..00000000000 --- a/src/en/guide/commandLine/wrapper.gdoc +++ /dev/null @@ -1,27 +0,0 @@ -The Grails Wrapper allows a Grails application to built without having to install Grails and configure a GRAILS_HOME environment variable. The wrapper includes a small shell script and a couple of small bootstrap jar files that typically would be checked in to source code control along with the rest of the project. The first time the wrapper is executed it will download and configure a Grails installation. This wrapper makes it more simple to setup a development environment, configure CI and manage upgrades to future versions of Grails. When the application is upgraded to the next version of Grails, the wrapper is updated and checked in to the source code control system and the next time developers update their workspace and run the wrapper, they will automatically be using the correct version of Grails. - -h4. Generating The Wrapper - -The [wrapper|commandLine] command can be used to generate the wrapper shell scripts and supporting jar files. Execute the wrapper command at the top of an existing Grails project. - -{code} -grails wrapper -{code} - -In order to do this of course Grails must be installed and configured. This is only a requirement for bootstrapping the wrapper. Once the wrapper is generated there is no need to have a Grails installation configured in order to use the wrapper. - -See the [wrapper|commandLine] command documentation for details about command line arguments. - -By default the wrapper command will generate a @grailsw@ shell script and @grailsw.bat@ batch file at the top of the project. In addition to those, a @wrapper/@ directory (the name of the directory is configurable via command line options) is generated which contains some support files which are necessary to run the wrapper. All of these files should be checked into the source code control system along with the rest of the project. This allows developers to check the project out of source code control and immediately start using the wrapper to execute Grails commands without having to install and configure Grails. - -h4. Using The Wrapper - -The wrapper script accepts all of the same arguments as the normal grails command. - -{code} -./grailsw create-domain-class com.demo.Person -./grailsw run-app -./grailsw test-app unit: - -etc... -{code} diff --git a/src/en/guide/conf/config.gdoc b/src/en/guide/conf/config.gdoc index 9fcf6a9095d..51bf6f52242 100644 --- a/src/en/guide/conf/config.gdoc +++ b/src/en/guide/conf/config.gdoc @@ -1,56 +1,10 @@ -For general configuration Grails provides two files: +Configuration in Grails is generally split across 2 areas: build configuration and runtime configuration. -* @grails-app/conf/BuildConfig.groovy@ -* @grails-app/conf/Config.groovy@ +Build configuration is generally done via Gradle and the @build.gradle@ file. Runtime configuration is by default specified in YAML in the @grails-app/conf/application.yml@ file. -Both of them use Groovy's "ConfigSlurper":http://groovy.codehaus.org/ConfigSlurper syntax. The first, @BuildConfig.groovy@, is for settings that are used when running Grails commands, such as @compile@, @doc@, etc. The second file, @Config.groovy@, is for settings that are used when your application is running. This means that @Config.groovy@ is packaged with your application, but @BuildConfig.groovy@ is not. Don't worry if you're not clear on the distinction: the guide will tell you which file to put a particular setting in. +If you prefer to use Grails 2.0-style Groovy configuration then you can create an additional @grails-app/conf/application.groovy@ file to specify configuration using Groovy's "ConfigSlurper":http://groovy.codehaus.org/ConfigSlurper syntax. -The most basic syntax is similar to that of Java properties files with dot notation on the left-hand side: - -{code} -foo.bar.hello = "world" -{code} - -Note that the value is a Groovy string literal! Those quotes around 'world' are important. In fact, this highlights one of the advantages of the ConfigSlurper syntax over properties files: the property values can be any valid Groovy type, such as strings, integers, or arbitrary objects! - -Things become more interesting when you have multiple settings with the same base. For example, you could have the two settings - -{code} -foo.bar.hello = "world" -foo.bar.good = "bye" -{code} - -both of which have the same base: @foo.bar@. The above syntax works but it's quite repetitive and verbose. You can remove some of that verbosity by nesting properties at the dots: - -{code} -foo { - bar { - hello = "world" - good = "bye" - } -} -{code} - -or by only partially nesting them: - -{code} -foo { - bar.hello = "world" - bar.good = "bye" -} -{code} - -However, you can't nest after using the dot notation. In other words, this *won't* work: - -{code} -// Won't work! -foo.bar { - hello = "world" - good = "bye" -} -{code} - -Within both @BuildConfig.groovy@ and @Config.groovy@ you can access several implicit variables from configuration values: +For Groovy configuration the following variables are available to the configuration script: {table} *Variable* | *Description* @@ -66,55 +20,56 @@ For example: my.tmp.dir = "\${userHome}/.grails/tmp" {code} -In addition, @BuildConfig.groovy@ has - -{table} -*Variable* | *Description* -grailsVersion | The version of Grails used to build the project. -grailsSettings | An object containing various build related settings, such as @baseDir@. It's of type [@BuildSettings@|api:grails.util.BuildSettings]. -{table} - -and @Config.groovy@ has - -{table} -*Variable* | *Description* -grailsApplication | The [@GrailsApplication@|api:org.codehaus.groovy.grails.commons.GrailsApplication] instance. -{table} - -Those are the basics of adding settings to the configuration file, but how do you access those settings from your own application? That depends on which config you want to read. -The settings in @BuildConfig.groovy@ are only available from [command scripts|guide:creatingGantScripts] and can be accessed via the @grailsSettings.config@ property like so: - -{code} -target(default: "Example command") { - def maxIterations = grailsSettings.config.myapp.iterations.max - ... -} -{code} - -If you want to read runtime configuration settings, i.e. those defined in @Config.groovy@, use the [@grailsApplication@|api:org.codehaus.groovy.grails.commons.GrailsApplication] object, which is available as a variable in controllers and tag libraries: +If you want to read runtime configuration settings, i.e. those defined in @application.yml@, use the [@grailsApplication@|api:grails.core.GrailsApplication] object, which is available as a variable in controllers and tag libraries: {code} class MyController { def hello() { - def recipient = grailsApplication.config.foo.bar.hello + def recipient = grailsApplication.config.getProperty('foo.bar.hello') render "Hello ${recipient}" } } {code} +The @config@ property of the @grailsApplication@ object is an instance of the [Config|api:grails.config.Config] interface and provides a number of useful methods to read the configuration of the application. + +Notice that the @Config@ instance is a merged configuration based on Spring's [PropertySource|api:org.springframework.context.annotation.PropertySource] concept and reads configuration from the environment, system properties and the local application configuration merging them into a single object. + + and can be easily injected into services and other Grails artifacts: {code} +import grails.core.* + class MyService { - def grailsApplication + GrailsApplication grailsApplication String greeting() { - def recipient = grailsApplication.config.foo.bar.hello + def recipient = grailsApplication.config.getProperty('foo.bar.hello') return "Hello ${recipient}" } } {code} +Finally, you can also use Spring's [Value|api:org.springframework.beans.factory.annotation.Value] annotation to dependency injection configuration values: + +{code} +import org.springframework.beans.factory.annotation.* + +class MyController { + @Value('${foo.bar.hello}') + String recipient + + def hello() { + render "Hello ${recipient}" + } +} +{code} + +{note} +In Groovy code you must use single quotes around the string for the value of the @Value@ annotation otherwise it is interpreted as a GString not a Spring expression. +{note} + As you can see, when accessing configuration settings you use the same dot notation as when you define them. diff --git a/src/en/guide/conf/config/builtInOptions.gdoc b/src/en/guide/conf/config/builtInOptions.gdoc index e0d7be70833..825f426c5f4 100644 --- a/src/en/guide/conf/config/builtInOptions.gdoc +++ b/src/en/guide/conf/config/builtInOptions.gdoc @@ -1,27 +1,10 @@ Grails has a set of core settings that are worth knowing about. Their defaults are suitable for most projects, but it's important to understand what they do because you may need one or more of them later. -h3. Build settings - -Let's start with some important build settings. Although Grails requires JDK 6 when developing your applications, it is possible to deploy those applications to JDK 5 containers. Simply set the following in @BuildConfig.groovy@: - -{code} -grails.project.source.level = "1.5" -grails.project.target.level = "1.5" -{code} - -Note that source and target levels are different to the standard public version of JDKs, so JDK 5 -> 1.5, JDK 6 -> 1.6, and JDK 7 -> 1.7. - -In addition, Grails supports Servlet versions 2.5 and above but defaults to 2.5. If you wish to use newer features of the Servlet API (such as 3.0 async support) you should configure the @grails.servlet.version@ setting appropriately: - -{code} -grails.servlet.version = "3.0" -{code} h3. Runtime settings -On the runtime front, i.e. @Config.groovy@, there are quite a few more core settings: +On the runtime front, i.e. @grails-app/conf/application.yml@, there are quite a few more core settings: -* @grails.config.locations@ - The location of properties files or addition Grails Config files that should be merged with main configuration. See the [section on externalised config|guide:configExternalized]. * @grails.enable.native2ascii@ - Set this to false if you do not require native2ascii conversion of Grails i18n properties files (default: true). * @grails.views.default.codec@ - Sets the default encoding regime for GSPs - can be one of 'none', 'html', or 'base64' (default: 'none'). To reduce risk of XSS attacks, set this to 'html'. * @grails.views.gsp.encoding@ - The file encoding used for GSP source files (default: 'utf-8'). @@ -31,11 +14,3 @@ On the runtime front, i.e. @Config.groovy@, there are quite a few more core sett * @grails.views.gsp.sitemesh.preprocess@ - Determines whether SiteMesh preprocessing happens. Disabling this slows down page rendering, but if you need SiteMesh to parse the generated HTML from a GSP view then disabling it is the right option. Don't worry if you don't understand this advanced property: leave it set to true. * @grails.reload.excludes@ and @grails.reload.includes@ - Configuring these directives determines the reload behavior for project specific source files. Each directive takes a list of strings that are the class names for project source files that should be excluded from reloading behavior or included accordingly when running the application in development with the @run-app@ command. If the @grails.reload.includes@ directive is configured, then only the classes in that list will be reloaded. -h3. War generation - -* @grails.project.war.file@ - Sets the name and location of the WAR file generated by the [war|commandLine] command -* @grails.war.dependencies@ - A closure containing Ant builder syntax or a list of JAR filenames. Lets you customise what libraries are included in the WAR file. -* @grails.war.copyToWebApp@ - A closure containing Ant builder syntax that is legal inside an Ant copy, for example "fileset()". Lets you control what gets included in the WAR file from the "web-app" directory. -* @grails.war.resources@ - A closure containing Ant builder syntax. Allows the application to do any other work before building the final WAR file - -For more information on using these options, see the section on [deployment|guide:deployment] diff --git a/src/en/guide/conf/config/configGORM.gdoc b/src/en/guide/conf/config/configGORM.gdoc index 274acc8e792..de4b161036c 100644 --- a/src/en/guide/conf/config/configGORM.gdoc +++ b/src/en/guide/conf/config/configGORM.gdoc @@ -4,12 +4,19 @@ Grails provides the following GORM configuration options: For example, to enable failOnError for all domain classes: {code:java} -grails.gorm.failOnError=true +grails: + gorm: + failOnError: true {code} and to enable failOnError for domain classes by package: + {code:java} -grails.gorm.failOnError = ['com.companyname.somepackage', - 'com.companyname.someotherpackage'] +grails: + gorm: + failOnError: + - com.companyname.somepackage + - com.companyname.someotherpackage {code} + * @grails.gorm.autoFlush@ = If set to @true@, causes the [merge|domainClasses], [save|domainClasses] and [delete|domainClasses] methods to flush the session, replacing the need to explicitly flush using @save(flush: true)@. diff --git a/src/en/guide/conf/config/logging.gdoc b/src/en/guide/conf/config/logging.gdoc index 4514b555a50..78fb966f26a 100644 --- a/src/en/guide/conf/config/logging.gdoc +++ b/src/en/guide/conf/config/logging.gdoc @@ -1,476 +1,7 @@ -h3. The Basics +By default logging in Grails 3.0 is handled by the [Logback logging framework|http://logback.qos.ch] and can be configured with the @grails-app/conf/logback.groovy@ file. -Grails uses its common configuration mechanism to provide the settings for the underlying "Log4j":http://logging.apache.org/log4j/1.2/index.html log system, so all you have to do is add a @log4j@ setting to the file @grails-app/conf/Config.groovy@. +{note} +If you prefer XML you can replace the @logback.groovy@ file with a @logback.xml@ file instead. +{note} -So what does this @log4j@ setting look like? Here's a basic example: - -{code:java} -log4j = { - error 'org.codehaus.groovy.grails.web.servlet', // controllers - 'org.codehaus.groovy.grails.web.pages' // GSP - - warn 'org.apache.catalina' -} -{code} - -This says that for loggers whose name starts with 'org.codehaus.groovy.grails.web.servlet' or 'org.codehaus.groovy.grails.web.pages', only messages logged at 'error' level and above will be shown. Loggers with names starting with 'org.apache.catalina' logger only show messages at the 'warn' level and above. What does that mean? First of all, you have to understand how levels work. - -h4. Logging levels - -There are several standard logging levels, which are listed here in order of descending priority: - -# off -# fatal -# error -# warn -# info -# debug -# trace -# all - -When you log a message, you implicitly give that message a level. For example, the method @log.error(msg)@ will log a message at the 'error' level. Likewise, @log.debug(msg)@ will log it at 'debug'. Each of the above levels apart from 'off' and 'all' have a corresponding log method of the same name. - -The logging system uses that _message_ level combined with the configuration for the logger (see next section) to determine whether the message gets written out. For example, if you have an 'org.example.domain' logger configured like so: - -{code:java} -warn 'org.example.domain' -{code} - -then messages with a level of 'warn', 'error', or 'fatal' will be written out. Messages at other levels will be ignored. - -Before we go on to loggers, a quick note about those 'off' and 'all' levels. These are special in that they can only be used in the configuration; you can't log messages at these levels. So if you configure a logger with a level of 'off', then no messages will be written out. A level of 'all' means that you will see all messages. Simple. - -h4. Loggers - -Loggers are fundamental to the logging system, but they are a source of some confusion. For a start, what are they? Are they shared? How do you configure them? - -A logger is the object you log messages to, so in the call @log.debug(msg)@, @log@ is a logger instance (of type [Log|http://commons.apache.org/logging/apidocs/org/apache/commons/logging/Log.html]). These loggers are cached and uniquely identified by name, so if two separate classes use loggers with the same name, those loggers are actually the same instance. - -There are two main ways to get hold of a logger: - -# use the @log@ instance injected into artifacts such as domain classes, controllers and services; -# use the Commons Logging API directly. - -If you use the dynamic @log@ property, then the name of the logger is 'grails.app..', where @type@ is the type of the artifact, for example 'controllers' or 'services', and @className@ is the fully qualified name of the artifact. For example, if you have this service: - -{code:java} -package org.example - -class MyService { - ... -} -{code} - -then the name of the logger will be 'grails.app.services.org.example.MyService'. - -For other classes, the typical approach is to store a logger based on the class name in a constant static field: - -{code:java} -package org.other - -import org.apache.commons.logging.LogFactory - -class MyClass { - private static final log = LogFactory.getLog(this) - ... -} -{code} - -This will create a logger with the name 'org.other.MyClass' - note the lack of a 'grails.app.' prefix since the class isn't an artifact. You can also pass a name to the @getLog()@ method, such as "myLogger", but this is less common because the logging system treats names with dots ('.') in a special way. - -h4. Configuring loggers - -You have already seen how to configure loggers in Grails: - -{code:java} -log4j = { - error 'org.codehaus.groovy.grails.web.servlet' -} -{code} - -This example configures loggers with names starting with 'org.codehaus.groovy.grails.web.servlet' to ignore any messages sent to them at a level of 'warn' or lower. But is there a logger with this name in the application? No. So why have a configuration for it? Because the above rule applies to any logger whose name _begins with_ 'org.codehaus.groovy.grails.web.servlet.' as well. For example, the rule applies to both the @org.codehaus.groovy.grails.web.servlet.GrailsDispatcherServlet@ class and the @org.codehaus.groovy.grails.web.servlet.mvc.GrailsWebRequest@ one. - -In other words, loggers are hierarchical. This makes configuring them by package much simpler than it would otherwise be. - -The most common things that you will want to capture log output from are your controllers, services, and other artifacts. Use the convention mentioned earlier to do that: _grails.app.._. In particular the class name must be fully qualified, i.e. with the package if there is one: - -{code:java} -log4j = { - // Set level for all application artifacts - info "grails.app" - - // Set for a specific controller in the default package - debug "grails.app.controllers.YourController" - - // Set for a specific domain class - debug "grails.app.domain.org.example.Book" - - // Set for all taglibs - info "grails.app.taglib" -} -{code} - -The standard artifact names used in the logging configuration are: - -* @conf@ - For anything under @grails-app/conf@ such as @BootStrap.groovy@ (but excluding filters) -* @filters@ - For filters -* @taglib@ - For tag libraries -* @services@ - For service classes -* @controllers@ - For controllers -* @domain@ - For domain entities - -Grails itself generates plenty of logging information and it can sometimes be helpful to see that. Here are some useful loggers from Grails internals that you can use, especially when tracking down problems with your application: - -* @org.codehaus.groovy.grails.commons@ - Core artifact information such as class loading etc. -* @org.codehaus.groovy.grails.web@ - Grails web request processing -* @org.codehaus.groovy.grails.web.mapping@ - URL mapping debugging -* @org.codehaus.groovy.grails.plugins@ - Log plugin activity -* @grails.spring@ - See what Spring beans Grails and plugins are defining -* @org.springframework@ - See what Spring is doing -* @org.hibernate@ - See what Hibernate is doing - -So far, we've only looked at explicit configuration of loggers. But what about all those loggers that _don't_ have an explicit configuration? Are they simply ignored? The answer lies with the root logger. - -h4. The Root Logger - -All logger objects inherit their configuration from the root logger, so if no explicit configuration is provided for a given logger, then any messages that go to that logger are subject to the rules defined for the root logger. In other words, the root logger provides the default configuration for the logging system. - -Grails automatically configures the root logger to only handle messages at 'error' level and above, and all the messages are directed to the console (stdout for those with a C background). You can customise this behaviour by specifying a 'root' section in your logging configuration like so: - -{code:java} -log4j = { - root { - info() - } - ... -} -{code} - -The above example configures the root logger to log messages at 'info' level and above to the default console appender. You can also configure the root logger to log to one or more named appenders (which we'll talk more about shortly): - -{code:java} -log4j = { - appenders { - file name:'file', file:'/var/logs/mylog.log' - } - root { - debug 'stdout', 'file' - } -} -{code} - -In the above example, the root logger will log to two appenders - the default 'stdout' (console) appender and a custom 'file' appender. - -For power users there is an alternative syntax for configuring the root logger: the root @org.apache.log4j.Logger@ instance is passed as an argument to the log4j closure. This lets you work with the logger directly: - -{code:java} -log4j = { root -> - root.level = org.apache.log4j.Level.DEBUG - ... -} -{code} - -For more information on what you can do with this @Logger@ instance, refer to the Log4j API documentation. - -Those are the basics of logging pretty well covered and they are sufficient if you're happy to only send log messages to the console. But what if you want to send them to a file? How do you make sure that messages from a particular logger go to a file but not the console? These questions and more will be answered as we look into appenders. - -h3. Appenders - -Loggers are a useful mechanism for filtering messages, but they don't physically write the messages anywhere. That's the job of the appender, of which there are various types. For example, there is the default one that writes messages to the console, another that writes them to a file, and several others. You can even create your own appender implementations\! - -This diagram shows how they fit into the logging pipeline: - -!logging.png! - -As you can see, a single logger may have several appenders attached to it. In a standard Grails configuration, the console appender named 'stdout' is attached to all loggers through the default root logger configuration. But that's the only one. Adding more appenders can be done within an 'appenders' block: - -{code:java} -log4j = { - appenders { - rollingFile name: "myAppender", - maxFileSize: 1024, - file: "/tmp/logs/myApp.log" - } -} -{code} - -The following appenders are available by default: - -{table} - *Name* | *Class* | *Description* - jdbc | [JDBCAppender|http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/jdbc/JDBCAppender.html] | Logs to a JDBC connection. - console | [ConsoleAppender|http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/ConsoleAppender.html] | Logs to the console. - file | [FileAppender|http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/FileAppender.html] | Logs to a single file. - rollingFile | [RollingFileAppender|http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/RollingFileAppender.html] | Logs to rolling files, for example a new file each day. -{table} - -Each named argument passed to an appender maps to a property of the underlying [Appender|http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/Appender.html] implementation. So the previous example sets the @name@, @maxFileSize@ and @file@ properties of the @RollingFileAppender@ instance. - -You can have as many appenders as you like - just make sure that they all have unique names. You can even have multiple instances of the same appender type, for example several file appenders that log to different files. - -If you prefer to create the appender programmatically or if you want to use an appender implementation that's not available in the above syntax, simply declare an @appender@ entry with an instance of the appender you want: - -{code:java} -import org.apache.log4j.* - -log4j = { - appenders { - appender new RollingFileAppender( - name: "myAppender", - maxFileSize: 1024, - file: "/tmp/logs/myApp.log") - } -} -{code} - -This approach can be used to configure @JMSAppender@, @SocketAppender@, @SMTPAppender@, and more. - -Once you have declared your extra appenders, you can attach them to specific loggers by passing the name as a key to one of the log level methods from the previous section: - -{code:java} -error myAppender: "grails.app.controllers.BookController" -{code} - -This will ensure that the 'grails.app.controllers.BookController' logger sends log messages to 'myAppender' as well as any appenders configured for the root logger. To add more than one appender to the logger, then add them to the same level declaration: - -{code:java} -error myAppender: "grails.app.controllers.BookController", - myFileAppender: ["grails.app.controllers.BookController", - "grails.app.services.BookService"], - rollingFile: "grails.app.controllers.BookController" -{code} - -The above example also shows how you can configure more than one logger at a time for a given appender (@myFileAppender@) by using a list. - -Be aware that you can only configure a single level for a logger, so if you tried this code: - -{code:java} -error myAppender: "grails.app.controllers.BookController" -debug myFileAppender: "grails.app.controllers.BookController" -fatal rollingFile: "grails.app.controllers.BookController" -{code} - -you'd find that only 'fatal' level messages get logged for 'grails.app.controllers.BookController'. That's because the last level declared for a given logger wins. What you probably want to do is limit what level of messages an appender writes. - -An appender that is attached to a logger configured with the 'all' level will generate a lot of logging information. That may be fine in a file, but it makes working at the console difficult. So we configure the console appender to only write out messages at 'info' level or above: - -{code:java} -log4j = { - appenders { - console name: "stdout", threshold: org.apache.log4j.Level.INFO - } -} -{code} - -The key here is the @threshold@ argument which determines the cut-off for log messages. This argument is available for all appenders, but do note that you currently have to specify a @Level@ instance - a string such as "info" will not work. - -h3. Custom Layouts - -By default the Log4j DSL assumes that you want to use a [PatternLayout|http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/PatternLayout.html]. However, there are other layouts available including: - -* @xml@ - Create an XML log file -* @html@ - Creates an HTML log file -* @simple@ - A simple textual log -* @pattern@ - A Pattern layout - -You can specify custom patterns to an appender using the @layout@ setting: - -{code:java} -log4j = { - appenders { - console name: "customAppender", - layout: pattern(conversionPattern: "%c{2} %m%n") - } -} -{code} - -This also works for the built-in appender "stdout", which logs to the console: -{code:java} -log4j = { - appenders { - console name: "stdout", - layout: pattern(conversionPattern: "%c{2} %m%n") - } -} -{code} - -h3. Environment-specific configuration - -Since the logging configuration is inside @Config.groovy@, you can put it inside an environment-specific block. However, there is a problem with this approach: you have to provide the full logging configuration each time you define the @log4j@ setting. In other words, you cannot selectively override parts of the configuration - it's all or nothing. - -To get around this, the logging DSL provides its own environment blocks that you can put anywhere in the configuration: - -{code:java} -log4j = { - appenders { - console name: "stdout", - layout: pattern(conversionPattern: "%c{2} %m%n") - - environments { - production { - rollingFile name: "myAppender", maxFileSize: 1024, - file: "/tmp/logs/myApp.log" - } - } - } - - root { - //... - } - - // other shared config - info "grails.app.controller" - - environments { - production { - // Override previous setting for 'grails.app.controller' - error "grails.app.controllers" - } - } -} -{code} - -The one place you can't put an environment block is _inside_ the @root@ definition, but you can put the @root@ definition inside an environment block. - -h3. Full stacktraces - -When exceptions occur, there can be an awful lot of noise in the stacktrace from Java and Groovy internals. Grails filters these typically irrelevant details and restricts traces to non-core Grails/Groovy class packages. - -When this happens, the full trace is always logged to the @StackTrace@ logger, which by default writes its output to a file called @stacktrace.log@. As with other loggers though, you can change its behaviour in the configuration. For example if you prefer full stack traces to go to the console, add this entry: - -{code:java} -error stdout: "StackTrace" -{code} - -This won't stop Grails from attempting to create the stacktrace.log file - it just redirects where stack traces are written to. An alternative approach is to change the location of the 'stacktrace' appender's file: - -{code:java} -log4j = { - appenders { - rollingFile name: "stacktrace", maxFileSize: 1024, - file: "/var/tmp/logs/myApp-stacktrace.log" - } -} -{code} - -or, if you don't want to the 'stacktrace' appender at all, configure it as a 'null' appender: - -{code:java} -log4j = { - appenders { - 'null' name: "stacktrace" - } -} -{code} - -You can of course combine this with attaching the 'stdout' appender to the 'StackTrace' logger if you want all the output in the console. - -Finally, you can completely disable stacktrace filtering by setting the @grails.full.stacktrace@ VM property to @true@: - -{code:java} -grails -Dgrails.full.stacktrace=true run-app -{code} - -h3. Masking Request Parameters From Stacktrace Logs - -When Grails logs a stacktrace, the log message may include the names and values of all of the request parameters for the current request. To mask out the values of secure request parameters, specify the parameter names in the @grails.exceptionresolver.params.exclude@ config property: - -{code:java} -grails.exceptionresolver.params.exclude = ['password', 'creditCard'] -{code} - -Request parameter logging may be turned off altogether by setting the @grails.exceptionresolver.logRequestParameters@ config property to @false@. The default value is @true@ when the application is running in DEVELOPMENT mode and @false@ for all other modes. - -{code:java} -grails.exceptionresolver.logRequestParameters=false -{code} - -h3. Logger inheritance - -Earlier, we mentioned that all loggers inherit from the root logger and that loggers are hierarchical based on '.'-separated terms. What this means is that unless you override a parent setting, a logger retains the level and the appenders configured for that parent. So with this configuration: - -{code:java} -log4j = { - appenders { - file name:'file', file:'/var/logs/mylog.log' - } - root { - debug 'stdout', 'file' - } -} -{code} - -all loggers in the application will have a level of 'debug' and will log to both the 'stdout' and 'file' appenders. What if you only want to log to 'stdout' for a particular logger? Change the 'additivity' for a logger in that case. - -Additivity simply determines whether a logger inherits the configuration from its parent. If additivity is false, then its not inherited. The default for all loggers is true, i.e. they inherit the configuration. So how do you change this setting? Here's an example: - -{code:java} -log4j = { - appenders { - ... - } - root { - ... - } - - info additivity: false, - stdout: \["grails.app.controllers.BookController", - "grails.app.services.BookService"\] -} -{code} - -So when you specify a log level, add an 'additivity' named argument. Note that you when you specify the additivity, you must configure the loggers for a named appender. The following syntax will _not_ work: - -{code:java} -info additivity: false, \["grails.app.controllers.BookController", - "grails.app.services.BookService"\] -{code} - -h3. Customizing stack trace printing and filtering - -Stacktraces in general and those generated when using Groovy in particular are quite verbose and contain many stack frames that aren't interesting when diagnosing problems. So Grails uses a implementation of the @org.codehaus.groovy.grails.exceptions.StackTraceFilterer@ interface to filter out irrelevant stack frames. To customize the approach used for filtering, implement that interface in a class in src/groovy or src/java and register it in @Config.groovy@: - -{code} -grails.logging.stackTraceFiltererClass = - 'com.yourcompany.yourapp.MyStackTraceFilterer' -{code} - -In addition, Grails customizes the display of the filtered stacktrace to make the information more readable. To customize this, implement the @org.codehaus.groovy.grails.exceptions.StackTracePrinter@ interface in a class in src/groovy or src/java and register it in @Config.groovy@: - -{code} -grails.logging.stackTracePrinterClass = - 'com.yourcompany.yourapp.MyStackTracePrinter' -{code} - -Finally, to render error information in the error GSP, an HTML-generating printer implementation is needed. The default implementation is @org.codehaus.groovy.grails.web.errors.ErrorsViewStackTracePrinter@ and it's registered as a Spring bean. To use your own implementation, either implement the @org.codehaus.groovy.grails.exceptions.StackTraceFilterer@ directly or subclass @ErrorsViewStackTracePrinter@ and register it in @grails-app/conf/spring/resources.groovy@ as: - -{code} -import com.yourcompany.yourapp.MyErrorsViewStackTracePrinter - -beans = { - - errorsViewStackTracePrinter(MyErrorsViewStackTracePrinter, - ref('grailsResourceLocator')) -} -{code} - -h3. Alternative logging libraries - -By default, Grails uses Log4J to do its logging. For most people this is absolutely fine, and many users don't even care what logging library is used. But if you're not one of those and want to use an alternative, such as the [JDK logging package|http://download.oracle.com/javase/6/docs/api/index.html?java/util/logging/package-summary.html] or [logback|http://logback.qos.ch/], you can do so by simply excluding a couple of dependencies from the global set and adding your own: - -{code} -grails.project.dependency.resolution = { - inherits("global") { - excludes "grails-plugin-logging", "log4j" - } - ... - dependencies { - runtime "ch.qos.logback:logback-core:0.9.29" - ... - } - ... -} - -{code} - -If you do this, you will get unfiltered, standard Java stacktraces in your log files and you won't be able to use the logging configuration DSL that's just been described. Instead, you will have to use the standard configuration mechanism for the library you choose. +For more information on configuring logging refer to the [Logback documentation|http://logback.qos.ch/manual/groovy.html] on the subject. \ No newline at end of file diff --git a/src/en/guide/conf/configExternalized.gdoc b/src/en/guide/conf/configExternalized.gdoc deleted file mode 100644 index 25172ee230f..00000000000 --- a/src/en/guide/conf/configExternalized.gdoc +++ /dev/null @@ -1,33 +0,0 @@ -Some deployments require that configuration be sourced from more than one place and be changeable without requiring a rebuild of the application. In order to support deployment scenarios such as these the configuration can be externalized. To do so, point Grails at the locations of the configuration files that should be used by adding a @grails.config.locations@ setting in @Config.groovy@, for example: - -{code:java} -grails.config.locations = [ - "classpath:${appName}-config.properties", - "classpath:${appName}-config.groovy", - "file:${userHome}/.grails/${appName}-config.properties", - "file:${userHome}/.grails/${appName}-config.groovy" ] -{code} - -In the above example we're loading configuration files (both Java Properties files and "ConfigSlurper":http://groovy.codehaus.org/ConfigSlurper configurations) from different places on the classpath and files located in @USER_HOME@. - -It is also possible to load config by specifying a class that is a config script. - -{code:java} -grails.config.locations = [com.my.app.MyConfig] -{code} - -This can be useful in situations where the config is either coming from a plugin or some other part of your application. A typical use for this is re-using configuration provided by plugins across multiple applications. - -Ultimately all configuration files get merged into the @config@ property of the [GrailsApplication|api:org.codehaus.groovy.grails.commons.GrailsApplication] object and are hence obtainable from there. - -Values that have the same name as previously defined values will overwrite the existing values, and the pointed to configuration sources are loaded in the order in which they are defined. - -h4. Config Defaults - -The configuration values contained in the locations described by the @grails.config.locations@ property will *override* any values defined in your application @Config.groovy@ file which may not be what you want. You may want to have a set of _default_ values be be loaded that can be overridden in either your application's @Config.groovy@ file or in a named config location. For this you can use the @grails.config.defaults.locations@ property. - -This property supports the same values as the @grails.config.locations@ property (i.e. paths to config scripts, property files or classes), but the config described by @grails.config.defaults.locations@ will be loaded _before_ all other values and can therefore be overridden. Some plugins use this mechanism to supply one or more sets of default configuration that you can choose to include in your application config. - -{note} -Grails also supports the concept of property place holders and property override configurers as defined in "Spring":http://www.springframework.org. For more information on these see the section on [Grails and Spring|guide:spring] -{note} diff --git a/src/en/guide/conf/dataSource/JNDIDataSources.gdoc b/src/en/guide/conf/dataSource/JNDIDataSources.gdoc deleted file mode 100644 index 47df03f5338..00000000000 --- a/src/en/guide/conf/dataSource/JNDIDataSources.gdoc +++ /dev/null @@ -1,42 +0,0 @@ -h4. Referring to a JNDI DataSource - -Most Java EE containers supply @DataSource@ instances via "Java Naming and Directory Interface":http://www.oracle.com/technetwork/java/jndi/index.html (JNDI). Grails supports the definition of JNDI data sources as follows: - -{code:java} -dataSource { - jndiName = "java:comp/env/myDataSource" -} -{code} - -The format on the JNDI name may vary from container to container, but the way you define the @DataSource@ in Grails remains the same. - -h4. Configuring a Development time JNDI resource - -The way in which you configure JNDI data sources at development time is plugin dependent. Using the "Tomcat":http://grails.org/plugin/tomcat plugin you can define JNDI resources using the @grails.naming.entries@ setting in @grails-app/conf/Config.groovy@: - -{code} -grails.naming.entries = [ - "bean/MyBeanFactory": [ - auth: "Container", - type: "com.mycompany.MyBean", - factory: "org.apache.naming.factory.BeanFactory", - bar: "23" - ], - "jdbc/EmployeeDB": [ - type: "javax.sql.DataSource", //required - auth: "Container", // optional - description: "Data source for Foo", //optional - driverClassName: "org.h2.Driver", - url: "jdbc:h2:mem:database", - username: "dbusername", - password: "dbpassword", - maxActive: "8", - maxIdle: "4" - ], - "mail/session": [ - type: "javax.mail.Session, - auth: "Container", - "mail.smtp.host": "localhost" - ] -] -{code} diff --git a/src/en/guide/conf/dataSource/automaticDatabaseMigration.gdoc b/src/en/guide/conf/dataSource/automaticDatabaseMigration.gdoc index c6907020386..4a4c8fb3ffc 100644 --- a/src/en/guide/conf/dataSource/automaticDatabaseMigration.gdoc +++ b/src/en/guide/conf/dataSource/automaticDatabaseMigration.gdoc @@ -10,15 +10,4 @@ In [development|guide:environments] mode @dbCreate@ is by default set to "create It's tempting to switch to @update@ so you retain existing data and only update the schema when your code changes, but Hibernate's update support is very conservative. It won't make any changes that could result in data loss, and doesn't detect renamed columns or tables, so you'll be left with the old one and will also have the new one. -Grails supports migrations via the "Database Migration":http://grails.org/plugin/database-migration plugin which can be installed by declaring the plugin in @grails-app/conf/BuildConfig.groovy@: - -{code:java} -grails.project.dependency.resolution = { - ... - plugins { - runtime ':database-migration:1.3.1' - } -} -{code} - -The plugin uses "Liquibase":http://www.liquibase.org/ and provides access to all of its functionality, and also has support for GORM (for example generating a change set by comparing your domain classes to a database). +Grails supports migrations with Flyway or Liquibase using the [same mechanism provided by Spring Boot|http://docs.spring.io/spring-boot/docs/current/reference/html/howto-database-initialization.html]. diff --git a/src/en/guide/conf/dataSource/multipleDatasources.gdoc b/src/en/guide/conf/dataSource/multipleDatasources.gdoc index 07f140b2ef9..b689073b0d3 100644 --- a/src/en/guide/conf/dataSource/multipleDatasources.gdoc +++ b/src/en/guide/conf/dataSource/multipleDatasources.gdoc @@ -5,79 +5,75 @@ h4. Configuring Additional DataSources The default @DataSource@ configuration in @grails-app/conf/DataSource.groovy@ looks something like this: {code} -dataSource { - pooled = true - driverClassName = "org.h2.Driver" - username = "sa" - password = "" -} -hibernate { - cache.use_second_level_cache = true - cache.use_query_cache = true - cache.provider_class = 'net.sf.ehcache.hibernate.EhCacheProvider' -} - -environments { - development { - dataSource { - dbCreate = "create-drop" - url = "jdbc:h2:mem:devDb" - } - } - test { - dataSource { - dbCreate = "update" - url = "jdbc:h2:mem:testDb" - } - } - production { - dataSource { - dbCreate = "update" - url = "jdbc:h2:prodDb" - } - } -} -{code} - -This configures a single @DataSource@ with the Spring bean named @dataSource@. To configure extra @DataSource@s, add another @dataSource@ block (at the top level, in an environment block, or both, just like the standard @DataSource@ definition) with a custom name, separated by an underscore. For example, this configuration adds a second @DataSource@, using MySQL in the development environment and Oracle in production: - -{code} -environments { - development { - dataSource { - dbCreate = "create-drop" - url = "jdbc:h2:mem:devDb" - } - dataSource_lookup { - dialect = org.hibernate.dialect.MySQLInnoDBDialect - driverClassName = 'com.mysql.jdbc.Driver' - username = 'lookup' - password = 'secret' - url = 'jdbc:mysql://localhost/lookup' - dbCreate = 'update' - } - } - test { - dataSource { - dbCreate = "update" - url = "jdbc:h2:mem:testDb" - } - } - production { - dataSource { - dbCreate = "update" - url = "jdbc:h2:prodDb" - } - dataSource_lookup { - dialect = org.hibernate.dialect.Oracle10gDialect - driverClassName = 'oracle.jdbc.driver.OracleDriver' - username = 'lookup' - password = 'secret' - url = 'jdbc:oracle:thin:@localhost:1521:lookup' - dbCreate = 'update' - } - } -} +--- +dataSource: + pooled: true + jmxExport: true + driverClassName: org.h2.Driver + username: sa + password: + +environments: + development: + dataSource: + dbCreate: create-drop + url: jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE + test: + dataSource: + dbCreate: update + url: jdbc:h2:mem:testDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE + production: + dataSource: + dbCreate: update + url: jdbc:h2:prodDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE + properties: + jmxEnabled: true + initialSize: 5 +{code} + +This configures a single @DataSource@ with the Spring bean named @dataSource@. To configure extra @DataSource@s, add a @dataSources@ block (at the top level, in an environment block, or both, just like the standard @DataSource@ definition) with a custom name, separated by an underscore. For example, this configuration adds a second @DataSource@, using MySQL in the development environment and Oracle in production: + +{code} +--- +dataSources: + dataSource: + pooled: true + jmxExport: true + driverClassName: org.h2.Driver + username: sa + password: + dataSource_lookup: + dialect: org.hibernate.dialect.MySQLInnoDBDialect + driverClassName: com.mysql.jdbc.Driver + username: lookup + password: secret + url: jdbc:mysql://localhost/lookup + dbCreate: update + +environments: + development: + dataSource: + dbCreate: create-drop + url: jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE + test: + dataSource: + dbCreate: update + url: jdbc:h2:mem:testDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE + production: + dataSource: + dbCreate: update + url: jdbc:h2:prodDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE + properties: + jmxEnabled: true + initialSize: 5 + ... + dataSource_lookup: + dialect: org.hibernate.dialect.Oracle10gDialect + driverClassName: oracle.jdbc.driver.OracleDriver + username: lookup + password: secret + url: jdbc:oracle:thin:@localhost:1521:lookup + dbCreate: update {code} You can use the same or different databases as long as they're supported by Hibernate. diff --git a/src/en/guide/conf/dependencyResolution.gdoc b/src/en/guide/conf/dependencyResolution.gdoc index eaf695d1d72..148a51bf380 100644 --- a/src/en/guide/conf/dependencyResolution.gdoc +++ b/src/en/guide/conf/dependencyResolution.gdoc @@ -1,85 +1 @@ -Grails features a dependency resolution DSL that lets you control how plugins and JAR dependencies are resolved. - -You can choose to use Aether (since Grails 2.3) or Apache Ivy as the dependency resolution engine. Aether is the dependency resolution library used by the Maven build tool, so if you are looking for Maven-like behavior then Aether is the better choice. Ivy allows more flexibility if you wish to resolve jars from flat file systems or none HTTP repositories. Aether is the default dependency resolution engine for Grails applications since Grails 2.3. - -{warning} -As of Grails 2.4 the Ivy resolver is considered deprecated and no longer maintained. It is recommended all users switch to using Aether. -{warning} - -To configure which dependency resolution engine to use you can specify the @grails.project.dependency.resolver@ setting in @grails-app/conf/BuildConfig.groovy@. The default setting is shown below: - -{code} -grails.project.dependency.resolver = "maven" // or ivy -{code} - -You can then specify a @grails.project.dependency.resolution@ property inside the @grails-app/conf/BuildConfig.groovy@ file that configures how dependencies are resolved: - -{code} -grails.project.dependency.resolution = { - // config here -} -{code} - -The default configuration looks like the following: - -{code} -grails.servlet.version = "3.0" // 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.work.dir = "target/work" -grails.project.target.level = 1.6 -grails.project.source.level = 1.6 -//grails.project.war.file = "target/\${appName}-\${appVersion}.war" - -grails.project.fork = [ - // configure settings for compilation JVM, note that if you alter the Groovy version forked compilation is required - // compile: [maxMemory: 256, minMemory: 64, debug: false, maxPerm: 256, daemon:true], - - // configure settings for the test-app JVM, uses the daemon by default - test: [maxMemory: 768, minMemory: 64, debug: false, maxPerm: 256, daemon:true], - // configure settings for the run-app JVM - run: [maxMemory: 768, minMemory: 64, debug: false, maxPerm: 256, forkReserve:false], - // configure settings for the run-war JVM - war: [maxMemory: 768, minMemory: 64, debug: false, maxPerm: 256, forkReserve:false], - // configure settings for the Console UI JVM - console: [maxMemory: 768, minMemory: 64, debug: false, maxPerm: 256] -] - -grails.project.dependency.resolver = "maven" // or ivy -grails.project.dependency.resolution = { - // inherit Grails' default dependencies - inherits("global") { - // specify dependency exclusions here; for example, uncomment this 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 - legacyResolve false // whether to do a secondary resolve on plugin installation, not advised and here for backwards compatibility - - repositories { - inherits true // Whether to inherit repository definitions from plugins - - grailsPlugins() - grailsHome() - mavenLocal() - grailsCentral() - mavenCentral() - // uncomment these (or add new ones) to enable remote dependency resolution from public Maven repositories - //mavenRepo "http://repository.codehaus.org" - //mavenRepo "http://download.java.net/maven/2/" - } - - dependencies { - // specify dependencies here under either 'build', 'compile', 'runtime', 'test' or 'provided' scopes e.g. - runtime 'mysql:mysql-connector-java:5.1.24' - compile 'org.springframework.integration:spring-integration-core:2.2.5.RELEASE' - } - - plugins { - // plugins for the build system only - } -} -{code} - -The details of the above will be explained in the next few sections. +Dependency resolution is handled by the [Gradle build tool|http://gradle.org], all dependencies are defined in the @build.gradle@ file. Refer to the [Gradle user guide|https://www.gradle.org/documentation] for more information. \ No newline at end of file diff --git a/src/en/guide/conf/dependencyResolution/changingDependencies.gdoc b/src/en/guide/conf/dependencyResolution/changingDependencies.gdoc deleted file mode 100644 index 14591aa6be6..00000000000 --- a/src/en/guide/conf/dependencyResolution/changingDependencies.gdoc +++ /dev/null @@ -1,101 +0,0 @@ -h4. Configuration Changing dependencies - -Typically, dependencies are constant. That is, for a given combination of @group@, @name@ and @version@ the jar (or plugin) that it refers to will never change. The Grails dependency management system uses this fact to cache dependencies in order to avoid having to download them from the source repository each time. Sometimes this is not desirable. For example, many developers use the convention of a _snapshot_ (i.e. a dependency with a version number ending in “-SNAPSHOT”) that can change from time to time while still retaining the same version number. We call this a "changing dependency". - -Whenever you have a changing dependency, Grails will always check the remote repository for a new version. More specifically, when a changing dependency is encountered during dependency resolution its last modified timestamp in the local cache is compared against the last modified timestamp in the dependency repositories. If the version on the remote server is deemed to be newer than the version in the local cache, the new version will be downloaded and used. - -{note} -Be sure to read the next section on "Dependency Resolution Caching" in addition to this one as it affects changing dependencies. -{note} - -All dependencies (jars and plugins) with a version number ending in @-SNAPSHOT@ are *implicitly* considered to be changing by Grails. You can also explicitly specify that a dependency is changing by setting the changing flag in the dependency DSL (This is only required for Ivy, Aether does not support the 'changing' flag and treats dependencies that end with -SNAPSHOT as changing): - -{code} -runtime ('org.my:lib:1.2.3') { - changing = true -} -{code} - -h4. Aether and SNAPSHOT dependencies - -The semantics for handling snapshots when using Aether in Grails are the same as those when using the Maven build tool. The default snapshot check policy is to check once a day for a new version of the dependency. This means that if a new snapshot is published during the day to a remote repository you may not see that change unless you manually clear out your local snapshot. - -If you wish to change the snapshot update policy you can do so by configuring an @updatePolicy@ for the repository where the snapshot was resolved from, for example: - -{code} -repositories { - mavenCentral { - updatePolicy "interval:1" - } -} -{code} - -The above example configures an update policy that checks once a minute for changes. Note that that an @updatePolicy@ like the above will seriously impact performance of dependency resolution. The possibly configuration values for @updatePolicy@ are as follows: - -* @never@ - Never check for new snapshots -* @always@ - Always check for new snapshots -* @daily@ - Check once a day for new snapshots (the default) -* @interval:x@ - Check once every x minutes for new snapshots - -h4. Ivy and Changing dependencies - -For those used to Maven snapshot handling, if you use Aether dependency management you can expect the same semantics as Maven. If you choose to use Ivy there is a caveat to the support for changing dependencies that you should be aware of. Ivy will stop looking for newer versions of a dependency once it finds a remote repository that has the dependency. - -Consider the following setup: - -{code} -grails.project.dependency.resolution = { - repositories { - mavenLocal() - mavenRepo "http://my.org/repo" - } - dependencies { - compile "myorg:mylib:1.0-SNAPSHOT" - } -{code} - -In this example we are using the local maven repository and a remote network maven repository. Assuming that the local OI dependency and the local Maven cache do not contain the dependency but the remote repository does, when we perform dependency resolution the following actions will occur: - -* maven local repository is searched, dependency not found -* maven network repository is searched, dependency is downloaded to the cache and used - -Note that the repositories are checked in the order they are defined in the @BuildConfig.groovy@ file. - -If we perform dependency resolution again without the dependency changing on the remote server, the following will happen: - -* maven local repository is searched, dependency not found -* maven network repository is searched, dependency is found to be the same "age" as the version in the cache so will not be updated (i.e. downloaded) - -Later on, a new version of @mylib 1.0-SNAPSHOT@ is published changing the version on the server. The next time we perform dependency resolution, the following will happen: - -* maven local repository is searched, dependency not found -* maven network repository is searched, dependency is found to newer than version in the cache so will be updated (i.e. downloaded to the cache) - -So far everything is working well. - -Now we want to test some local changes to the @mylib@ library. To do this we build it locally and install it to the local Maven cache (how doesn't particularly matter). The next time we perform a dependency resolution, the following will occur: - -* maven local repository is searched, dependency is found to newer than version in the cache so will be updated (i.e. downloaded to the cache) -* maven network repository is NOT searched as we've already found the dependency - -This is what we wanted to occur. - -Later on, a new version of @mylib 1.0-SNAPSHOT@ is published changing the version on the server. The next time we perform dependency resolution, the following will happen: - -* maven local repository is searched, dependency is found to be the same "age" as the version in the cache so will not be updated (i.e. downloaded) -* maven network repository is NOT searched as we've already found the dependency - -This is likely to not be the desired outcome. We are now out of sync with the latest published snapshot and will continue to keep using the version from the local maven repository. - -The rule to remember is this: when resolving a dependency, Ivy will stop searching as soon as it finds a repository that has the dependency at the specified version number. It will *not* continue searching all repositories trying to find a more recently modified instance. - -To remedy this situation (i.e. build against the _newer_ version of @mylib 1.0-SNAPSHOT@ in the remote repository), you can either: - -* Delete the version from the local maven repository, or -* Reorder the repositories in the @BuildConfig.groovy@ file - -Where possible, prefer deleting the version from the local maven repository. In general, when you have finished building against a locally built SNAPSHOT always try to clear it from the local maven repository. - -{note} -This changing dependency behaviour is an unmodifiable characteristic of the underlying dependency management system Apache Ivy. It is currently not possible to have Ivy search all repositories to look for newer versions (in terms of modification date) of the same dependency (i.e. the same combination of @group@, @name@ and @version@). If you want this behavior consider switching to Aether as the dependency manager. -{note} diff --git a/src/en/guide/conf/dependencyResolution/configurationsAndDependencies.gdoc b/src/en/guide/conf/dependencyResolution/configurationsAndDependencies.gdoc deleted file mode 100644 index ec4690a5616..00000000000 --- a/src/en/guide/conf/dependencyResolution/configurationsAndDependencies.gdoc +++ /dev/null @@ -1,134 +0,0 @@ -Grails features five dependency resolution configurations (or 'scopes'): - -* @build@: Dependencies for the build system only -* @compile@: Dependencies for the compile step -* @runtime@: Dependencies needed at runtime but not for compilation (see above) -* @test@: Dependencies needed for testing but not at runtime (see above) -* @provided@: Dependencies needed at development time, but not during WAR deployment -* @optional@ (Aether only): Dependencies considered optional and not required for the execution of the application or plugin - -Within the @dependencies@ block you can specify a dependency that falls into one of these configurations by calling the equivalent method. For example if your application requires the MySQL driver to function at @runtime@ you can specify that like this: - -{code} -runtime 'com.mysql:mysql-connector-java:5.1.16' -{code} - -This uses the string syntax: @group:name:version@. - - -If you are using Aether as the dependency resolution library, the Maven pattern of: - -{code} -:[:[:]]: -{code} - -You can also use a Map-based syntax: - -{code} -runtime group: 'com.mysql', - name: 'mysql-connector-java', - version: '5.1.16' -{code} - -Possible settings to the map syntax are: - -* @group@ - The group / organization (or groupId in Maven terminology) -* @name@ - The dependency name (or artifactId in Maven terminology) -* @version@ - The version of the dependency -* @extension@ (Aether only) - The file extension of the dependency -* @classifier@ - The dependency classifier -* @branch@ (Ivy only) - The branch of the dependency -* @transitive@ (Ivy only) - Whether the dependency has transitive dependencies - -As you can see from the list above some dependency configuration settings work only in Aether and some only in Ivy. - -Multiple dependencies can be specified by passing multiple arguments: - -{code} -runtime 'com.mysql:mysql-connector-java:5.1.16', - 'net.sf.ehcache:ehcache:1.6.1' - -// Or - -runtime( - [group:'com.mysql', name:'mysql-connector-java', version:'5.1.16'], - [group:'net.sf.ehcache', name:'ehcache', version:'1.6.1'] -) -{code} - -h3. Disabling transitive dependency resolution - -By default, Grails will not only get the JARs and plugins that you declare, but it will also get their transitive dependencies. This is usually what you want, but there are occasions where you want a dependency without all its baggage. In such cases, you can disable transitive dependency resolution on a case-by-case basis: - -{code} -runtime('com.mysql:mysql-connector-java:5.1.16', - 'net.sf.ehcache:ehcache:1.6.1') { - transitive = false -} - -// Or -runtime group:'com.mysql', - name:'mysql-connector-java', - version:'5.1.16', - transitive:false -{code} - -h3. Excluding specific transitive dependencies - -A far more common scenario is where you want the transitive dependencies, but some of them cause issues with your own dependencies or are unnecessary. For example, many Apache projects have 'commons-logging' as a transitive dependency, but it shouldn't be included in a Grails project (we use SLF4J). That's where the @excludes@ option comes in: - -{code} -runtime('com.mysql:mysql-connector-java:5.1.16', - 'net.sf.ehcache:ehcache:1.6.1') { - excludes "xml-apis", "commons-logging" -} - -// Or -runtime(group:'com.mysql', name:'mysql-connector-java', version:'5.1.16') { - excludes([ group: 'xml-apis', name: 'xml-apis'], - [ group: 'org.apache.httpcomponents' ], - [ name: 'commons-logging' ]) -{code} - -As you can see, you can either exclude dependencies by their artifact ID (also known as a module name) or any combination of group and artifact IDs (if you use the Map notation). You may also come across @exclude@ as well, but that can only accept a single string or Map: - -{code} -runtime('com.mysql:mysql-connector-java:5.1.16', - 'net.sf.ehcache:ehcache:1.6.1') { - exclude "xml-apis" -} -{code} - -h3. Dependency Management (Aether Only) - -If you are using Aether then you can take advantage of Maven's notion of [Dependency Management|http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Dependency_Management]. - -To do so you use a @management@ block, for example: - -{code} -management { - dependency "commons-logging:commons-logging:1.1.3" -} -{code} - -The above declaration will force all any transitive dependencies on @commons-logging@ to use the 1.1.3 version without you having to declare an explicit dependency on @commons-logging@ yourself. In addition to the version, you can also control the scope and exclusion rules of a dependency. - -h3. Where are the JARs? - -With all these declarative dependencies, you may wonder where all the JARs end up. They have to go somewhere after all. By default Grails puts them into a directory, called the dependency cache, that resides on your local file system at @user.home/.grails/ivy-cache@ or @user.home/.m2/repository@ when using Aether. You can change this either via the @settings.groovy@ file: - -{code} -grails.dependency.cache.dir = "${userHome}/.my-dependency-cache" -{code} - -or in the dependency DSL: - -{code} -grails.project.dependency.resolution = { - ... - cacheDir "target/ivy-cache" - ... -} -{code} - -The @settings.groovy@ option applies to all projects, so it's the preferred approach. diff --git a/src/en/guide/conf/dependencyResolution/debuggingResolution.gdoc b/src/en/guide/conf/dependencyResolution/debuggingResolution.gdoc deleted file mode 100644 index ee385b59dc0..00000000000 --- a/src/en/guide/conf/dependencyResolution/debuggingResolution.gdoc +++ /dev/null @@ -1,20 +0,0 @@ -If you are having trouble getting a dependency to resolve you can enable more verbose debugging from the underlying engine using the @log@ method: - -{code} -// log level of the Aether or Ivy resolver, either 'error', 'warn', -// 'info', 'debug' or 'verbose' -log "warn" -{code} - -A common issue is that the checksums for a dependency don't match the associated JAR file, and so Ivy rejects the dependency. This helps ensure that the dependencies are valid. But for a variety of reasons some dependencies simply don't have valid checksums in the repositories, even if they are valid JARs. To get round this, you can disable Ivy's dependency checks like so: - -{code} -grails.project.dependency.resolution = { - ... - log "warn" - checksums false - ... -} -{code} - -This is a global setting, so only use it if you have to. diff --git a/src/en/guide/conf/dependencyResolution/dependencyReports.gdoc b/src/en/guide/conf/dependencyResolution/dependencyReports.gdoc deleted file mode 100644 index a4fd5c9b469..00000000000 --- a/src/en/guide/conf/dependencyResolution/dependencyReports.gdoc +++ /dev/null @@ -1,33 +0,0 @@ -As mentioned in the previous section a Grails application consists of dependencies inherited from the framework, the plugins installed and the application dependencies itself. - -To obtain a report of an application's dependencies you can run the [dependency-report|commandLine] command: - -{code} -grails dependency-report -{code} - -By default this will generate reports in the @target/dependency-report@ directory. You can specify which configuration (scope) you want a report for by passing an argument containing the configuration name: - -{code} -grails dependency-report runtime -{code} - -As of Grails 2.3 the @dependency-report@ command will also output to the console a graph of the dependencies of an application. Example output it shown below: - -{code} -compile - Dependencies placed on the classpath for compilation (total: 73) -+--- org.codehaus.groovy:groovy-all:2.0.6 -+--- org.grails:grails-plugin-codecs:2.3.0 -| \--- org.grails:grails-web:2.3.0 -| \--- commons-fileupload:commons-fileupload:1.2.2 -| \--- xpp3:xpp3_min:1.1.4c -| \--- commons-el:commons-el:1.0 -| \--- opensymphony:sitemesh:2.4 -| \--- org.springframework:spring-webmvc:3.1.2.RELEASE -| \--- commons-codec:commons-codec:1.5 -| \--- org.slf4j:slf4j-api:1.7.2 -+--- org.grails:grails-plugin-controllers:2.3.0 -| \--- commons-beanutils:commons-beanutils:1.8.3 -| \--- org.grails:grails-core:2.3.0 -... -{code} \ No newline at end of file diff --git a/src/en/guide/conf/dependencyResolution/dependencyRepositories.gdoc b/src/en/guide/conf/dependencyResolution/dependencyRepositories.gdoc deleted file mode 100644 index f06c3d91681..00000000000 --- a/src/en/guide/conf/dependencyResolution/dependencyRepositories.gdoc +++ /dev/null @@ -1,109 +0,0 @@ -h4. Remote Repositories - -Initially your BuildConfig.groovy does not use any remote public Maven repositories. There is a default @grailsHome()@ repository that will locate the JAR files Grails needs from your Grails installation. To use a public repository, specify it in the @repositories@ block: - -{code} -repositories { - mavenCentral() -} -{code} - -In this case the default public Maven repository is specified. - -You can also specify a specific Maven repository to use by URL: - -{code} -repositories { - mavenRepo "http://repository.codehaus.org" -} -{code} - -and even give it a name: - -{code} -repositories { - mavenRepo name: "Codehaus", root: "http://repository.codehaus.org" -} -{code} - -so that you can easily identify it in logs. - -h4. Offline Mode - -There are times when it is not desirable to connect to any remote repositories (whilst working on the train for example!). In this case you can use the @offline@ flag to execute Grails commands and Grails will not connect to any remote repositories: - -{code} -grails --offline run-app -{code} - -{note} -Note that this command will fail if you do not have the necessary dependencies in your local Maven cache -{note} - -You can also globally configure offline mode by setting @grails.offline.mode@ to @true@ in @~/.grails/settings.groovy@ or in your project's @BuildConfig.groovy@ file: - -{code} -grails.offline.mode=true -{code} - -To specify your local Maven cache (@~/.m2/repository@) as a repository: - -{code} -repositories { - mavenLocal() -} -{code} - -h4. Authentication with Aether - -To authenticate with Aether you can either define the credentials on the repository definition: - -{code} -mavenRepo(url:"http://localhost:8082/myrepo") { - auth username: "foo", password: "bar" -} -{code} - -Or you can specify an @id@ on the repository: - -{code} -mavenRepo(id:'myrepo', url:"http://localhost:8082/myrepo") -{code} - -And then declare your credentials in @USER_HOME/.grails/settings.groovy@: - -{code} -grails.project.dependency.authentication = { - credentials { - id = "myrepo" - username = "admin" - password = "password" - } -} -{code} - -h4. Authentication with Ivy - -If your repository requires authentication you can configure this using a @credentials@ block: - -{code} -credentials { - realm = ".." - host = "localhost" - username = "myuser" - password = "mypass" -} -{code} - -This can be placed in your @USER_HOME/.grails/settings.groovy@ file using the @grails.project.ivy.authentication@ setting: - -{code} -grails.project.ivy.authentication = { - credentials { - realm = ".." - host = "localhost" - username = "myuser" - password = "mypass" - } -} -{code} diff --git a/src/en/guide/conf/dependencyResolution/dependencyResolutionCaching.gdoc b/src/en/guide/conf/dependencyResolution/dependencyResolutionCaching.gdoc deleted file mode 100644 index 66d903da62c..00000000000 --- a/src/en/guide/conf/dependencyResolution/dependencyResolutionCaching.gdoc +++ /dev/null @@ -1,27 +0,0 @@ -As a performance optimisation, when using Ivy (this does not apply to Aether), Grails does not resolve dependencies for every command invocation. Even with all the necessary dependencies downloaded and cached, resolution may take a second or two. To minimise this cost, Grails caches the result of dependency resolution (i.e. the location on the local file system of all of the declared dependencies, typically inside the dependency cache) and reuses this result for subsequent commands when it can reasonably expect that nothing has changed. - -Grails only performs dependency resolution under the following circumstances: - -* The project is clean (i.e. fresh checkout or after @grails clean@) -* The @BuildConfig.groovy@ file has changed since the last command was run -* The @\-\-refresh-dependencies@ command line switch is provided to the command (any command) -* The @refresh-dependencies@ command is the command being executed - -Generally, this strategy works well and you can ignore dependency resolution caching. Every time you change your dependencies (i.e. modify @BuildConfig.groovy@) Grails will do the right thing and resolve your new dependencies. - -However, when you have _changing_ or _dynamic_ dependencies you will have to consider dependency resolution caching. - -{info} -A _changing_ dependency is one whose version number does not change, but its contents do (like a SNAPSHOT). A _dynamic_ dependency is one that is defined as one of many possible options (like a dependency with a version range, or symbolic version number like @latest.integration@). -{info} - -Both _changing_ and _dynamic_ dependencies are influenced by the environment. With caching active, any changes to the environment are effectively ignored. For example, your project may not automatically fetch the very latest version of a dependency when using @latest.integration@. Or if you declare a @SNAPSHOT@ dependency, you may not automatically get the latest that's available on the server. - -To ensure you have the correct version of a _changing_ or _dynamic_ dependency in your project, you can: - -* clean the project -* run the @refresh-dependencies@ command -* run _any_ command with the @\-\-refresh-dependencies@ switch; or -* make a change to @BuildConfig.groovy@ - -If you have your CI builds configured to not perform clean builds, it may be worth adding the @\-\-refresh-dependencies@ switch to the command you use to build your projects. diff --git a/src/en/guide/conf/dependencyResolution/inheritedDependencies.gdoc b/src/en/guide/conf/dependencyResolution/inheritedDependencies.gdoc deleted file mode 100644 index 32bbc423c52..00000000000 --- a/src/en/guide/conf/dependencyResolution/inheritedDependencies.gdoc +++ /dev/null @@ -1,13 +0,0 @@ -By default every Grails application inherits several framework dependencies. This is done through the line: - -{code} -inherits "global" -{code} - -Inside the @BuildConfig.groovy@ file. To exclude specific inherited dependencies you use the @excludes@ method: - -{code} -inherits("global") { - excludes "oscache", "ehcache" -} -{code} diff --git a/src/en/guide/conf/dependencyResolution/mavenIntegration.gdoc b/src/en/guide/conf/dependencyResolution/mavenIntegration.gdoc deleted file mode 100644 index c2074fc3fed..00000000000 --- a/src/en/guide/conf/dependencyResolution/mavenIntegration.gdoc +++ /dev/null @@ -1,14 +0,0 @@ -When using the Grails Maven plugin with the Maven build tool, Grails' dependency resolution mechanics are disabled as it is assumed that you will manage dependencies with Maven's @pom.xml@ file. - -However, if you would like to continue using Grails regular commands like [run-app|commandLine], [test-app|commandLine] and so on then you can tell Grails' command line to load dependencies from the Maven @pom.xml@ file instead. - -To do so simply add the following line to your @BuildConfig.groovy@: - -{code} -grails.project.dependency.resolution = { - pom true - .. -} -{code} - -The line @pom true@ tells Grails to parse Maven's @pom.xml@ and load dependencies from there. diff --git a/src/en/guide/conf/dependencyResolution/mavendeploy.gdoc b/src/en/guide/conf/dependencyResolution/mavendeploy.gdoc deleted file mode 100644 index 0ed80ec6cb2..00000000000 --- a/src/en/guide/conf/dependencyResolution/mavendeploy.gdoc +++ /dev/null @@ -1,101 +0,0 @@ -If you use Maven to build your Grails project, you can use the standard Maven targets @mvn install@ and @mvn deploy@. -If not, you can deploy a Grails project or plugin to a Maven repository using the [release|http://grails.org/plugin/release] plugin. - -The plugin provides the ability to publish Grails projects and plugins to local and remote Maven repositories. There are two key additional targets added by the plugin: - -* *maven-install* - Installs a Grails project or plugin into your local Maven cache -* *maven-deploy* - Deploys a Grails project or plugin to a remote Maven repository - -By default this plugin will automatically generate a valid @pom.xml@ for you unless a @pom.xml@ is already present in the root of the project, in which case this @pom.xml@ file will be used. - -h4. maven-install - -The @maven-install@ command will install the Grails project or plugin artifact into your local Maven cache: - -{code} -grails maven-install -{code} - -In the case of plugins, the plugin zip file will be installed, whilst for application the application WAR file will be installed. - -h4. maven-deploy - -The @maven-deploy@ command will deploy a Grails project or plugin into a remote Maven repository: - -{code} -grails maven-deploy -{code} - -It is assumed that you have specified the necessary @@ configuration within a @pom.xml@ or that you specify the @id@ of the remote repository to deploy to: - -{code} -grails maven-deploy --repository=myRepo -{code} - -The @repository@ argument specifies the 'id' for the repository. Configure the details of the repository specified by this 'id' within your @grails-app/conf/BuildConfig.groovy@ file or in your @$USER_HOME/.grails/settings.groovy@ file: - -{code} -grails.project.dependency.distribution = { - localRepository = "/path/to/my/local" - remoteRepository(id: "myRepo", url: "http://myserver/path/to/repo") -} -{code} - -The syntax for configuring remote repositories matches the syntax from the [remoteRepository|http://maven.apache.org/ant-tasks/reference.html#remoteRepository] element in the Ant Maven tasks. For example the following XML: - -{code} - - - -{code} - -Can be expressed as: - -{code} -remoteRepository(id: "myRepo", url: "scp://localhost/www/repository") { - authentication username: "...", privateKey: "\${userHome}/.ssh/id_dsa" -} -{code} - -By default the plugin will try to detect the protocol to use from the URL of the repository (e.g. "http" from "http://.." etc.), however to specify a different protocol you can do: - -{code} -grails maven-deploy --repository=myRepo --protocol=webdav -{code} - -The available protocols are: - -* http -* scp -* scpexe -* ftp -* webdav - -h4. Groups, Artifacts and Versions - -Maven defines the notion of a 'groupId', 'artifactId' and a 'version'. This plugin pulls this information from the Grails project conventions or plugin descriptor. - -h5. Projects - -For applications this plugin will use the Grails application name and version provided by Grails when generating the @pom.xml@ file. To change the version you can run the @set-version@ command: - -{code} -grails set-version 0.2 -{code} - -The Maven @groupId@ will be the same as the project name, unless you specify a different one in Config.groovy: - -{code} -grails.project.groupId="com.mycompany" -{code} - -h5. Plugins - -With a Grails plugin the @groupId@ and @version@ are taken from the following properties in the @GrailsPlugin.groovy@ descriptor: - -{code} -String groupId = 'myOrg' -String version = '0.1' -{code} - -The 'artifactId' is taken from the plugin name. For example if you have a plugin called @FeedsGrailsPlugin@ the @artifactId@ will be "feeds". If your plugin does not specify a @groupId@ then this defaults to "org.grails.plugins". diff --git a/src/en/guide/conf/dependencyResolution/pluginDependencies.gdoc b/src/en/guide/conf/dependencyResolution/pluginDependencies.gdoc deleted file mode 100644 index 80d27c6db8e..00000000000 --- a/src/en/guide/conf/dependencyResolution/pluginDependencies.gdoc +++ /dev/null @@ -1,91 +0,0 @@ -You can declaratively specify plugins as dependencies via the dependency DSL instead of using the [install-plugin|commandLine] command: - -{code} -grails.project.dependency.resolution = { - ... - repositories { - ... - } - - plugins { - runtime ':hibernate:1.2.1' - } - - dependencies { - ... - } - ... -} -{code} - -If you don't specify a group id the default plugin group id of @org.grails.plugins@ is used. - -h4. Latest Integration - -{warning} -Only the Ivy dependency manager supports the "latest.integration" version. For Aether you can achieve a similar effect with version ranges. -{warning} - -You can specify to use the latest version of a particular plugin by using "latest.integration" as the version number: - -{code} -plugins { - runtime ':hibernate:latest.integration' -} -{code} - -h4. Integration vs. Release - -The "latest.integration" version label will also include resolving snapshot versions. To not include snapshot versions then use the "latest.release" label: - -{code} -plugins { - runtime ':hibernate:latest.release' -} -{code} - -{note} -The "latest.release" label only works with Maven compatible repositories. If you have a regular SVN-based Grails repository then you should use "latest.integration". -{note} - -And of course if you use a Maven repository with an alternative group id you can specify a group id: - -{code} -plugins { - runtime 'mycompany:hibernate:latest.integration' -} -{code} - -h4. Plugin Exclusions - -You can control how plugins transitively resolves both plugin and JAR dependencies using exclusions. For example: - -{code} -plugins { - runtime(':weceem:0.8') { - excludes "searchable" - } -} -{code} - -Here we have defined a dependency on the "weceem" plugin which transitively depends on the "searchable" plugin. By using the @excludes@ method you can tell Grails _not_ to transitively install the searchable plugin. You can combine this technique to specify an alternative version of a plugin: - -{code} -plugins { - runtime(':weceem:0.8') { - excludes "searchable" // excludes most recent version - } - runtime ':searchable:0.5.4' // specifies a fixed searchable version -} -{code} - -You can also completely disable transitive plugin installs, in which case no transitive dependencies will be resolved: - -{code} -plugins { - runtime(':weceem:0.8') { - transitive = false - } - runtime ':searchable:0.5.4' // specifies a fixed searchable version -} -{code} diff --git a/src/en/guide/conf/dependencyResolution/pluginJARDependencies.gdoc b/src/en/guide/conf/dependencyResolution/pluginJARDependencies.gdoc deleted file mode 100644 index 142cc038463..00000000000 --- a/src/en/guide/conf/dependencyResolution/pluginJARDependencies.gdoc +++ /dev/null @@ -1,40 +0,0 @@ -h4. Specifying Plugin JAR dependencies - -The way in which you specify dependencies for a [plugin|guide:plugins] is identical to how you specify dependencies in an application. When a plugin is installed into an application the application automatically inherits the dependencies of the plugin. - -To define a dependency that is resolved for use with the plugin but not _exported_ to the application then you can set the @export@ property of the dependency: - -{code} -compile('org.spockframework:spock-core:0.5-groovy-1.8') { - export = false -} -{code} - -In this case the Spock dependency will be available only to the plugin and not resolved as an application dependency. Alternatively, if you're using the Map syntax: - -{code} -compile group: 'org.spockframework', name: 'spock-core', - version: '0.5-groovy-1.8', export: false -{code} - -{note} -You can use @exported = false@ instead of @export = false@, but we recommend the latter because it's consistent with the Map argument. -{note} - -h4. Overriding Plugin JAR Dependencies in Your Application - -If a plugin is using a JAR which conflicts with another plugin, or an application dependency then you can override how a plugin resolves its dependencies inside an application using exclusions. For example: - -{code} -plugins { - compile("\:hibernate\:\$grailsVersion") { - excludes "javassist" - } -} - -dependencies { - runtime "javassist:javassist:3.4.GA" -} -{code} - -In this case the application explicitly declares a dependency on the "hibernate" plugin and specifies an exclusion using the @excludes@ method, effectively excluding the javassist library as a dependency. diff --git a/src/en/guide/conf/dependencyResolution/providingDefaultDependencies.gdoc b/src/en/guide/conf/dependencyResolution/providingDefaultDependencies.gdoc deleted file mode 100644 index 40ad2403be1..00000000000 --- a/src/en/guide/conf/dependencyResolution/providingDefaultDependencies.gdoc +++ /dev/null @@ -1,25 +0,0 @@ -Most Grails applications have runtime dependencies on several jar files that are provided by the Grails framework. These include libraries like Spring, Sitemesh, Hibernate etc. When a war file is created, all of these dependencies will be included in it. But, an application may choose to exclude these jar files from the war. This is useful when the jar files will be provided by the container, as would normally be the case if multiple Grails applications are deployed to the same container. - -The dependency resolution DSL provides a mechanism to express that all of the default dependencies will be provided by the container. This is done by invoking the @defaultDependenciesProvided@ method and passing @true@ as an argument: - -{code} -grails.project.dependency.resolution = { - - defaultDependenciesProvided true // all of the default dependencies will - // be "provided" by the container - - inherits "global" // inherit Grails' default dependencies - - repositories { - grailsHome() - ... - } - dependencies { - ... - } -} -{code} - -{note} -@defaultDependenciesProvided@ must come before @inherits@, otherwise the Grails dependencies will be included in the war. -{note} diff --git a/src/en/guide/conf/environments.gdoc b/src/en/guide/conf/environments.gdoc index 2b4c940902d..13613d4c8fe 100644 --- a/src/en/guide/conf/environments.gdoc +++ b/src/en/guide/conf/environments.gdoc @@ -1,6 +1,28 @@ h4. Per Environment Configuration -Grails supports the concept of per environment configuration. The @Config.groovy@, @DataSource.groovy@, and @BootStrap.groovy@ files in the @grails-app/conf@ directory can use per-environment configuration using the syntax provided by [ConfigSlurper|http://groovy.codehaus.org/ConfigSlurper]. As an example consider the following default @DataSource@ definition provided by Grails: +Grails supports the concept of per environment configuration. The @application.yml@ and @application.groovy@ files in the @grails-app/conf@ directory can use per-environment configuration using either YAML or the syntax provided by [ConfigSlurper|http://groovy.codehaus.org/ConfigSlurper]. As an example consider the following default @application.yml@ definition provided by Grails: + +{code} +environments: + development: + dataSource: + dbCreate: create-drop + url: jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE + test: + dataSource: + dbCreate: update + url: jdbc:h2:mem:testDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE + production: + dataSource: + dbCreate: update + url: jdbc:h2:prodDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE + properties: + jmxEnabled: true + initialSize: 5 + ... +{code} + +The above can expression in Groovy syntax in @application.groovy@ as follows: {code:java} dataSource { diff --git a/src/en/guide/conf/versioning.gdoc b/src/en/guide/conf/versioning.gdoc index ee6289e7a32..9b23f4f5b5b 100644 --- a/src/en/guide/conf/versioning.gdoc +++ b/src/en/guide/conf/versioning.gdoc @@ -1,27 +1,15 @@ -h4. Versioning Basics - -Grails has built in support for application versioning. The version of the application is set to @0.1@ when you first create an application with the [create-app|commandLine] command. The version is stored in the application meta data file @application.properties@ in the root of the project. - -To change the version of your application you can edit the file manually, or run the [set-version|commandLine] command: - -{code:java} -grails set-version 0.2 -{code} - -The version is used in various commands including the [war|commandLine] command which will append the application version to the end of the created WAR file. - h4. Detecting Versions at Runtime You can detect the application version using Grails' support for application metadata using the [GrailsApplication|api:org.codehaus.groovy.grails.commons.GrailsApplication] class. For example within [controllers|guide:controllers] there is an implicit [grailsApplication|controllers] variable that can be used: {code:java} -def version = grailsApplication.metadata['app.version'] +def version = grailsApplication.metadata.getApplicationVersion() {code} You can retrieve the version of Grails that is running with: {code:java} -def grailsVersion = grailsApplication.metadata['app.grails.version'] +def grailsVersion = grailsApplication.metadata.getGrailsVersion() {code} or the @GrailsUtil@ class: diff --git a/src/en/guide/gettingStarted/conventionOverConfiguration.gdoc b/src/en/guide/gettingStarted/conventionOverConfiguration.gdoc index c9bcff688e9..8d906e84aa6 100644 --- a/src/en/guide/gettingStarted/conventionOverConfiguration.gdoc +++ b/src/en/guide/gettingStarted/conventionOverConfiguration.gdoc @@ -11,8 +11,6 @@ Here is a breakdown and links to the relevant sections: ** @taglib@ - [Tag libraries|guide:taglibs]. ** @utils@ - Grails specific utilities. ** @views@ - [Groovy Server Pages|guide:gsp] - The V in MVC. -* @scripts@ - [Gant scripts|guide:commandLine]. -* @src@ - Supporting sources -** @groovy@ - Other Groovy sources -** @java@ - Other Java sources -* @test@ - [Unit and integration tests|guide:testing]. \ No newline at end of file +* @scripts@ - [Code generation scripts|guide:commandLine]. +* @src/main/groovy@ - Supporting sources +* @src/test/groovy@ - [Unit and integration tests|guide:testing]. \ No newline at end of file diff --git a/src/en/guide/gettingStarted/deployingAnApplication.gdoc b/src/en/guide/gettingStarted/deployingAnApplication.gdoc index 80c94cba055..6d91be0d3eb 100644 --- a/src/en/guide/gettingStarted/deployingAnApplication.gdoc +++ b/src/en/guide/gettingStarted/deployingAnApplication.gdoc @@ -1,10 +1,12 @@ -Grails applications are deployed as Web Application Archives (WAR files), and Grails includes the [war|commandLine] command for performing this task: +Grails applications can be deployed in a number of different ways. + +If you are deploying to a traditional container (Tomcat, Jetty etc.) you can create a Web Application Archive (WAR file), and Grails includes the [war|commandLine] command for performing this task: {code} grails war {code} -This will produce a WAR file under the @target@ directory which can then be deployed as per your container's instructions. +This will produce a WAR file under the @build/libs@ directory which can then be deployed as per your container's instructions. Unlike most scripts which default to the @development@ environment unless overridden, the @war@ command runs in the @production@ environment by default. You can override this like any script by specifying the environment name, for example: @@ -12,12 +14,16 @@ Unlike most scripts which default to the @development@ environment unless overri grails dev war {code} -{warning} -NEVER deploy Grails using the [run-app|commandLine] command as this command sets Grails up for auto-reloading at runtime which has a severe performance and scalability implications -{warning} +If you prefer not to operate a separate Servlet container then you can simply run the Grails WAR file as a regular Java application. Example: + +{code} +grails war +java -Xmx768M -XX:MaxPermSize=256m -jar build/libs/mywar-0.1.war +{code} + When deploying Grails you should always run your containers JVM with the @-server@ option and with sufficient memory allocation. A good set of VM flags would be: {code} --server -Xmx512M -XX:MaxPermSize=256m +-server -Xmx768M -XX:MaxPermSize=256m {code} diff --git a/src/en/guide/gettingStarted/downloadingAndInstalling.gdoc b/src/en/guide/gettingStarted/downloadingAndInstalling.gdoc index 707fa7abacb..72fc663d573 100644 --- a/src/en/guide/gettingStarted/downloadingAndInstalling.gdoc +++ b/src/en/guide/gettingStarted/downloadingAndInstalling.gdoc @@ -1,4 +1,8 @@ -The first step to getting up and running with Grails is to install the distribution. To do so follow these steps: +The first step to getting up and running with Grails is to install the distribution. + +The best way to install Grails on *nix systems is with the [GVM tool|http://gvmtool.net] which greatly simplifies installing and managing multiple Grails versions. + +For manual installation follow these steps: * "Download":http://grails.org/Download a binary distribution of Grails and extract the resulting zip file to a location of your choice * Set the GRAILS_HOME environment variable to the location where you extracted the zip @@ -11,5 +15,5 @@ The first step to getting up and running with Grails is to install the distribut If Grails is working correctly you should now be able to type @grails -version@ in the terminal window and see output similar to this: bc. -Grails version: 2.0.0 +Grails version: 3.0.0 diff --git a/src/en/guide/gettingStarted/requirements.gdoc b/src/en/guide/gettingStarted/requirements.gdoc index 2580a5e79e0..a9feffe0693 100644 --- a/src/en/guide/gettingStarted/requirements.gdoc +++ b/src/en/guide/gettingStarted/requirements.gdoc @@ -1,4 +1,8 @@ -Before installing Grails you will need as a minimum a Java Development Kit (JDK) installed version 1.6 or above. Download the appropriate JDK for your operating system, run the installer, and then set up an environment variable called @JAVA_HOME@ pointing to the location of this installation. If you're unsure how to do this, we recommend the video installation guides from [grailsexample.net|http://www.grailsexample.net/]: +Before installing Grails 3.0 you will need as a minimum a Java Development Kit (JDK) installed version 1.7 or above. Download the appropriate JDK for your operating system, run the installer, and then set up an environment variable called @JAVA_HOME@ pointing to the location of this installation. + +To automate the installation of Grails we recommend the [GVM tool|http://gvmtool.net] which greatly simplifies installing and managing multiple Grails versions. + +For manual installation, we recommend the video installation guides from [grailsexample.net|http://www.grailsexample.net/]: * [Windows|http://www.grailsexample.net/installing-a-grails-development-environment-on-windows/] * [Linux|http://www.grailsexample.net/installing-a-grails-development-environment-on-linux/] diff --git a/src/en/guide/gettingStarted/supportedJavaEEContainers.gdoc b/src/en/guide/gettingStarted/supportedJavaEEContainers.gdoc index ba2bd08d8e0..305f5bfdcd0 100644 --- a/src/en/guide/gettingStarted/supportedJavaEEContainers.gdoc +++ b/src/en/guide/gettingStarted/supportedJavaEEContainers.gdoc @@ -1,25 +1,13 @@ -Grails runs on any container that supports Servlet 2.5 and above and is known to work on the following specific container products: +Grails runs on any container that supports Servlet 3.0 and above and is known to work on the following specific container products: * Tomcat 7 -* Tomcat 6 -* SpringSource tc Server -* Eclipse Virgo -* GlassFish 3 -* GlassFish 2 -* Resin 4 -* Resin 3 -* JBoss 6 -* JBoss 5 -* Jetty 8 -* Jetty 7 -* Jetty 6 -* Oracle Weblogic 10.3 -* Oracle Weblogic 10 -* Oracle Weblogic 9 -* IBM WebSphere 8.5 -* IBM WebSphere 8.0 -* IBM WebSphere 7.0 -* IBM WebSphere 6.1 +* GlassFish 3 or above +* Resin 4 or above +* JBoss 6 or above +* Jetty 8 or above +* Oracle Weblogic 12c or above +* IBM WebSphere 8.0 or above + {note} It's required to set "-Xverify:none" in "Application servers > server > Process Definition > Java Virtual Machine > Generic JVM arguments" for older versions of WebSphere. This is no longer needed for WebSphere version 8 or newer. {note} diff --git a/src/en/guide/gettingStarted/testingAnApplication.gdoc b/src/en/guide/gettingStarted/testingAnApplication.gdoc index 41225bff655..43d656eed75 100644 --- a/src/en/guide/gettingStarted/testingAnApplication.gdoc +++ b/src/en/guide/gettingStarted/testingAnApplication.gdoc @@ -1,4 +1,4 @@ -The @create-*@ commands in Grails automatically create unit or integration tests for you within the @test/unit@ or @test/integration@ directory. It is of course up to you to populate these tests with valid test logic, information on which can be found in the section on [Testing|guide:testing]. +The @create-*@ commands in Grails automatically create unit or integration tests for you within the @src/test/groovy@ directory. It is of course up to you to populate these tests with valid test logic, information on which can be found in the section on [Testing|guide:testing]. To execute tests you run the [test-app|commandLine] command as follows: diff --git a/src/en/guide/gettingStarted/usingInteractiveMode.gdoc b/src/en/guide/gettingStarted/usingInteractiveMode.gdoc index 811f4408791..765efaaa246 100644 --- a/src/en/guide/gettingStarted/usingInteractiveMode.gdoc +++ b/src/en/guide/gettingStarted/usingInteractiveMode.gdoc @@ -1,4 +1,4 @@ -Grails 2.0 features an interactive mode which makes command execution faster since the JVM doesn't have to be restarted for each command. To use interactive mode simple type 'grails' from the root of any projects and use TAB completion to get a list of available commands. See the screenshot below for an example: +Grails 3.0 features an interactive mode which makes command execution faster since the JVM doesn't have to be restarted for each command. To use interactive mode simple type 'grails' from the root of any projects and use TAB completion to get a list of available commands. See the screenshot below for an example: !interactive-output.png! diff --git a/src/en/guide/toc.yml b/src/en/guide/toc.yml index ecc772e43b2..20e795a91cd 100644 --- a/src/en/guide/toc.yml +++ b/src/en/guide/toc.yml @@ -22,8 +22,7 @@ gettingStarted: supportedJavaEEContainers: Supported Java EE Containers creatingArtefacts: Creating Artefacts generatingAnApplication: Generating an Application -upgradingFrom22: Upgrading from Grails 2.2 -upgradingFrom23: Upgrading from Grails 2.3 +upgradingFrom2: Upgrading from Grails 2.x conf: title: Configuration config: @@ -35,38 +34,19 @@ conf: dataSource: title: The DataSource dataSourcesAndEnvironments: DataSources and Environments - JNDIDataSources: JNDI DataSources automaticDatabaseMigration: Automatic Database Migration transactionAwareDataSourceProxy: Transaction-aware DataSource Proxy databaseConsole: Database Console multipleDatasources: Multiple Datasources - configExternalized: Externalized Configuration versioning: Versioning docengine: Project Documentation - dependencyResolution: - title: Dependency Resolution - configurationsAndDependencies: Configurations and Dependencies - dependencyRepositories: Dependency Repositories - debuggingResolution: Debugging Resolution - inheritedDependencies: Inherited Dependencies - providingDefaultDependencies: Providing Default Dependencies - changingDependencies: Snapshots and Other Changing Dependencies - dependencyReports: Dependency Reports - pluginJARDependencies: Plugin JAR Dependencies - mavenIntegration: Maven Integration - mavendeploy: Deploying to a Maven Repository - pluginDependencies: Plugin Dependencies - dependencyResolutionCaching: Caching of Dependency Resolution Results + dependencyResolution: Dependency Resolution commandLine: title: The Command Line interactiveMode: Interactive Mode - forkedMode: Forked Execution - creatingGantScripts: Creating Gant Scripts + profiles: The Command Line and Profiles + creatingCustomScripts: Creating Custom Scripts reusingGrailsScripts: Re-using Grails scripts - events: Hooking into Events - buildCustomising: Customising the build - antAndMaven: Ant and Maven - wrapper: Grails Wrapper GORM: title: Object Relational Mapping (GORM) quickStartGuide: diff --git a/src/en/guide/upgradingFrom2.gdoc b/src/en/guide/upgradingFrom2.gdoc new file mode 100644 index 00000000000..a0990367ef8 --- /dev/null +++ b/src/en/guide/upgradingFrom2.gdoc @@ -0,0 +1 @@ +TBD diff --git a/src/en/guide/upgradingFrom22.gdoc b/src/en/guide/upgradingFrom22.gdoc deleted file mode 100644 index 73e7e7fcb3a..00000000000 --- a/src/en/guide/upgradingFrom22.gdoc +++ /dev/null @@ -1,197 +0,0 @@ -A number of changes need to be considered when upgrading your application from Grails 2.2, some of them breaking. Here's a quick list with more detail on each item following after: - -* New improved data binding (no Spring property editors) -* Much improved XSS prevention with default HTML encoding -* A new dependency resolution engine -* Must be online to fetch Grails dependencies -* Grails core dependencies rearranged -* Tomcat and Hibernate plugins independently versioned now (breaking!) -* Scaffolding is now a separate plugin -* Spock included by default -* Dependency injection does not work in integration tests by default -* Forked execution for tests -* Reloading in @run-app@ won't work by default on upgraded apps -* @grails-debug@ doesn't work for forked execution - - -h4. New Data Binder - -There is a new data binding mechanism written from the ground up to meet Grails' needs. If you wish to continue using Spring for data binding then you must set the @grails.databinding.useSpringBinder@ property to @true@ in @grails-app/conf/Config.groovy@ - -h4. Encoding / Escaping (XSS) Changes - -Grails 2.3 includes new features to help prevent XSS attacks. These are enabled by default for new applications, but older applications will require manual intervention. See the section on [Cross Site Scripting (XSS) prevention|guide:xssPrevention] for how to appropriately configure XSS prevention. - -h4. Dependency Resolution changes - -Although dependency resolution using Ivy is still supported, the default for Grails 2.3 is to use Aether and the Ivy support will not be improved upon going forward. You may wish to consider using Aether instead for your existing applications by setting the following in @grails-app/conf/BuildConfig.groovy@: - -{code} -grails.project.dependency.resolver = "maven" // or ivy -{code} - -If you need to authenticate to a maven repository, you will want to change the definition of that repository like so: - -{code} -mavenRepo("http://artifactory.mycompany.com/repo") { - authentication(username: "myusername", password: "secret") -} -{code} - -h4. Dependency Metadata Changes - -In addition, the POM and dependency metadata for Grails 2.3 has been re-arranged and cleaned up so that only direct dependencies are specified for an application and all other dependencies are inherited transitively. This has implications to the upgrade since, for example, Ehcache is now a transitive dependency of the Hibernate plugin, whilst before it was a direct dependency. If get a compilation error related to Ehcache, it is most likely that you don't have the Hibernate plugin installed and need to directly declare the Ehcache dependency: - -{code} -compile "net.sf.ehcache:ehcache-core:2.4.6" -{code} - -In addition, excludes may no longer work and may need adjusting when upgrading due to how the metadata has changed. Run the [dependency-report|commandLine] to see the new dependency metadata and make adjustments accordingly. - -A common error that may occur when upgrading is: - -{code} -| Configuring classpath -:: problems summary :: -:::: WARNINGS - :::::::::::::::::::::::::::::::::::::::::::::: - :: UNRESOLVED DEPENDENCIES :: - :::::::::::::::::::::::::::::::::::::::::::::: - :: org.springframework#spring-test;3.2.2.RELEASE: configuration not found in org.springframework#spring-test;3.2.2.RELEASE: 'compile'. It was required from org.grails#grails-plugin-testing;2.3.0.BUILD-SNAPSHOT compile - :::::::::::::::::::::::::::::::::::::::::::::: -{code} - -This is caused by a plugin that depends on an old version of @spring-test@ (for example the [Mail plugin|http://grails.org/plugins/mail]). To correct this run @grails dependency-report@ and search for plugins that have a transitive dependency on @spring-test@ and exclude them. For example: - -{code} -plugins { - compile ':mail:1.0', { - excludes 'spring-test' - } -} -{code} - -However, longer term to solve problems like this we recommend that users move away from Ivy and use Aether instead for dependency resolution: - -{code} -grails.project.dependency.resolver="maven" -{code} - -h4. No initial offline mode with Aether - -Aether does not support resolving dependencies from a flat file system. This means that the jars we ship with Grails in GRAILS_HOME/lib are not used for the first resolve, but instead the jars are obtained from Maven central. After they have been obtained from Maven central then Aether operates fine offline. - -If however you do not have the necessary jars in your local Maven repository, then the only way to get offline execution is to enable Ivy via BuildConfig (see above). - -h4. Changes to Core plugin versioning schemes and the Upgrade command - -Core plugins like @tomcat@ and @hibernate@ are no longer versioned the same as the Grails version, instead they are versioned according to the Tomcat and Hibernate version they target. If you are upgrading from Grails 2.2 you need to manually configure the correct Tomcat and Hibernate plugins in @BuildConfig@. The @upgrade@ command will not do this for you! - -{code} - plugins { - // plugins for the build system only - build ':tomcat:7.0.42' - - // plugins needed at runtime but not for compilation - runtime ':hibernate:3.6.10.2' - } -{code} - -Note that the @upgrade@ command will be deprecated in 2.3 and replaced with a command named @use-current-grails-version@, which will make no attempts to automatically upgrade Grails applications. - -h4. Scaffolding moved to a plugin and rewritten - -If you have dynamically scaffolded controllers in your application then you will need to configure the 1.0 version of the [Scaffolding plugin|http://grails.org/plugin/scaffolding] in BuildConfig: - -{code} -plugins { - compile ':scaffolding:1.0.0' -} -{code} - -By default for new applications the 2.0 version of the scaffolding plugin is used, which is not backwards compatible with 1.0. - -h4. Spock included by default - -You no longer need to add the Spock plugin to your projects. Simply create Spock specifications as before and they will be run as unit tests. In fact, don't install the Spock plugin, otherwise your specifications will run twice and potentially fail. This also means that the @spock@ test type no longer exists. Specifications and JUnit tests run as the same type now. - -h4. Dependency Injection for Integration Tests - -In order to support alternate JUnit4 test runners, Grails 2.3 no longer uses a special test runner to run tests and integration tests should no longer extend @GroovyTestCase@. - -This change requires that any JUnit integration tests that require dependency injection now need to be annotated with: - -{code} -\@TestMixin(IntegrationTestMixin) -{code} - -For Spock integration tests, extending @IntegrationSpec@ also works. - -h4. Forked Execution for Testing - -Tests are now by default executed in a forked JVM (although this can be disabled). One implication of this is that tests will be slower to execute when using: - -{code} -grails test-app -{code} - -The reason for this is the need to load a separate JVM to execute tests. To mitigate this Grails interactive mode has been updated to load a background JVM that can be resumed. If you do: - -{code} -$ grails // load interactive mode -$ grails -> test-app -$ grails -> test-app -{code} - -Test execution will be noticeably faster and is the recommended way to run tests in Grails. On older hardware that does not include multiple cores (to run the separate JVMs) it is recommended you disable forked execution for tests to achieve faster test execution times: - -{code} -forkConfig = [maxMemory: 1024, minMemory: 64, debug: false, maxPerm: 256] -grails.project.fork = [ - test: false, // disable forked execution for test-app - run: forkConfig, // configure settings for the run-app JVM - ... -] -{code} - -h4. Forked Execution and the Reloading Agent - -In Grails 2.3 the reloading agent is no longer on the build system path unless you pass the @-reloading@ flag to the @grails@ command: - -{code} -grails -reloading run-app -{code} - -The reason for this is that the default in Grails 2.3 and above is to load Grails application in a forked JVM and enable the agent for the forked JVM. If you do not wish to use forked JVMs then you must ensure that you run Grails with the @-reloading@ flag. Alternatively, you can enable forking with the following configuration in @BuildConfig@: - -{code} -forkConfig = [maxMemory: 1024, minMemory: 64, debug: false, maxPerm: 256] -grails.project.fork = [ - test: forkConfig, // configure settings for the test-app JVM - run: forkConfig, // configure settings for the run-app JVM - war: forkConfig, // configure settings for the run-war JVM - console: forkConfig // configure settings for the Swing console JVM -] -{code} - -h4. Forked Execution and Remote Debugging - -The @grails-debug@ command will no longer work with Grails for remote debugging sessions. The reason is the command enabled debugging for the build system JVM, but not the JVM used in forked execution. The solution to this is to use the @debug-fork@ command line argument: - -{code} -grails --debug-fork run-app -{code} - - -Alternatively you can set the @debug@ setting to @true@ in @BuildConfig@ and use the regular @grails@ command to execute: - -{code} -forkConfig = [maxMemory: 1024, minMemory: 64, debug: true, maxPerm: 256] -grails.project.fork = [ - run: forkConfig, // configure settings for the run-app JVM - ... -{code} - -h4. Forked Execution and Functional Test plugins - -Some existing plugins (Cucumber plugin for example) do not work with 2.3.x forked execution because they expect the tests to be running in the same JVM as the application under tests. For example it is not possible to setup fixture / test data using GORM inside a functional test and have that data visible to the application under test since the application under test is in a separate JVM. The solution to this is to provide the necessary fixture data in the @BootStrap@ of the application (only for the test environment of course). diff --git a/src/en/guide/upgradingFrom23.gdoc b/src/en/guide/upgradingFrom23.gdoc deleted file mode 100644 index 7d48678bb06..00000000000 --- a/src/en/guide/upgradingFrom23.gdoc +++ /dev/null @@ -1,237 +0,0 @@ -h4. The upgrade Command - -The @upgrade@ command has been removed from Grails 2.4. The procedure for upgrading to the latest version of Grails will be detailed in the user guide from now on. Below are steps that must be taken to upgrade an application from 2.3.x to 2.4. - -h4. The set-grails-version Command - -The [set-grails-version|commandLine] command should be run to update the application's metadata to indicate which version of Grails the application is built with. - -h4. Update to latest Plugin versions - -You should update your application's @BuildConfig@ to use the latest plugins compatible with Grails 2.3. Example: - -{code:none} - plugins { - // plugins for the build system only - build ':tomcat:7.0.52.1' - - // plugins for the compile step - compile ':scaffolding:2.1.0' - compile ':cache:1.1.3' - compile ':asset-pipeline:1.8.3' - - // plugins needed at runtime but not for compilation - runtime ':hibernate4:4.3.5.2' // or ':hibernate:3.6.10.14' - runtime ':database-migration:1.4.0' - runtime ':jquery:1.11.0.2' - ... - } -{code} - -You may get compilation errors or incompatibility problems with older versions of the above plugins installed. - -h4. grails-debug Script Has Been Removed - -The @grails-debug@ and @grails-debug.bat@ scripts have been removed. To debug the build system JVM run @grails -debug @ and to debug the forked JVM run @grails --debug-fork @. - -h4. New Command Object Data Binding Behavior - -The data binding behavior for command objects has changed in Grails 2.4. Request parameter names may now be prefixed with the name of the controller action argument name that the request parameter should be bound to. For example, if a request is made to the @buy@ action in the controller below a request parameter named @buyer.name@ will be bound to the @name@ property of the @buyer@ argument and a request parameter named @seller.name@ will be bound to the @name@ property of the @seller@ argument. See the [Command Objects|guide:commandObjects] documentation for more details. - - -h4. New Behavior For Domain Class Command Objects - -If a command object's type is a domain class and there is no @id@ request parameter then @null@ will be passed into the controller action unless the HTTP request method is "POST", in which case a new instance of the domain class will be created by invoking the domain class constructor. For all of the cases where the domain class instance is non-null, data binding is only performed if the HTTP request method is "POST", "PUT" or "PATCH". See the [Command Objects|guide:commandObjects] documentation for more details. - -h4. Nullable Command Object Properties - -The behavior in Grails 2.3.x is such that constrained properties in command objects and other classes marked with \@Validateable are all configured with @nullable: false@ by default. Unconstrained properties were not configured with @nullable: false@. In Grails 2.4 all non-static unconstrained properties in command object classes and other classes marked with \@Validateable are all configured with @nullable: false@. - - -{code:java} -class StoreController { - def buy(Person buyer, Person seller) { - // ... - } -} - -class Person { - String name -} -{code} - -If you wish to retain the old behavior, you can do so on a per-command object basis by using the \@Validateable constraint explicitly and passing the @nullable: true@ argument: - -{code:java} -@Validateable(nullable = true) -class Person { - String name -} -{code} - -This will cause all properties to be nullable by default unless a constraint is explicitly added (similar to the behavior prior to Grails 2.4). - -See the [Command Objects documentation|guide:commandObjects] for more details. - -h4. Ajax Tags Have Been Deprecated - -The [formRemote|tags], [remoteField|tags], [remoteFunction|tags] and [remoteLink|tags] Ajax tags have been deprecated and will be removed from a future version of Grails. Applications may provide their own Ajax tags and/or Javascript plugins may provide Ajax tags of their own. - -h4. The Spring Data Binder Has Been Deprecated - -The @grails.databinding.useSpringBinder@ config property may be set to @true@ to tell Grails to use the Spring data binder instead of the Grails data binder. The Spring data binder has been deprecated and will be removed from a future version of Grails. It is recommended that when upgrading to Grails 2.4 that the Grails data binder be used. - -h4. The resources Plugin - -As of Grails 2.4 the @resources@ plugin has been replaced with the @asset-pipeline@ plugin as the default resource management plugin for newly created applications. See the [static resource abstraction|guide:resources] section of the User Guide for more details. When upgrading an application to Grails 2.4 if you choose to continue using the resources plugin you will need to use version 1.2.7 or later as previous versions of the plugin are not compatible with Grails 2.4. - -h4. Static Holder Classes - -The following deprecated classes have been removed from Grails 2.4.x: - -* @org.codehaus.groovy.grails.commons.ApplicationHolder@ -* @org.codehaus.groovy.grails.commons.ConfigurationHolder@ -* @org.codehaus.groovy.grails.plugins.PluginManagerHolder@ -* @org.codehaus.groovy.grails.web.context.ServletContextHolder@ -* @org.codehaus.groovy.grails.compiler.support.GrailsResourceLoaderHolder@ - -If you or any plugins you have installed are using these classes you will get a compilation error. The problem can be rectified by updating to new plugins and using @grails.util.Holders@ instead. - -{note} -If your application uses the jquery plugin you will need to update to version 1.11.0.2 or later as previous versions of the plugin made use of the @ApplicationHolder@ class. If your application uses the resources plugin you will need to update to version 1.2.7 or later as previous versions of the plugin made use of the @ConfigurationHolder@ class. -{note} - -h4. Changes To applicationContext.xml - -The @web-app/WEB-INF/applicationContext.xml@ file contains a bean definition for a @grailsResourceLoader@ bean which is an instance of @org.codehaus.groovy.grails.commons.GrailsResourceLoaderFactoryBean@. That bean definition needs to be removed from the file. The @grailsApplication@ bean may have the @grailsResourceLoader@ bean injected into it as shown below. - -{code:java} - - Grails application factory bean - - - -{code} - -The @grailsApplication@ bean definition should be left in the file but the @grailsResourceLoader@ bean reference should be removed as shown below. - -{code:java} - - Grails application factory bean - - -{code} - -h4. Changes to web.xml - -The Sitemesh servlet filter has been removed and the GSP layout feature is now handled by [GrailsLayoutView|api:org.codehaus.groovy.grails.web.sitemesh.GrailsLayoutView]. -Applications that are using a customized web.xml should apply the customizations to a web.xml file of Grails 2.4 . -This applies only to applications that have used the "install-templates" to install template files in src/templates folder of the application. -It's recommended to rename src/templates to a different name and use a diff tool to apply the possible application specific customizations to the files created with Grails 2.4 install-templates command. - -h4. Data Binding Changes - -Prior to Grails 2.4 when data binding was performed with the @params@ object in a controller, if the request contained a body the body would be parsed and used for data binding instead of the @params@ object. In Grails 2.4 this behavior has changed so that if binding is initiated with @params@, the binding will always be done with the @params@ object, without regard to whether or not the request has a body. If binding is done with the @request@ object, if the request has a body then the body will be parsed and used for data binding, otherwise the request parameters will be used for data binding. - -{code:java} -class SomeController { - - def someAction() { - // Prior to Grails 2.4 if the request contains a body - // then obj1 will be populated with values parsed from - // the body instead of with values in params. - - // With Grails 2.4 obj1 will be populated with values - // in params. - def obj1 = new SomeDomainClass(params) - - // the same is true for the following - def obj2 = new SomeDomainClass() - obj2.properties = params - } - - def someOtherAction() { - // If the request contains a body then obj1 will be - // populated with values parsed from the body, otherwise - // obj1 will be populated with the request parameters. - - // This is not a new change in behavior. - def obj1 = new SomeDomainClass() - obj1.properties = request - } -} -{code} - -{note} -There is one release in the 2.3.x chain which has the 2.4 behavior described above and that is Grails 2.3.8. None of the 2.3.x releases before or after 2.3.8 have this behavior. -{note} - -h4. The allowedMethods Property And Unit Tests - -The unit testing environment now respects the [allowedMethods|controllers] property in controllers. Prior to Grails 2.4 a unit test which accessed a controller action which is supposed to be restricted to certain request methods could have skipped the step of setting the request method in the unit test because the allowedMethods property was ignored by the unit test. As of Grails 2.4 if a controller action is limited to be accessed with certain request methods, the unit test must be constructed to deal with that. - -{code:java} -// grails-app/controllers/com/demo/DemoController.groovypackage com.demo - -class DemoController { - - static allowedMethods = [save: 'POST', update: 'PUT', delete: 'DELETE'] - - def save() { - render 'Save was successful!' - } - - // ... -} -{code} - -{code:java} -// test/unit/com/demo/DemoControllerSpec.groovy -package com.demo - -import grails.test.mixin.TestFor -import spock.lang.Specification -import static javax.servlet.http.HttpServletResponse.* - -@TestFor(DemoController) -class DemoControllerSpec extends Specification { - - void "test a valid request method"() { - when: - request.method = 'POST' - controller.save() - - then: - response.status == SC_OK - response.text == 'Save was successful!' - } - - void "test an invalid request method"() { - when: - request.method = 'DELETE' - controller.save() - - then: - response.status == SC_METHOD_NOT_ALLOWED - } -} -{code} - -h4. scanning for JSP taglibs has to be configured, no JSTL default dependency - -JSP taglib tld files aren't scanned by default any more. This must be configured with the @grails.gsp.tldScanPattern@ setting. It accepts a comma separated String value. Spring's PathMatchingResourcePatternResolver is used to resolve the patterns. - -You can get the previous behaviour by adding this setting to Config.groovy: -{code} -grails.gsp.tldScanPattern='classpath*:/META-INF/*.tld,/WEB-INF/tld/*.tld' -{code} - -JSTL standard library is no more added as a dependency. In case you are using JSTL, you should also add these dependencies: -{code} - runtime 'javax.servlet:jstl:1.1.2' - runtime 'taglibs:standard:1.1.2' -{code} - - - - From aa181d2baa5f4cbb1bef12c2dae86a6002778149 Mon Sep 17 00:00:00 2001 From: Graeme Rocher Date: Fri, 9 Jan 2015 10:11:05 +0100 Subject: [PATCH 026/230] Remove redundant commands Command no longer present in Grails 3.0 --- src/en/ref/Command Line/add-proxy.gdoc | 31 --------- src/en/ref/Command Line/clear-proxy.gdoc | 21 ------- .../create-hibernate-cfg-xml.gdoc | 24 ------- .../create-multi-project-build.gdoc | 46 -------------- src/en/ref/Command Line/create-pom.gdoc | 27 -------- .../create-scaffold-controller.gdoc | 31 --------- .../ref/Command Line/install-dependency.gdoc | 49 --------------- src/en/ref/Command Line/install-plugin.gdoc | 63 ------------------- .../ref/Command Line/install-templates.gdoc | 39 ------------ src/en/ref/Command Line/integrate-with.gdoc | 37 ----------- src/en/ref/Command Line/interactive.gdoc | 25 -------- src/en/ref/Command Line/migrate-docs.gdoc | 33 ---------- .../Command Line/refresh-dependencies.gdoc | 36 ----------- src/en/ref/Command Line/remove-proxy.gdoc | 24 ------- src/en/ref/Command Line/run-script.gdoc | 40 ------------ src/en/ref/Command Line/run-war.gdoc | 45 ------------- .../ref/Command Line/set-grails-version.gdoc | 37 ----------- src/en/ref/Command Line/set-proxy.gdoc | 26 -------- src/en/ref/Command Line/set-version.gdoc | 24 ------- src/en/ref/Command Line/stop-app.gdoc | 19 ------ src/en/ref/Command Line/uninstall-plugin.gdoc | 20 ------ src/en/ref/Command Line/wrapper.gdoc | 32 ---------- 22 files changed, 729 deletions(-) delete mode 100644 src/en/ref/Command Line/add-proxy.gdoc delete mode 100644 src/en/ref/Command Line/clear-proxy.gdoc delete mode 100644 src/en/ref/Command Line/create-hibernate-cfg-xml.gdoc delete mode 100644 src/en/ref/Command Line/create-multi-project-build.gdoc delete mode 100644 src/en/ref/Command Line/create-pom.gdoc delete mode 100644 src/en/ref/Command Line/create-scaffold-controller.gdoc delete mode 100644 src/en/ref/Command Line/install-dependency.gdoc delete mode 100644 src/en/ref/Command Line/install-plugin.gdoc delete mode 100644 src/en/ref/Command Line/install-templates.gdoc delete mode 100644 src/en/ref/Command Line/integrate-with.gdoc delete mode 100644 src/en/ref/Command Line/interactive.gdoc delete mode 100644 src/en/ref/Command Line/migrate-docs.gdoc delete mode 100644 src/en/ref/Command Line/refresh-dependencies.gdoc delete mode 100644 src/en/ref/Command Line/remove-proxy.gdoc delete mode 100644 src/en/ref/Command Line/run-script.gdoc delete mode 100644 src/en/ref/Command Line/run-war.gdoc delete mode 100644 src/en/ref/Command Line/set-grails-version.gdoc delete mode 100644 src/en/ref/Command Line/set-proxy.gdoc delete mode 100644 src/en/ref/Command Line/set-version.gdoc delete mode 100644 src/en/ref/Command Line/stop-app.gdoc delete mode 100644 src/en/ref/Command Line/uninstall-plugin.gdoc delete mode 100644 src/en/ref/Command Line/wrapper.gdoc diff --git a/src/en/ref/Command Line/add-proxy.gdoc b/src/en/ref/Command Line/add-proxy.gdoc deleted file mode 100644 index 2e00674036b..00000000000 --- a/src/en/ref/Command Line/add-proxy.gdoc +++ /dev/null @@ -1,31 +0,0 @@ -h1. add-proxy - -h2. Purpose - -Adds a proxy configuration that Grails can use when communicating over the internet such as with the [install-plugin|commandLine] command. - -The proxy configuration can be activated with the [set-proxy|commandLine] command. - -h2. Examples - -{code:java} -grails add-proxy client --host=proxy-server --port=4300 \ - --username=guest --password=guest -{code} - -h2. Description - -Usage: -{code:java} -grails add-proxy [name] --host=[server] --port=[port] \ - --username=[username]* --password=[password]* -{code} - -Arguments: - -* @name@ - The name of the proxy configuration -* @host@ - The server host -* @port@ - The server port -* @username@ (optional) - The server username -* @password@ (optional) - The server password - diff --git a/src/en/ref/Command Line/clear-proxy.gdoc b/src/en/ref/Command Line/clear-proxy.gdoc deleted file mode 100644 index 310b8052918..00000000000 --- a/src/en/ref/Command Line/clear-proxy.gdoc +++ /dev/null @@ -1,21 +0,0 @@ -h1. clear-proxy - -h2. Purpose - -Clears the current proxy configuration Grails should use when communicating over the internet such as with the [install-plugin|commandLine] command. - -Proxy configurations are defined using the [add-proxy|commandLine] command - -h2. Examples - -{code:java} -grails clear-proxy -{code} - -h2. Description - -Usage: -{code:java} -grails clear-proxy -{code} - diff --git a/src/en/ref/Command Line/create-hibernate-cfg-xml.gdoc b/src/en/ref/Command Line/create-hibernate-cfg-xml.gdoc deleted file mode 100644 index 5d2d0e19bec..00000000000 --- a/src/en/ref/Command Line/create-hibernate-cfg-xml.gdoc +++ /dev/null @@ -1,24 +0,0 @@ -h1. create-hibernate-cfg-xml - -h2. Purpose - -The @create-hibernate-cfg-xml@ command will create a hibernate.cfg.xml file for custom Hibernate mappings. - -h2. Examples - -bc. -grails create-hibernate-cfg-xml - -h2. Description - -Creates a @hibernate.cfg.xml@ file in the @grails-app/conf/hibernate@ directory. You can add @@ elements there to reference annotated Java domain classes, classes mapped by hbm.xml files, or hbm.xml files containing @@ elements defining custom DDL that's not supported by GORM. - -Usage: -{code:java} -grails create-hibernate-cfg-xml -{code} - -Fired Events: - -* @CreatedFile@ - When the file is created - diff --git a/src/en/ref/Command Line/create-multi-project-build.gdoc b/src/en/ref/Command Line/create-multi-project-build.gdoc deleted file mode 100644 index 061306353ef..00000000000 --- a/src/en/ref/Command Line/create-multi-project-build.gdoc +++ /dev/null @@ -1,46 +0,0 @@ -h1. create-multi-project-build - -h2. Purpose - -The @create-multi-project-build@ creates a multi-module Maven build from a Grails application and plugins - -h2. Examples - -bc. -grails create-multi-project-build org.mycompany:foo:1.0 - -h2. Description - -The @create-multi-project-build@ is designed to be run from the parent directory containing Grails applications and plugins. It will generate a parent POM and POMs for each child directory containing an application or plugin. It assumes that applications depend on all plugins in the parent directory and configures dependencies based on this assumption. Simple example: - -{code} -$ grails create-app myapp -$ grails create-plugin plugin1 -$ grails create-plugin plugin2 -$ grails create-multi-project-build org.mycompany:parent:1.0 -{code} - -The application will contain a @pom.xml@ with dependencies configured for each plugin: - -{code} - - org.grails.plugins - plugin1 - 0.1 - zip - compile - -{code} - -Running @mvn install@ will build all projects together. To enable the 'grails' command to read the POMs you can modify @BuildConfig.groovy@ to use the POM and resolve dependencies from your Maven local cache: - -{code} -grails.project.dependency.resolution = { - ... - pom true - repositories { - ... - mavenLocal() - } -} -{code} \ No newline at end of file diff --git a/src/en/ref/Command Line/create-pom.gdoc b/src/en/ref/Command Line/create-pom.gdoc deleted file mode 100644 index 703d7d5ed5f..00000000000 --- a/src/en/ref/Command Line/create-pom.gdoc +++ /dev/null @@ -1,27 +0,0 @@ -h1. create-pom - -h2. Purpose - -The @create-pom@ creates a POM file for the current application allowing it to be built with Maven. - -h2. Examples - -bc. -grails create-pom org.mycompany - -h2. Description - -The @create-pom@ command will generate a @pom.xml@ file usable by Maven for the current Grails application. - -Running @mvn package@ will build the project. To enable the 'grails' command to read the POM you can modify @BuildConfig.groovy@ to use the POM and resolve dependencies from your Maven local cache: - -{code} -grails.project.dependency.resolution = { - ... - pom true - repositories { - ... - mavenLocal() - } -} -{code} \ No newline at end of file diff --git a/src/en/ref/Command Line/create-scaffold-controller.gdoc b/src/en/ref/Command Line/create-scaffold-controller.gdoc deleted file mode 100644 index 4752fbdeeae..00000000000 --- a/src/en/ref/Command Line/create-scaffold-controller.gdoc +++ /dev/null @@ -1,31 +0,0 @@ -h1. create-scaffold-controller - -h2. Purpose - -The @create-scaffold-controller@ command creates a controller that scaffolds the given domain class, based on convention. - -h2. Examples - -{code} -grails create-scaffold-controller -grails create-scaffold-controller org.bookstore.Book -{code} - -h2. Description - -Creates a dynamic scaffolding controller for the given domain class. If the domain class does not exist, the command will fail. The argument is optional, but if you don't include it the command will ask you for the name of the domain class to scaffold. - -A [controller|guide:controllers] is responsible for handling incoming web requests and performing actions such as redirects, rendering views and so on. A dynamically scaffolding controller automatically provides a fully-fledged CRUD user interface for a particular domain class, allowing users to create new records, modify them, and delete them. - -With the second example above, this command will create the file @grails-app/controllers/org/bookstore/BookController.groovy@ that declares a controller class containing a static @scaffold@ property. The controller's package is the same as for the domain class and the class name is the domain class name with a 'Controller' suffix. - -Note that this command is just for convenience and you can also create dynamic scaffolding controllers in your favourite text editor or IDE if you choose. - -Usage: -{code:java} -grails create-scaffold-controller [name] -{code} - -Fired Events: - -* @CreatedFile@ - When the controller is created diff --git a/src/en/ref/Command Line/install-dependency.gdoc b/src/en/ref/Command Line/install-dependency.gdoc deleted file mode 100644 index 0fb3754e50d..00000000000 --- a/src/en/ref/Command Line/install-dependency.gdoc +++ /dev/null @@ -1,49 +0,0 @@ -h1. install-dependency - -h2. Purpose - -Installs a JAR dependency, making it available to Grails [dependency resolution|guide:dependencyResolution] mechanism. - -h2. Examples - -{code:java} -grails install-dependency mysql:mysql-connector-java:5.1.16 -grails install-dependency mysql:mysql-connector-java:5.1.16 --dir=lib -grails install-dependency --group=mysql --name=mysql-connector-java --version=5.1.16 -{code} - -h2. Description - -Usage: -{code:java} -grails install-dependency [dependency] -{code} - -Arguments: - -* @group@ - The group of the dependency -* @name@ - The name of the dependency -* @version@ - The version of the dependency -* @repository@ - The repository to resolve from -* @dir@ - The target directory to resolve JAR files to - -The @install-dependency@ command allows the installation of a JAR dependency into the dependency cache so that it can be resolved locally (without needing to configure a repository explicitly). - -In its most simple form you can pass a single argument that defines the dependency in the form "group:name:version": - -{code} -grails install-dependency mysql:mysql-connector-java:5.1.16 -{code} - -Grails has some built in common public Maven repositories that will be used to resolve the dependency. If the dependency is not found you can specify your own repository using the @repository@ argument: - -{code} -grails install-dependency mysql:mysql-connector-java:5.1.16 \\\\ - --repository=http://download.java.net/maven/2 -{code} - -By default the JARs will be resolved to your local Ivy cache (typically @\$USER_HOME/.ivy2/cache@) when using Ivy and into your local Maven repoistory (typically @\$USER_HOME/.m2/repository@) when using Aether, if you wish the JAR files to be placed in an alternative directory you can use the @dir@ argument: - -{code} -grails install-dependency mysql:mysql-connector-java:5.1.16 --dir=lib -{code} diff --git a/src/en/ref/Command Line/install-plugin.gdoc b/src/en/ref/Command Line/install-plugin.gdoc deleted file mode 100644 index 0366a98a28d..00000000000 --- a/src/en/ref/Command Line/install-plugin.gdoc +++ /dev/null @@ -1,63 +0,0 @@ -h1. install-plugin - -h2. Purpose - -Installs a plugin from the Grails central SVN repository, a file, or a URL - -{warning} -DEPRECATED: The install-plugin command is deprecated - -Plugins should be installed by listing them in BuildConfig.groovy with the appropriate scope instead of using install-plugin. -{warning} - -h2. Examples - -{code:java} -grails install-plugin shiro -grails install-plugin shiro 1.1 -grails install-plugin ../grails-bar-1.0.zip -grails install-plugin http://foo.com/grails-bar-1.0.zip -{code} - -h2. Description - -Usage: -{code:java} -grails install-plugin [name] [version]* -grails install-plugin [URL/File] -{code} - -Fired Events: - -* @StatusUpdate@ - Fired at various points during the plugin installation -* @StatusError@ - When an error occurs during plugin installation -* @StatusFinal@ - When the plugin is installed successfully -* @PluginInstalled@ - When the plugin is installed successfully - -The @install-plugin@ command is a versatile command that installs plugins from the Grails central SVN repository at [http://svn.codehaus.org/grails-plugins/|http://svn.codehaus.org/grails-plugins/], a local file, or a remote URL. - -To install a plugin from the remote central repository, for example the "shiro" plugin, use the @install-plugin@ command followed by the plugin name: - -{code:java} -grails install-plugin shiro -{code} - -This will install the latest version of the plugin. To install a specific version specify it as an argument: - -{code:java} -grails install-plugin shiro 1.1 -{code} - -To find out what plugins are available use the [list-plugins|commandLine] command. - -To install from a URL, simply specify the absolute URL to the plugin package: - -{code:java} -grails install-plugin http://foo.com/grails-bar-1.0.zip -{code} - -To install from a local file, specify the absolute or relative path to the file: - -{code:java} -grails install-plugin ../grails-bar-1.0.zip -{code} diff --git a/src/en/ref/Command Line/install-templates.gdoc b/src/en/ref/Command Line/install-templates.gdoc deleted file mode 100644 index 526fc0aafcf..00000000000 --- a/src/en/ref/Command Line/install-templates.gdoc +++ /dev/null @@ -1,39 +0,0 @@ -h1. install-templates - -h2. Purpose - -Copies the the templates used by Grails during code generation to your project directory - -h2. Examples - -{code:java} -grails install-templates -{code} - -h2. Description - -Usage: - -{code:java} -grails install-templates -{code} - -Fired Events: - -* @InstallTemplatesStart@ - Before the templates are installed -* @StatusUpdate@ - When the templates are successfully installed -* @InstallTemplatesEnd@ - After the templates have been installed - -The @install-templates@ command will copy the templates Grails uses for all code generation activities to the application's @src/templates@ directory. The templates directories include: - -{code:java} -src - templates - artifacts - scaffolding - war -{code} - -The @artifacts@ directory contains the templates used by the @create-* @ commands. -The @scaffolding@ directory contains templates used by the @generate-* @ commands. -The @war@ directory contains the web.xml template used to generate the deployment descriptor. diff --git a/src/en/ref/Command Line/integrate-with.gdoc b/src/en/ref/Command Line/integrate-with.gdoc deleted file mode 100644 index 01543793780..00000000000 --- a/src/en/ref/Command Line/integrate-with.gdoc +++ /dev/null @@ -1,37 +0,0 @@ -h1. integrate-with - -h2. Purpose - -The @integrate-with@ command allows Grails to be integrated with a variety of IDEs and build systems. - -h2. Examples - -{code} -grails integrate-with --eclipse --intellij --textmate --ant --git -{code} - -h2. Description - -Usage: -{code:java} -grails integrate-with [ARGUMENTS] -{code} - -The @integrate-with@ command will integrate Grails with different IDEs and build systems based on the arguments provided. For example the @\--eclipse@ command will produce @.project@ and @.classpath@ files for use with Eclipse or [Spring Tool Suite (STS)|http://spring.io/tools]. - -The command is extensible. For example to provide a @\--myide@ command, create an @_Events.groovy@ file and handle the @IntegrateWithStart@ event: - -{code} -eventIntegrateWithStart = { - binding.integrateMyide = { - // your code here - } -} -{code} - -Fired Events: - -* @IntegrateWithStart@ - Fired when the script is first run -* @Integrate[NAME]Start@ - Fired when each integration starts (e.g. IntegrateEclipseStart) -* @Integrate[NAME]End@ - Fired when each integration ends (e.g. IntegrateIntellijEnd) -* @IntegrateWithEnd@ - Fired when the script finishes diff --git a/src/en/ref/Command Line/interactive.gdoc b/src/en/ref/Command Line/interactive.gdoc deleted file mode 100644 index bcf281a2bcb..00000000000 --- a/src/en/ref/Command Line/interactive.gdoc +++ /dev/null @@ -1,25 +0,0 @@ -h1. interactive - -h2. Purpose - -The @interactive@ command starts the Grails CLI in interactive mode, but is deprecated since running the @grails@ command without a script name does the same thing. The script will be removed in a future version of Grails. - -h2. Example - -{code} -grails interactive -{code} - -h2. Description - -Usage: -{code} -grails [environment]* interactive -{code} - -Starts the Grails CLI (script runner) in interactive mode. Interactive mode behaves the same as running Grails commands from the command line, but keeps the JVM running in between scripts. A simple command shell allows running and re-running grails commands. - -By keeping the JVM running, interactive mode avoids the (costly) JVM startup time for running successive Grails commands. It also allows the JVM JIT compiler to optimize Grails scripts, so repeated commands will execute more quickly after the initial run. This significantly speeds up repeated runs of unit tests for example. - -See also @shell@ and @console@ commands for ways to interact with a running grails app. - diff --git a/src/en/ref/Command Line/migrate-docs.gdoc b/src/en/ref/Command Line/migrate-docs.gdoc deleted file mode 100644 index 17849b88d22..00000000000 --- a/src/en/ref/Command Line/migrate-docs.gdoc +++ /dev/null @@ -1,33 +0,0 @@ -h1. migrate-docs - -h2. Purpose - -Migrates old style gdocs in which the section numbers are in the file names to the new approach where section numbers and titles are put into a toc.yml file. - -h2. Examples - -{code:java} -grails migrate-docs -{code} - -h2. Description - -Originally, the source files for Grails-generated user guides included the section numbers and titles in the gdoc filenames. This made it very easy to get going, but tricky to renumber sections and change their titles since the corresponding URLs would also change. The @[doc|commandLine]@ command now allows you to specify sections in a table of contents in YAML form, so the guide can be restructured without breaking URLs. - -If you already have a user guide in the old style, then this command will automatically convert the source files to the new format. The gdoc files are created under the directory @src/docs/migratedGuide@ along with: - -* @toc.yml@ - the YAML table of contents file containing the original user guide structure -* @links.yml@ - a map of new section names to old ones (see later for more detail) -* @rewriteRules.txt@ - a simple text file containing the mappings from old HTML filenames to new ones - -The gdoc files themselves are also renamed, with the section numbers removed and the titles converted into Java property notation. This automatic conversion may not always work particularly well, so be prepared to change gdoc the filenames and their corresponding entries in the above files if necessary. For example, - -* 12.1 Welcome to the New World.gdoc - -will become - -* welcomeToTheNewWorld.gdoc - -Once the migration has finished, you can replace the @src/docs/guide@ directory with the contents of @migratedGuide@ and run the @doc@ command. This command is aware of the @links.yml@ file and will use it to add legacy links into the generated documentation so that old HTML fragment identifiers will continue to work. - -Of course, old URLs will break because the names of the HTML files have changed. Hence why the @rewriteRules@ file is created: you can use it to create the appropriate Apache HTTPD rewrite rules or the equivalent for your web server. diff --git a/src/en/ref/Command Line/refresh-dependencies.gdoc b/src/en/ref/Command Line/refresh-dependencies.gdoc deleted file mode 100644 index 781c6b1c208..00000000000 --- a/src/en/ref/Command Line/refresh-dependencies.gdoc +++ /dev/null @@ -1,36 +0,0 @@ -h1. refresh-dependencies - -h2. Purpose - -The @refresh-dependencies@ command refreshes application dependencies and installs any required plugins as necessary. Optionally the command can -generate an XML dependency report. - -h2. Examples - -{code:java} -grails refresh-dependencies -{code} - -{code:java} -grails refresh-dependencies myApplicationDependencies.xml -{code} - -{code:java} -grails refresh-dependencies --include-source myApplicationDependencies.xml -{code} - -Usage: -{code:java} -grails refresh-dependencies [options] [filename] -{code} - -Arguments: - -* @filename@ - The path and name to use for an XML dependency report (optional) -* @\--include-source@ - Include source attachments when doing the refresh (optional) -* @\--include-javadoc@ - Include javadoc attachments when doing the refresh (optional) - - -Fired Events: - -* @StatusFinal@ - After the refresh diff --git a/src/en/ref/Command Line/remove-proxy.gdoc b/src/en/ref/Command Line/remove-proxy.gdoc deleted file mode 100644 index 2c0e72a4530..00000000000 --- a/src/en/ref/Command Line/remove-proxy.gdoc +++ /dev/null @@ -1,24 +0,0 @@ -h1. remove-proxy - -h2. Purpose - -Removes a proxy configuration that Grails can use when communicating over the internet such as with the [install-plugin|commandLine] command. - -Proxy configurations can be added with the [add-proxy|commandLine] command. - -h2. Examples - -{code:java} -grails remove-proxy client -{code} - -h2. Description - -Usage: -{code:java} -grails remove-proxy [name] -{code} - -Arguments: - -* @name@ - The name of the proxy configuration diff --git a/src/en/ref/Command Line/run-script.gdoc b/src/en/ref/Command Line/run-script.gdoc deleted file mode 100644 index 45a0f02b600..00000000000 --- a/src/en/ref/Command Line/run-script.gdoc +++ /dev/null @@ -1,40 +0,0 @@ -h1. run-script - -h2. Purpose - -Runs one or more custom Groovy scripts, bootstrapping the Grails application first. Gant scripts can't directly call application classes since they aren't on the classpath when the script is compiled. You can load them dynamically but this complicates the scripts. - -This script configures the Grails environment, so the Spring application context and Hibernate/GORM are available and you can access the database using domain classes, call service methods, etc. - -In addition, the script(s) run in the context of a Hibernate Session to avoid lazy loading exceptions. - -h2. Examples - -{code:java} -// run a single script in the dev environment -grails run-script userScripts/createBook.groovy -{code} - -{code:java} -// run multiple scripts in the dev environment -grails run-script userScripts/someScript.groovy userScripts/otherScript.groovy -{code} - -{code:java} -// run a single script in the prod environment -grails prod run-script userScripts/updateDatabase.groovy -{code} - -Also see [Ted Naleid's Blog|http://naleid.com/blog/2010/12/03/grails-run-script-updated-for-grails-1-3-5/] for more usage examples. - -h2. Description - -Usage: -{code:java} -grails [environment] run-script [scriptName] -{code} - -Arguments: - -* @environment@ - The environment containing the database configuration to use (dev, prod, etc...). -* @scriptName@ - one or more paths to scripts to run diff --git a/src/en/ref/Command Line/run-war.gdoc b/src/en/ref/Command Line/run-war.gdoc deleted file mode 100644 index 46efaecdd21..00000000000 --- a/src/en/ref/Command Line/run-war.gdoc +++ /dev/null @@ -1,45 +0,0 @@ -h1. run-war - -h2. Purpose - -Packages the current Grails application into a Web Application Archive (WAR) file and runs the application in a Tomcat container on port @8080@ (by default). - -h2. Examples - -{code:java} -grails run-war -grails run-war -https // with HTTPS -grails run-war -restart // restarts without rebuilding the war -grails prod run-war -grails -Dserver.port=8090 run-war -{code} - -h2. Description - -Usage: -{code:java} -grails [env]* run-war -{code} - -{warning} -Unlike the @war@ command, @run-war@ default to the development environment (like most commands). To build and run a WAR file for a different environment just specify the environment name, e.g. @grails prod run-war@. -{warning} - -Arguments: - -* @https@ - Start an HTTPS server (on port 8443 by default) alongside the main server. Just to be clear, the application will be accessible via HTTPS _and_ HTTP. -* @restart@ - Does not rebuild an already existing WAR. - -Supported system properties: - -* @grails.server.port.http@/@server.port@ - Specifies the HTTP port to run the server on (defaults to 8080) -* @grails.server.port.https@ - Specifies the HTTPS port to run the server on (defaults to 8443) -* @grails.server.host@/@server.host@ - Specifies the host name to run the server on (defaults to localhost) -* @grails.tomcat.jvmArgs@ - A list of JVM arguments to be used for the forked JVM, e.g. @\["-Xms128m", "-Xmx512m"\]@ (defaults to @\["-Xmx512m"\]@) - -Fired Events: - -* @StatusFinal@ - When the container has been started -* @StatusUpdate@ - When the container is reloading - -This command packages your application into a WAR file and then runs it in the installed container. It is useful for quick deployment and/or testing. However, unlike [run-app|commandLine] this command does not support reloading as a Grails WAR archive does not ship with Groovy sources, but only compiled byte code. diff --git a/src/en/ref/Command Line/set-grails-version.gdoc b/src/en/ref/Command Line/set-grails-version.gdoc deleted file mode 100644 index 3f1549fa5d4..00000000000 --- a/src/en/ref/Command Line/set-grails-version.gdoc +++ /dev/null @@ -1,37 +0,0 @@ -h1. set-grails-version - -h2. Purpose - -Sets the Grails version inside the application metadata file (@application.properties@) - -h2. Examples - -{code:java} -grails set-grails-version -{code} - -{code:java} -grails set-grails-version 2.4.0 -{code} - -h2. Description - -Usage: -{code:java} -grails set-grails-version [number] -{code} - -The @application.properties@ file in the top level directory of every Grails application contains a @app.grails.version@ property and the value of that property represents the version of Grails required to build that application. The @set-grails-version@ command can be used to set the value of that property. - -Arguments: - -* @number@ - The number to set the Grails version to. If no argument is supplied then the version of Grails which is being used to run the command will be used. - -{note} -All that the @set-grails-version@ command is doing is updating the @app.grails.version@ property in @application.properties@. -{note} - - -Fired Events: - -* @StatusFinal@ - When the version has been set diff --git a/src/en/ref/Command Line/set-proxy.gdoc b/src/en/ref/Command Line/set-proxy.gdoc deleted file mode 100644 index 90dc83602a7..00000000000 --- a/src/en/ref/Command Line/set-proxy.gdoc +++ /dev/null @@ -1,26 +0,0 @@ -h1. set-proxy - -h2. Purpose - -Activates a proxy configuration Grails should use when communicating over the internet such as with the [install-plugin|commandLine] command. - -Proxy configurations are defined using the [add-proxy|commandLine] command - -h2. Examples - -{code:java} -grails add-proxy client --host=proxy-server --port=4300 \ - --username=guest --password=guest -grails set-proxy client -{code} - -h2. Description - -Usage: -{code:java} -grails set-proxy [configuration] -{code} - -Arguments: - -* @configuration@ - The proxy configuration name diff --git a/src/en/ref/Command Line/set-version.gdoc b/src/en/ref/Command Line/set-version.gdoc deleted file mode 100644 index 54908e05941..00000000000 --- a/src/en/ref/Command Line/set-version.gdoc +++ /dev/null @@ -1,24 +0,0 @@ -h1. set-version - -h2. Purpose - -Sets the current application version inside the application metadata file (@application.properties@) - -h2. Examples - -{code:java} -grails set-version 1.6 -{code} - -h2. Description - -Usage: -{code:java} -grails set-version [number] -{code} - -When executing Grails retains metadata about the currently executing application inside the @GrailsApplication@ object. The version of the application is one such item of metadata. The version is used by the Grails [war|commandLine] command to produce a versioned WAR archive and can also be used by the application at runtime to validate application state. - -Fired Events: - -* @StatusFinal@ - When the version has been set diff --git a/src/en/ref/Command Line/stop-app.gdoc b/src/en/ref/Command Line/stop-app.gdoc deleted file mode 100644 index 1414289aa1d..00000000000 --- a/src/en/ref/Command Line/stop-app.gdoc +++ /dev/null @@ -1,19 +0,0 @@ -h1. stop-app - -h2. Purpose - -Stops the Grails container started as a background process using [Forked Mode|guide:forkedMode] - - -h2. Examples - -{code:java} -grails stop-app -{code} - -h2. Description - -Usage: -{code:java} -grails stop-app -{code} diff --git a/src/en/ref/Command Line/uninstall-plugin.gdoc b/src/en/ref/Command Line/uninstall-plugin.gdoc deleted file mode 100644 index 68d39c82d04..00000000000 --- a/src/en/ref/Command Line/uninstall-plugin.gdoc +++ /dev/null @@ -1,20 +0,0 @@ -h1. uninstall-plugin - -h2. Purpose - -Uninstalls an installed plugin from an application. - -h2. Examples - -{code:java} -grails uninstall-plugin shiro -{code} - -h2. Description - -Usage: -{code:java} -grails uninstall-plugin [name] -{code} - -This command will perform a @clean@ and then uninstall the plugin for the given name if it is already installed. The command will remove any metadata referring to the plugin from @application.properties@ and execute the plugin's @scripts/_Uninstall.groovy@ file if it exists. diff --git a/src/en/ref/Command Line/wrapper.gdoc b/src/en/ref/Command Line/wrapper.gdoc deleted file mode 100644 index 92856564fd9..00000000000 --- a/src/en/ref/Command Line/wrapper.gdoc +++ /dev/null @@ -1,32 +0,0 @@ -h1. wrapper - -h2. Purpose - -Generate the Grails wrapper. - -h2. Examples - -{code:java} -grails wrapper --wrapperDir=grailsWrapper -grails wrapper --wrapperDir=grailsWrapper --distributionUrl=http://dist.springframework.org.s3.amazonaws.com/milestone/GRAILS/ -{code} - -{note} -On Windows arguments may need to be quoted, as in... - -grails wrapper "--wrapperDir=grailsWrapper" -{note} - -See the [Wrapper Documentation|guide:wrapper] for more details. - -Arguments: - -* @wrapperDir@ - Directory where wrapper support files are installed relative to project root (defaults to wrapper) -* @distributationUrl@ - URL to the directory where the release may be downloaded from if necessary (defaults to http://dist.springframework.org.s3.amazonaws.com/release/GRAILS/) - -Fired Events: - -* @InstallWrapperStart@ - Start generating the wrapper -* @InstallWrapperEnd@ - Finished generating the wrapper -* @StatusUpdate@ - When the plugin list is being refreshed -* @StatusError@ - When there was an error generating the wrapper From ff2bc893c8342e9a3d910b6ec107ce234b013961 Mon Sep 17 00:00:00 2001 From: Graeme Rocher Date: Fri, 9 Jan 2015 16:35:54 +0100 Subject: [PATCH 027/230] New section on Gradle for the user guide --- src/en/guide/commandLine/gradleBuild.gdoc | 17 ++++++++ .../gradleBuild/gradleDependencies.gdoc | 41 +++++++++++++++++++ .../gradleBuild/gradlePlugins.gdoc | 31 ++++++++++++++ .../commandLine/gradleBuild/gradleTasks.gdoc | 41 +++++++++++++++++++ src/en/guide/introduction.gdoc | 6 +-- .../introduction/whatsNew/coreFeatures.gdoc | 20 +++++++-- .../developmentEnvironmentFeatures.gdoc | 14 ++++++- .../whatsNew/persistenceFeatures.gdoc | 1 - .../whatsNew/testingFeatures.gdoc | 8 +++- .../introduction/whatsNew/webFeatures.gdoc | 1 - src/en/guide/toc.yml | 7 +++- .../Command Line/create-functional-test.gdoc | 31 ++++++++++++++ .../Command Line/create-integration-test.gdoc | 2 - src/en/ref/Command Line/war.gdoc | 12 +----- 14 files changed, 207 insertions(+), 25 deletions(-) create mode 100644 src/en/guide/commandLine/gradleBuild.gdoc create mode 100644 src/en/guide/commandLine/gradleBuild/gradleDependencies.gdoc create mode 100644 src/en/guide/commandLine/gradleBuild/gradlePlugins.gdoc create mode 100644 src/en/guide/commandLine/gradleBuild/gradleTasks.gdoc delete mode 100644 src/en/guide/introduction/whatsNew/persistenceFeatures.gdoc delete mode 100644 src/en/guide/introduction/whatsNew/webFeatures.gdoc create mode 100644 src/en/ref/Command Line/create-functional-test.gdoc diff --git a/src/en/guide/commandLine/gradleBuild.gdoc b/src/en/guide/commandLine/gradleBuild.gdoc new file mode 100644 index 00000000000..98129b79b00 --- /dev/null +++ b/src/en/guide/commandLine/gradleBuild.gdoc @@ -0,0 +1,17 @@ +Grails 3.0 uses the [Gradle Build System|http://gradle.org] for build related tasks such as compilation, runnings tests and producing binary distrubutions of your project. It is recommended to use Gradle 2.2 or above with Grails 3.0. + +The build is defined by the @build.gradle@ file which specifies the version of your project, the dependencies of the project and the repositories where to find those dependencies (amongst other things). + +When you invoke the @grails@ command the version of Gradle that ships with Grails 3.0 (currently 2.3) is invoked by the @grails@ process via the [Gradle Tooling API|http://www.gradle.org/docs/current/userguide/embedding.html]: + +{code} +# Equivalent to 'gradle classes' +$ grails compile +{code} + +You can invoke Gradle directly using the @gradle@ command and use your own local version of Gradle, however you will need Gradle 2.2 or above to work with Grails 3.0: + +{code} +$ gradle assemble +{code} + diff --git a/src/en/guide/commandLine/gradleBuild/gradleDependencies.gdoc b/src/en/guide/commandLine/gradleBuild/gradleDependencies.gdoc new file mode 100644 index 00000000000..15717e4e425 --- /dev/null +++ b/src/en/guide/commandLine/gradleBuild/gradleDependencies.gdoc @@ -0,0 +1,41 @@ +Dependencies for your project are defined in the @dependencies@ block. In general you can follow the [Gradle documentation on dependency management|http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html] to understand how to configure additional dependencies. + +The default dependencies for the "web" profile can be seen below: + +{code} +dependencies { + compile 'org.springframework.boot:spring-boot-starter-logging' + compile("org.springframework.boot:spring-boot-starter-actuator") + compile "org.springframework.boot:spring-boot-autoconfigure" + compile "org.springframework.boot:spring-boot-starter-tomcat" + compile "org.grails:grails-dependencies:$grailsVersion" + compile "org.grails:grails-web-boot:$grailsVersion" + + compile "org.grails.plugins:hibernate" + compile "org.grails.plugins:cache" + compile "org.hibernate:hibernate-ehcache" + + runtime "org.grails.plugins:asset-pipeline" + runtime "org.grails.plugins:scaffolding" + + testCompile "org.grails:grails-plugin-testing" + testCompile "org.grails.plugins:geb" + + // Note: It is recommended to update to a more robust driver (Chrome, Firefox etc.) + testRuntime 'org.seleniumhq.selenium:selenium-htmlunit-driver:2.44.0' + + console "org.grails:grails-console" +} +{code} + +Note that version numbers are not present in the majority of the dependencies. This is thanks to the dependency management plugin which configures a Maven BOM that defines the default dependency versions for certain commonly used dependencies and plugins: + +{code} +dependencyManagement { + imports { + mavenBom "org.grails:grails-bom:$grailsVersion" + } + applyMavenExclusions false +} +{code} + diff --git a/src/en/guide/commandLine/gradleBuild/gradlePlugins.gdoc b/src/en/guide/commandLine/gradleBuild/gradlePlugins.gdoc new file mode 100644 index 00000000000..c01e4d44ab9 --- /dev/null +++ b/src/en/guide/commandLine/gradleBuild/gradlePlugins.gdoc @@ -0,0 +1,31 @@ +When you create a new project with the [create-app|commandLine] command, a default @build.gradle@ is created. The default @build.gradle@ configures the build with a set of Gradle plugins that allow Gradle to build the Grails project: + +{code} +plugins { + id "io.spring.dependency-management" version "0.3.1.RELEASE" +} + +apply plugin: "spring-boot" +apply plugin: "war" +apply plugin: "asset-pipeline" +apply plugin: "org.grails.grails-web" +apply plugin: "org.grails.grails-gsp" +apply plugin: "maven" +{code} + +The default plugins are as follows: + +* @dependency-management@ - The [dependency management|https://plugins.gradle.org/plugin/io.spring.dependency-management] plugin allows Gradle to read Maven BOM files that define the default dependency versions used by Grails. +* @spring-boot@ - The [Spring Boot|http://docs.spring.io/spring-boot/docs/current/reference/html/build-tool-plugins-gradle-plugin.html] Gradle plugin enhances the default packaging tasks provided by Gradle to allow for the creation of runnable JAR/WAR files. +* @war@ - The [WAR plugin|http://www.gradle.org/docs/current/userguide/war_plugin.html] changes the packaging so that Gradle creates as WAR file from you application. You can comment out this plugin if you wish to create only a runnable JAR file for standalone deployment. +* @asset-pipeline@ - The [asset pipeline|https://github.com/bertramdev/asset-pipeline-core] plugin enables the compilation of static assets (JavaScript, CSS etc.) +* @maven@ - The [maven plugin|http://www.gradle.org/docs/current/userguide/maven_plugin.html] allows installing your application into a local maven repository + +Many of these are built in plugins provided by Gradle or third party plugins. The Gradle plugins that Grails provides are as follows: + +* @org.grails.grails-core@ - The primary Grails plugin for Gradle, included by all other plugins and designed to operate with all profiles. +* @org.grails.grails-plugin@ - A plugin for Gradle for building Grails plugins. +* @org.grails.grails-web@ - The Grails Web gradle plugin configures Gradle to understand the Grails conventions and directory structure. +* @org.grails.grails-gsp@ - The Grails GSP plugin adds precompilation of GSP files for production deployments. +* @org.grails.grails-doc@ - A plugin for Gradle for using Grails 2.0's documentation engine. + diff --git a/src/en/guide/commandLine/gradleBuild/gradleTasks.gdoc b/src/en/guide/commandLine/gradleBuild/gradleTasks.gdoc new file mode 100644 index 00000000000..9b15c02ed3b --- /dev/null +++ b/src/en/guide/commandLine/gradleBuild/gradleTasks.gdoc @@ -0,0 +1,41 @@ +As mentioned previously the @grails@ command uses an embedded version of Gradle and certain Grails commands that existed in previous versions of Grails map onto their Gradle equivalents. The following table shows which Grails command invoke which Gradle task: + +{table} + *Grails Command* | *Gradle Task* + clean | clean + compile | classes + package | assemble + run-app | run + test-app | test + war | assemble +{table} + +You can invoke any of these Grails commands using their Gradle equivalents if you prefer: + +{code} +$ gradle test +{code} + +Note however that you will need to use a version of Gradle compatible with Grails 3.0 (Gradle 2.2 or above). If you wish to invoke a Gradle task using the version of Gradle used by Grails you can do so with the @grails@ command: + +{code} +$ grails gradle compileGroovy +{code} + +However, it is recommended you do this via interactive mode, as it greatly speeds up execution and provides TAB completion for the available Gradle tasks: + +{code} +$ grails +| Enter a command name to run. Use TAB for completion: + grails> gradle compileGroovy + ... +{code} + +To find out what Gradle tasks are available without using interactive mode TAB completion you can use the Gradle @tasks@ task: + +{code} +gradle tasks +{code} + + + diff --git a/src/en/guide/introduction.gdoc b/src/en/guide/introduction.gdoc index 57c61907c4f..ce9fd8162a6 100644 --- a/src/en/guide/introduction.gdoc +++ b/src/en/guide/introduction.gdoc @@ -6,13 +6,13 @@ Grails is a full stack framework and attempts to solve as many pieces of the web * An easy to use Object Relational Mapping (ORM) layer built on [Hibernate|http://www.hibernate.org] * An expressive view technology called Groovy Server Pages (GSP) -* A controller layer built on "Spring":http://www.springframework.org MVC -* A command line scripting environment built on the Groovy-powered "Gant":http://groovy.codehaus.org/Gant +* A controller layer built on "Spring":http://www.spring.io MVC +* An interactive command line environment and build system based on "Gradle":http://gradle.org * An embedded "Tomcat":http://tomcat.apache.org container which is configured for on the fly reloading * Dependency injection with the inbuilt Spring container * Support for internationalization (i18n) built on Spring's core MessageSource concept * A transactional service layer built on Spring's transaction abstraction -All of these are made easy to use through the power of the "Groovy":http://groovy.codehaus.org language and the extensive use of Domain Specific Languages (DSLs) +All of these are made easy to use through the power of the "Groovy":http://groovy-lang.org language and the extensive use of Domain Specific Languages (DSLs) This documentation will take you through getting started with Grails and building web applications with the Grails framework. \ No newline at end of file diff --git a/src/en/guide/introduction/whatsNew/coreFeatures.gdoc b/src/en/guide/introduction/whatsNew/coreFeatures.gdoc index 54077a0fe24..440a6122e72 100644 --- a/src/en/guide/introduction/whatsNew/coreFeatures.gdoc +++ b/src/en/guide/introduction/whatsNew/coreFeatures.gdoc @@ -2,8 +2,22 @@ h4. Groovy 2.4 Grails 3.0 comes with Groovy 2.4 which includes many new features and enhancements. -For more information on Groovy 2.3, see the (TBD). +For more information on Groovy 2.4, see the (TBD). -h4. Spring 4.2 +h4. Spring 4.1 and Spring Boot 1.2 -Grails 3.0 comes with Spring 4.2 which includes many new features and enhancements. See the (TBD). +Grails 3.0 comes with Spring 4.1 which includes many new features and enhancements. See the (TBD). + +In addition, Grails 3.0 is built on [Spring Boot|http://projects.spring.io/spring-boot/] which provides the ability to produce runnable JAR files that can embedd Tomcat, Jetty or Undertow containers. + +h4. Gradle Build System + +Grails 3.0 deprecates the older Gant-based build system in favour of a new [Gradle-based|http://gradle.org] build that integrates closely with the [Gradle plugin ecosystem|http://plugins.gradle.org]. + +h4. Application Profiles + +Grails 3.0 supports the notion of application profiles via a new [profile repository|https://github.com/grails/grails-profile-repository]. A profile encapsulates an application structure, set of commands, plugins and capabilities. For example the "web" profile allows construction on web applications deployable to a Servlet container. In the future more profiles will be developed targeting different environments. + +h4. Redesigned API based on Traits + +The Grails API has been redesigned so that public API is correctly populated under the @grails.@ package whilst private / internal API that is subject to change can be found in the @org.grails.@ package. The core API has also been rewritten and based around the [Groovy Traits|http://beta.groovy-lang.org/docs/latest/html/documentation/core-traits.html]. diff --git a/src/en/guide/introduction/whatsNew/developmentEnvironmentFeatures.gdoc b/src/en/guide/introduction/whatsNew/developmentEnvironmentFeatures.gdoc index 2f4f6266cd7..f8c392bbd39 100644 --- a/src/en/guide/introduction/whatsNew/developmentEnvironmentFeatures.gdoc +++ b/src/en/guide/introduction/whatsNew/developmentEnvironmentFeatures.gdoc @@ -1 +1,13 @@ -h4. TBD \ No newline at end of file +h4. New Shell and Code Generation API + +Replacing Gant, Grails 3.0 features a new interactive command line shell that integrates closely with Gradle and provides APIs for writing scripts that interact with Gradle and perform code generation. + +The new shell integrates closely with the concept of application profiles with each profile capable defining [profile specific commands|https://github.com/grails/grails-profile-repository/tree/master/profiles/web/commands]. As with previous versions of Grails, plugins can define new shell commands that can invoke Gradle or perform code generation and project automation tasks. + +h4. Enhanced IDE Integration + +Since Grails 3.0 is built on Gradle, you can now import a Grails project using IntelliJ community edition or GGTS's Gradle tooling support without the need for Grails specific tooling. Grails 3.0 plugins are published as simple JAR files greatly reducing the need for additional IDE support specific to Grails. + +h4. Application Main Class + +Each new Grails 3.0 project featurues an @Application@ class that has a traditional @static void main@ signature, meaning to run or debug a Grails 3.0 application from an IDE like Intellij or GGTS you can simply right-click on the @Application@ class and execute to start your Grails application. All Grails 3.0 tests can also just be run from the IDE directly without needing to resort to the command line (even integration / functional tests!). \ No newline at end of file diff --git a/src/en/guide/introduction/whatsNew/persistenceFeatures.gdoc b/src/en/guide/introduction/whatsNew/persistenceFeatures.gdoc deleted file mode 100644 index 2f4f6266cd7..00000000000 --- a/src/en/guide/introduction/whatsNew/persistenceFeatures.gdoc +++ /dev/null @@ -1 +0,0 @@ -h4. TBD \ No newline at end of file diff --git a/src/en/guide/introduction/whatsNew/testingFeatures.gdoc b/src/en/guide/introduction/whatsNew/testingFeatures.gdoc index 2f4f6266cd7..4d8d3789c7d 100644 --- a/src/en/guide/introduction/whatsNew/testingFeatures.gdoc +++ b/src/en/guide/introduction/whatsNew/testingFeatures.gdoc @@ -1 +1,7 @@ -h4. TBD \ No newline at end of file +h4. Integration and Geb Functional Tests + +Grails 3.0 supports built in support for Spock/Geb functional tests using the [create-functional-test|commandLine] command. Functional tests are based on Spring Boot's test running mechanism and load the application just once for an entire suite of tests. The tests can be run from and IDE and don't require the command line. + +h4. Gradle Test Running + +Since Grails 3.0 is built on Gradle the test execution configuration is much more flexible and can easily configured to execute in parallel. \ No newline at end of file diff --git a/src/en/guide/introduction/whatsNew/webFeatures.gdoc b/src/en/guide/introduction/whatsNew/webFeatures.gdoc deleted file mode 100644 index 2f4f6266cd7..00000000000 --- a/src/en/guide/introduction/whatsNew/webFeatures.gdoc +++ /dev/null @@ -1 +0,0 @@ -h4. TBD \ No newline at end of file diff --git a/src/en/guide/toc.yml b/src/en/guide/toc.yml index 20e795a91cd..a0647ab792e 100644 --- a/src/en/guide/toc.yml +++ b/src/en/guide/toc.yml @@ -4,8 +4,6 @@ introduction: title: What's new in Grails 3.0? coreFeatures: Core Features developmentEnvironmentFeatures: Development Environment Features - webFeatures: Web Features - persistenceFeatures: Persistence Features testingFeatures: Testing Features gettingStarted: title: Getting Started @@ -47,6 +45,11 @@ commandLine: profiles: The Command Line and Profiles creatingCustomScripts: Creating Custom Scripts reusingGrailsScripts: Re-using Grails scripts + gradleBuild: + title: Building with Gradle + gradleDependencies: Defining Dependencies with Gradle + gradleTasks: Working with Gradle Tasks + gradlePlugins: Grails plugins for Gradle GORM: title: Object Relational Mapping (GORM) quickStartGuide: diff --git a/src/en/ref/Command Line/create-functional-test.gdoc b/src/en/ref/Command Line/create-functional-test.gdoc new file mode 100644 index 00000000000..7457820b1fa --- /dev/null +++ b/src/en/ref/Command Line/create-functional-test.gdoc @@ -0,0 +1,31 @@ +h1. create-functional-test + +h2. Purpose + +The @create-functional-test@ command creates a Geb functional test for the given base name. + +h2. Examples + +{code:java} +grails create-functional-test +grails create-functional-test book +grails create-functional-test org.bookstore.Book +{code} + +h2. Description + +Creates an functional test for the given base name. The argument is optional, but if you don't include it the command will ask you for the name of the controller. + +An functional test differs from a unit test in that the Grails environment is loaded for the test execution. Refer to the section on [Unit Testing|guide:testing] of the user guide for information on unit vs. functional testing. + +The name of the test can include a Java package, such as @org.bookstore@ in the final example above, but if one is not provided a default is used. So the second example will create the file @test/integration//BookSpec.groovy@ whereas the last one will create @test/integration/org/bookstore/BookSpec.groovy@ directory. Note that the first letter of the test name is always upper-cased when determining the class name. + +If you want the command to default to a different package for tests, provide a value for @grails.project.groupId@ in the [runtime configuration|guide:config]. + +Note that this command is just for convenience and you can also create functional tests in your favourite text editor or IDE if you choose. + +Usage: +{code:java} +grails create-functional-test [name] +{code} + diff --git a/src/en/ref/Command Line/create-integration-test.gdoc b/src/en/ref/Command Line/create-integration-test.gdoc index a9640337ca7..f0e0cc35299 100644 --- a/src/en/ref/Command Line/create-integration-test.gdoc +++ b/src/en/ref/Command Line/create-integration-test.gdoc @@ -29,6 +29,4 @@ Usage: grails create-integration-test [name] {code} -Fired Events: -* @CreatedFile@ - When the integration test is created diff --git a/src/en/ref/Command Line/war.gdoc b/src/en/ref/Command Line/war.gdoc index 4802bcc541b..a8c9a5d2c5c 100644 --- a/src/en/ref/Command Line/war.gdoc +++ b/src/en/ref/Command Line/war.gdoc @@ -16,17 +16,9 @@ h2. Description Usage: {code:java} -grails [environment]* war [filename]* [arguments]* +grails [environment]* war [arguments]* {code} -Arguments: - -* @filename@ - The path and name to use in place of the default -* @nojars@ - Packages the WAR with no jar files. Used for shared deployment - -Fired Events: - -* @StatusFinal@ - When the WAR file has been created By default the @war@ command creates a web application archive (WAR) file using the application name and version number. The @war@ command is different from most commands since it runs in the production environment by default instead of development, but like any script the environment can be specified using the standard convention: @@ -34,8 +26,6 @@ By default the @war@ command creates a web application archive (WAR) file using grails test war grails dev war grails prod war -grails war /foo/bar/mywar.war -grails war --nojars {code} You can also specify a custom environment: From ff176650af68cce6f1c32743949aa97b52bdbe66 Mon Sep 17 00:00:00 2001 From: Graeme Rocher Date: Fri, 9 Jan 2015 16:47:46 +0100 Subject: [PATCH 028/230] Improve the IDE integration section --- src/en/guide/gettingStarted/ide.gdoc | 37 +++++++++------------------- 1 file changed, 11 insertions(+), 26 deletions(-) diff --git a/src/en/guide/gettingStarted/ide.gdoc b/src/en/guide/gettingStarted/ide.gdoc index 427a3e4780e..172081d3daa 100644 --- a/src/en/guide/gettingStarted/ide.gdoc +++ b/src/en/guide/gettingStarted/ide.gdoc @@ -1,39 +1,24 @@ h4. IntelliJ IDEA -[IntelliJ IDEA|http://www.jetbrains.com/idea] and the [JetGroovy|http://www.jetbrains.net/confluence/display/GRVY/Groovy+Home] plugin offer good support for Groovy and Grails developers. Refer to the section on [Groovy and Grails|http://www.jetbrains.com/idea/features/groovy_grails.html] support on the JetBrains website for a feature overview. +[IntelliJ IDEA|http://www.jetbrains.com/idea] is an excellent IDE for Grails 3.0 development. It comes in 2 editions, the free community edition and the paid-for ultimate edition. -IntelliJ IDEA comes in two flavours; the open source "Community Edition" and the commercial "Ultimate Edition". -Both offers support for Groovy, but only Ultimate Edition offers Grails support. - -With Ultimate Edition, there is no need to use the @grails integrate-with --intellij@ command, as Ultimate Edition understands Grails projects natively. Just open the project with @File -> New Project -> Create project from existing sources@. - -You can still use Community Edition for Grails development, but you will miss out on all the Grails specific features like automatic classpath management, GSP editor and quick access to Grails commands. -To integrate Grails with Community Edition run the following command to generate appropriate project files: - -{code} -grails integrate-with --intellij -{code} +The community edition can be used for most things, although GSP syntax higlighting is only part of the ultimate edition. To get started with Intellij IDEA and Grails 3.0 simply go to @File / Import Project@ and point IDEA at your @build.gradle@ file to import and configure the project. h4. Eclipse -We recommend that users of "Eclipse":http://www.eclipse.org/ looking to develop Grails application take a look at [Groovy/Grails Tool Suite|http://grails.org/products/ggts], which offers built in support for Grails including automatic classpath management, a GSP editor and quick access to Grails commands. See the [STS Integration|http://grails.org/STS+Integration] page for an overview. +We recommend that users of "Eclipse":http://www.eclipse.org/ looking to develop Grails application take a look at [Groovy/Grails Tool Suite|https://spring.io/tools/ggts], which offers built in support for Grails including automatic classpath management, a GSP editor and quick access to Grails commands. + +Like Intellij you can import a Grails 3.0 project using the Gradle project integration. h4. NetBeans NetBeans provides a Groovy/Grails plugin that automatically recognizes Grails projects and provides the ability to run Grails applications in the IDE, code completion and integration with the Glassfish server. For an overview of features see the [NetBeans Integration|http://www.grails.org/NetBeans+Integration] guide on the Grails website which was written by the NetBeans team. -h4. TextMate - -Since Grails' focus is on simplicity it is often possible to utilize more simple editors and "TextMate":http://macromates.com/ on the Mac has an excellent Groovy/Grails bundle available from the [TextMate bundles SVN|http://wiki.macromates.com/Main/SubversionCheckout]. - -To integrate Grails with TextMate run the following command to generate appropriate project files: - -{code} -grails integrate-with --textmate -{code} +h4. TextMate, Sublime, VIM etc. -Alternatively TextMate can easily open any project with its command line integration by issuing the following command from the root of your project: +There are several excellent text editors that work nicely with Groovy and Grails. See below for references: -{code} -mate . -{code} +* A [TextMate bundle|https://github.com/textmate/groovy-grails.tmbundle] exists Groovy / Grails support in [Textmate|http://macromates.com] +* A [Sublime Text plugin|https://github.com/osoco/sublimetext-grails] can be installed via Sublime Package Control for the [Sublime Text Editor|http://www.sublimetext.com]. +* See [this post|http://www.objectpartners.com/2012/02/21/using-vim-as-your-grails-ide-part-1-navigating-your-project/] for some helpful tips on how to setup VIM as your Grails editor of choise. +* An [Atom Package|https://atom.io/packages/atom-grails] is available for use with the [Atom editor|https://atom.io] \ No newline at end of file From df0de89322d87fc0646e0d95f40e3fc6673010da Mon Sep 17 00:00:00 2001 From: Graeme Rocher Date: Fri, 9 Jan 2015 17:21:33 +0100 Subject: [PATCH 029/230] fix indentation --- src/en/guide/conf/config/configGORM.gdoc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/en/guide/conf/config/configGORM.gdoc b/src/en/guide/conf/config/configGORM.gdoc index de4b161036c..3441332c61c 100644 --- a/src/en/guide/conf/config/configGORM.gdoc +++ b/src/en/guide/conf/config/configGORM.gdoc @@ -5,18 +5,18 @@ Grails provides the following GORM configuration options: For example, to enable failOnError for all domain classes: {code:java} grails: - gorm: - failOnError: true + gorm: + failOnError: true {code} and to enable failOnError for domain classes by package: {code:java} grails: - gorm: - failOnError: - - com.companyname.somepackage - - com.companyname.someotherpackage + gorm: + failOnError: + - com.companyname.somepackage + - com.companyname.someotherpackage {code} -* @grails.gorm.autoFlush@ = If set to @true@, causes the [merge|domainClasses], [save|domainClasses] and [delete|domainClasses] methods to flush the session, replacing the need to explicitly flush using @save(flush: true)@. +* @grails.gorm.autoFlush@ - If set to @true@, causes the [merge|domainClasses], [save|domainClasses] and [delete|domainClasses] methods to flush the session, replacing the need to explicitly flush using @save(flush: true)@. From 0ec6b73702a1dc1ed5aecd75baf06b364e676d16 Mon Sep 17 00:00:00 2001 From: Graeme Rocher Date: Wed, 21 Jan 2015 15:51:44 +0100 Subject: [PATCH 030/230] Initial cut of Travis integration --- .travis.yml | 10 ++++++++++ build.gradle | 12 +++++++----- travis-build.sh | 52 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 69 insertions(+), 5 deletions(-) create mode 100644 .travis.yml create mode 100755 travis-build.sh diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000000..4733794a287 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,10 @@ +script: ./travis-build.sh +jdk: +- openjdk7 +env: + global: + - GIT_NAME="Graeme Rocher" + - GIT_EMAIL="graeme.rocher@gmail.com" + env: + global: + secure: qdIkgqH7+I+A0rSjXLWJnVb1qtWkmd2SfFwSzchpEhYpKC0TtfvxsfqBaCha95L926YZna050tWkC9Fq33prxsyInqd4VRsPuNgp3KEsW+4sUd5LhDW6Y5luCFkB/RStMXSSuUv7NHxmjG6dsg4A/lV53tWv1xMhNZknTmYDBEM= diff --git a/build.gradle b/build.gradle index b68991f188f..f29f8fc85dd 100644 --- a/build.gradle +++ b/build.gradle @@ -22,7 +22,7 @@ buildscript { } dependencies { - classpath "org.grails:grails-docs:2.4.4.BUILD-SNAPSHOT" + classpath "org.grails:grails-docs:2.4.4" classpath 'org.codehaus.groovy:groovy-all:2.3.0' } } @@ -47,15 +47,17 @@ task fetchGrailsSource << { mapper type: "regexp", from: "(grails-grails-core-\\S*?/)(.*)", to: "grails-src/\\2" } + ant.chmod(file:"${checkOutDir}/grails-src/gradlew", perm:700) + println "Grails source code has been downloaded to ${relativePath(grailsHome)}" } fetchGrailsSource.onlyIf { !explicitGrailsHome } -task apiDocs(type: GradleBuild, dependsOn: 'fetchGrailsSource') { - tasks = ["groovydoc"] - buildFile = "${project.grailsHome}/build.gradle" - startParameter.excludedTaskNames = ['compileGroovy', 'compileUaaGroovy', 'compileJsp21Groovy', 'compileAstGroovy', 'jar'] +task apiDocs(type: Exec, dependsOn: 'fetchGrailsSource') { + commandLine = ["./gradlew", "groovydoc"] + workingDir = "${checkOutDir}/grails-src" + } apiDocs.onlyIf { !System.getProperty("disable.groovydocs") } diff --git a/travis-build.sh b/travis-build.sh new file mode 100755 index 00000000000..4679a3bd848 --- /dev/null +++ b/travis-build.sh @@ -0,0 +1,52 @@ +#!/bin/bash +set -e + +git config --global user.name "$GIT_NAME" +git config --global user.email "$GIT_EMAIL" +git config --global credential.helper "store --file=~/.git-credentials" +echo "https://$GH_TOKEN:@github.com" > ~/.git-credentials + + +./gradlew assemble + +if [[ $TRAVIS_PULL_REQUEST == 'false' ]]; then + + git clone https://${GH_TOKEN}@github.com/grails/grails-doc.git -b gh-pages gh-pages --single-branch > /dev/null + cd gh-pages + + # If this is the master branch then update the snapshot + if [[ $TRAVIS_BRANCH == 'master' ]]; then + mkdir -p snapshot + cp -r ../build/docs/. ./snapshot/ + + git add snapshot/* + + # If there is a tag present then this becomes the latest + if [[ -n $TRAVIS_TAG ]]; then + git rm -rf latest/ + mkdir -p latest + cp -r ../build/docs/. ./latest/ + git add latest/* + + version="$TRAVIS_TAG" + version=${version:1} + majorVersion=${version:0:4} + majorVersion="${majorVersion}x" + + mkdir -p "$version" + cp -r ../build/docs/. "./$version/" + git add "$version/*" + + mkdir -p "$majorVersion" + cp -r ../build/docs/. "./$majorVersion/" + git add "$majorVersion/*" + + fi + + git commit -a -m "Updating docs for Travis build: https://travis-ci.org/$TRAVIS_REPO_SLUG/builds/$TRAVIS_BUILD_ID" + git push origin HEAD + cd .. + rm -rf gh-pages + + fi +fi From 7b5928c77bb753089589cfdaad6392baab5ff19f Mon Sep 17 00:00:00 2001 From: graemerocher Date: Wed, 21 Jan 2015 15:54:44 +0100 Subject: [PATCH 031/230] Update README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 4bd1bcc4da0..dd54a9d637c 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,10 @@ Building the Guide To build the documentation, simply type: ./gradlew docs + +This will take some time as it generates groovydoc for the Grails sources. If you want to just generate the user guide to preview your change you can do: + + ./gradlew -Ddisable.groovydocs=true docs Be warned: this command can take a while to complete and you should probably increase your Gradle memory settings by giving the `GRADLE_OPTS` environment variable a value like From c9ce2318704af20a705c261d1a5a8d094a5df725 Mon Sep 17 00:00:00 2001 From: Graeme Rocher Date: Wed, 21 Jan 2015 15:58:37 +0100 Subject: [PATCH 032/230] fix token --- .travis.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4733794a287..2d2803eb81e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,6 +5,4 @@ env: global: - GIT_NAME="Graeme Rocher" - GIT_EMAIL="graeme.rocher@gmail.com" - env: - global: - secure: qdIkgqH7+I+A0rSjXLWJnVb1qtWkmd2SfFwSzchpEhYpKC0TtfvxsfqBaCha95L926YZna050tWkC9Fq33prxsyInqd4VRsPuNgp3KEsW+4sUd5LhDW6Y5luCFkB/RStMXSSuUv7NHxmjG6dsg4A/lV53tWv1xMhNZknTmYDBEM= + - secure: SdGzn2ItEkM0UGzByv/0yXLO7g9iJYmrSIgQ3a1yZXvOerQOLuOwwTZIJ4LUBJpJcQRhiAff1HidN/6fAGAd4mwgoQcX1kKdrRHIl0oG7V7DC9YRytPko/gasQ6aPoR3GBBpLqx8hIjGYbVKIrPWgMSRRA7DSvbzI5XlOgAX1Dg= From 83d8ae1d60560b2e945237069b6f3719a9fd5136 Mon Sep 17 00:00:00 2001 From: Graeme Rocher Date: Wed, 21 Jan 2015 16:17:12 +0100 Subject: [PATCH 033/230] tweak GRADLE_OPTS --- travis-build.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/travis-build.sh b/travis-build.sh index 4679a3bd848..775d112c74c 100755 --- a/travis-build.sh +++ b/travis-build.sh @@ -6,6 +6,7 @@ git config --global user.email "$GIT_EMAIL" git config --global credential.helper "store --file=~/.git-credentials" echo "https://$GH_TOKEN:@github.com" > ~/.git-credentials +export GRADLE_OPTS="-Xmx2048m -Xms256m -XX:MaxPermSize=512m -XX:+CMSClassUnloadingEnabled -XX:+HeapDumpOnOutOfMemoryError" ./gradlew assemble From b99cec1bb5ac6aab6fd7efd43505f851deb512fd Mon Sep 17 00:00:00 2001 From: Jeff Scott Brown Date: Sat, 24 Jan 2015 19:39:17 -0600 Subject: [PATCH 034/230] Validateable trait has moved --- src/en/guide/testing/unitTesting/unitTestingDomains.gdoc | 2 +- src/en/guide/theWebLayer/controllers/commandObjects.gdoc | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/en/guide/testing/unitTesting/unitTestingDomains.gdoc b/src/en/guide/testing/unitTesting/unitTestingDomains.gdoc index 1eeaa070f68..01a9e2f8188 100644 --- a/src/en/guide/testing/unitTesting/unitTestingDomains.gdoc +++ b/src/en/guide/testing/unitTesting/unitTestingDomains.gdoc @@ -167,7 +167,7 @@ These are all easily testable in a unit test with no special configuration neces // src/groovy/com/demo/MyValidateable.groovy package com.demo -class MyValidateable implements grails.validation.trait.Validateable { +class MyValidateable implements grails.validation.Validateable { String name Integer age diff --git a/src/en/guide/theWebLayer/controllers/commandObjects.gdoc b/src/en/guide/theWebLayer/controllers/commandObjects.gdoc index bd5a4918b37..18d44e246cc 100644 --- a/src/en/guide/theWebLayer/controllers/commandObjects.gdoc +++ b/src/en/guide/theWebLayer/controllers/commandObjects.gdoc @@ -9,7 +9,7 @@ h4. Declaring Command Objects Command object classes are defined just like any other class. {code:java} -class LoginCommand implements grails.validation.trait.Validateable { +class LoginCommand implements grails.validation.Validateable { String username String password @@ -25,7 +25,7 @@ In this example, the command object class implements the @Validateable@ trait. T By default, all @Validateable@ object properties are @nullable: false@ which matches the behavior of GORM domain objects. If you want a @Validateable@ that has @nullable: true@ properties by default, you can specify this by defining a @defaultNullable@ method in the class: {code:java} -class AuthorSearchCommand implements grails.validation.trait.Validateable { +class AuthorSearchCommand implements grails.validation.Validateable { String name Integer age @@ -133,7 +133,7 @@ h4. Command Objects and Dependency Injection Command objects can participate in dependency injection. This is useful if your command object has some custom validation logic which uses a Grails [service|guide:services]: {code} -class LoginCommand implements grails.validation.trait.Validateable { +class LoginCommand implements grails.validation.Validateable { def loginService From 239b156ecb375c055aca5d08dcf77020e9f84611 Mon Sep 17 00:00:00 2001 From: Graeme Rocher Date: Wed, 28 Jan 2015 13:56:30 +0100 Subject: [PATCH 035/230] Setup travis build to handle tagged releases --- .travis.yml | 12 ++++++++++++ travis-build.sh | 52 ++++++++++++++++++++++++++++++------------------- 2 files changed, 44 insertions(+), 20 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2d2803eb81e..d7ce7e5a72d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,6 @@ script: ./travis-build.sh +before_script: +- go get github.com/aktau/github-release jdk: - openjdk7 env: @@ -6,3 +8,13 @@ env: - GIT_NAME="Graeme Rocher" - GIT_EMAIL="graeme.rocher@gmail.com" - secure: SdGzn2ItEkM0UGzByv/0yXLO7g9iJYmrSIgQ3a1yZXvOerQOLuOwwTZIJ4LUBJpJcQRhiAff1HidN/6fAGAd4mwgoQcX1kKdrRHIl0oG7V7DC9YRytPko/gasQ6aPoR3GBBpLqx8hIjGYbVKIrPWgMSRRA7DSvbzI5XlOgAX1Dg= + - secure: R9aL92lh09LniCTbiZuuikiWHXL4ik/DDAKe7NLanqpI126vs5Y9zd56JifgN8Mp7sEbwlaM4RzFXpgkdl57FZqdDzC04ljeqy9Z4CmGthUCF2o2exV98HFWxrL6J18OH5zVSBtZJN0ANcgdJ3/+vMuk2wyS61qhl36uiUM66tM= +deploy: + provider: releases + api_key: + secure: OXqyhH6/rK9rmiApnm+8smg/+rjdM3T28/4ZUzbdibYZNSagVAMniDgndZIwt198jDvAPxf9jadN1G3OD5BLkW0wUWvAfYAtxAwOe6dzgcsMavdTxoBJnjXBc4XqFXSDhWTO4cd4vQ5Wx6cyvbUY5xgyREpvEP7oRUgQ0RJo9q8= + file: build/distributions/$RELEASE_FILE + skip_cleanup: true + on: + repo: grails/grails-doc + tags: true diff --git a/travis-build.sh b/travis-build.sh index 775d112c74c..45a44fecca8 100755 --- a/travis-build.sh +++ b/travis-build.sh @@ -12,7 +12,7 @@ export GRADLE_OPTS="-Xmx2048m -Xms256m -XX:MaxPermSize=512m -XX:+CMSClassUnloadi if [[ $TRAVIS_PULL_REQUEST == 'false' ]]; then - git clone https://${GH_TOKEN}@github.com/grails/grails-doc.git -b gh-pages gh-pages --single-branch > /dev/null + git clone https://${GH_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git -b gh-pages gh-pages --single-branch > /dev/null cd gh-pages # If this is the master branch then update the snapshot @@ -21,33 +21,45 @@ if [[ $TRAVIS_PULL_REQUEST == 'false' ]]; then cp -r ../build/docs/. ./snapshot/ git add snapshot/* + fi + # If there is a tag present then this becomes the latest + if [[ -n $TRAVIS_TAG ]]; then + version="$TRAVIS_TAG" + version=${version:1} + zipName="grails-docs-$version" + export RELEASE_FILE="${zipName}.zip" + + github-release upload \ + --user grails \ + --repo grails-core \ + --tag $TRAVIS_TAG \ + --name "grails-docs-${version}.zip" \ + --file "build/distributions/$RELEASE_FILE" + - # If there is a tag present then this becomes the latest - if [[ -n $TRAVIS_TAG ]]; then + milestone=${version:5} + if [[ -n $milestone ]]; then git rm -rf latest/ mkdir -p latest cp -r ../build/docs/. ./latest/ git add latest/* + fi - version="$TRAVIS_TAG" - version=${version:1} - majorVersion=${version:0:4} - majorVersion="${majorVersion}x" + majorVersion=${version:0:4} + majorVersion="${majorVersion}x" - mkdir -p "$version" - cp -r ../build/docs/. "./$version/" - git add "$version/*" + mkdir -p "$version" + cp -r ../build/docs/. "./$version/" + git add "$version/*" - mkdir -p "$majorVersion" - cp -r ../build/docs/. "./$majorVersion/" - git add "$majorVersion/*" + mkdir -p "$majorVersion" + cp -r ../build/docs/. "./$majorVersion/" + git add "$majorVersion/*" - fi + fi - git commit -a -m "Updating docs for Travis build: https://travis-ci.org/$TRAVIS_REPO_SLUG/builds/$TRAVIS_BUILD_ID" - git push origin HEAD - cd .. - rm -rf gh-pages - - fi + git commit -a -m "Updating docs for Travis build: https://travis-ci.org/$TRAVIS_REPO_SLUG/builds/$TRAVIS_BUILD_ID" + git push origin HEAD + cd .. + rm -rf gh-pages fi From 590db235c6fd311323e1215208e43fe575680606 Mon Sep 17 00:00:00 2001 From: Graeme Rocher Date: Wed, 28 Jan 2015 21:08:41 +0100 Subject: [PATCH 036/230] Release 3.0.0.M1 --- build.gradle | 4 ++-- resources/doc.properties | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index f29f8fc85dd..d2e26b3116b 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,6 @@ apply plugin: "base" -version = System.getProperty("grails.version") ?: "3.0.0.BUILD-SNAPSHOT" +version = System.getProperty("grails.version") ?: "3.0.0.M1" archivesBaseName = "grails-docs" @@ -57,7 +57,7 @@ fetchGrailsSource.onlyIf { !explicitGrailsHome } task apiDocs(type: Exec, dependsOn: 'fetchGrailsSource') { commandLine = ["./gradlew", "groovydoc"] workingDir = "${checkOutDir}/grails-src" - + } apiDocs.onlyIf { !System.getProperty("disable.groovydocs") } diff --git a/resources/doc.properties b/resources/doc.properties index dfea64f9d61..21039863f03 100644 --- a/resources/doc.properties +++ b/resources/doc.properties @@ -2,7 +2,6 @@ title=The Grails Framework subtitle=See the light - agile, industrial strength, rapid web application development made easy authors=Graeme Rocher, Peter Ledbrook, Marc Palmer, Jeff Brown, Luke Daley, Burt Beckwith, Lari Hotari copyright=Copies of this document may be made for your own use and for distribution to others, provided that you do not charge any fee for such copies and further provided that each copy contains this Copyright Notice, whether distributed in print or electronically. -footer=Sponsored by Pivotal # aliases are used in links to bind to a more specific topic name such as [GSP|guide:gsp] alias.resources=6.2.5 Static Resources alias.ajax=6.7 Ajax From b45030c18bf903228c9e92ffcb96236f6d1da553 Mon Sep 17 00:00:00 2001 From: Graeme Rocher Date: Thu, 29 Jan 2015 08:19:31 +0100 Subject: [PATCH 037/230] Release 3.0.0.M1 --- travis-build.sh | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/travis-build.sh b/travis-build.sh index 45a44fecca8..ab6e8bc158a 100755 --- a/travis-build.sh +++ b/travis-build.sh @@ -8,7 +8,7 @@ echo "https://$GH_TOKEN:@github.com" > ~/.git-credentials export GRADLE_OPTS="-Xmx2048m -Xms256m -XX:MaxPermSize=512m -XX:+CMSClassUnloadingEnabled -XX:+HeapDumpOnOutOfMemoryError" -./gradlew assemble +./gradlew assemble if [[ $TRAVIS_PULL_REQUEST == 'false' ]]; then @@ -26,18 +26,12 @@ if [[ $TRAVIS_PULL_REQUEST == 'false' ]]; then if [[ -n $TRAVIS_TAG ]]; then version="$TRAVIS_TAG" version=${version:1} - zipName="grails-docs-$version" - export RELEASE_FILE="${zipName}.zip" + zipName="grails-docs-$version" + export RELEASE_FILE="${zipName}.zip" - github-release upload \ - --user grails \ - --repo grails-core \ - --tag $TRAVIS_TAG \ - --name "grails-docs-${version}.zip" \ - --file "build/distributions/$RELEASE_FILE" +# github-release upload --user grails --repo grails-core --tag $TRAVIS_TAG --name grails-docs-${version}.zip --file build/distributions/$RELEASE_FILE - - milestone=${version:5} + milestone=${version:5} if [[ -n $milestone ]]; then git rm -rf latest/ mkdir -p latest @@ -50,16 +44,16 @@ if [[ $TRAVIS_PULL_REQUEST == 'false' ]]; then mkdir -p "$version" cp -r ../build/docs/. "./$version/" - git add "$version/*" + git add "$version/*" mkdir -p "$majorVersion" cp -r ../build/docs/. "./$majorVersion/" - git add "$majorVersion/*" + git add "$majorVersion/*" - fi + fi git commit -a -m "Updating docs for Travis build: https://travis-ci.org/$TRAVIS_REPO_SLUG/builds/$TRAVIS_BUILD_ID" git push origin HEAD cd .. - rm -rf gh-pages + rm -rf gh-pages fi From 05c645b66d6771f7486bea4855f632745e3ccb96 Mon Sep 17 00:00:00 2001 From: Graeme Rocher Date: Thu, 29 Jan 2015 08:59:22 +0100 Subject: [PATCH 038/230] Deploy all branches --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index d7ce7e5a72d..f5e288f2b58 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,3 +18,4 @@ deploy: on: repo: grails/grails-doc tags: true + all_branches: true From dc075d6f82a33d96bd4ffcec5be03abd224bb711 Mon Sep 17 00:00:00 2001 From: Graeme Rocher Date: Thu, 29 Jan 2015 10:31:06 +0100 Subject: [PATCH 039/230] Upgrade to grails-doc 3.0.0.M1 --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index d2e26b3116b..30238b500e8 100644 --- a/build.gradle +++ b/build.gradle @@ -22,8 +22,8 @@ buildscript { } dependencies { - classpath "org.grails:grails-docs:2.4.4" - classpath 'org.codehaus.groovy:groovy-all:2.3.0' + classpath "org.grails:grails-docs:3.0.0.M1" + classpath 'org.codehaus.groovy:groovy-all:2.4.0' } } From be000be06564efae6a6c99c8bab45c7951aacb8c Mon Sep 17 00:00:00 2001 From: Ken Geis Date: Mon, 2 Feb 2015 12:04:02 -0800 Subject: [PATCH 040/230] fix typo --- src/en/guide/introduction/whatsNew/coreFeatures.gdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/en/guide/introduction/whatsNew/coreFeatures.gdoc b/src/en/guide/introduction/whatsNew/coreFeatures.gdoc index 440a6122e72..586cd2dde81 100644 --- a/src/en/guide/introduction/whatsNew/coreFeatures.gdoc +++ b/src/en/guide/introduction/whatsNew/coreFeatures.gdoc @@ -8,7 +8,7 @@ h4. Spring 4.1 and Spring Boot 1.2 Grails 3.0 comes with Spring 4.1 which includes many new features and enhancements. See the (TBD). -In addition, Grails 3.0 is built on [Spring Boot|http://projects.spring.io/spring-boot/] which provides the ability to produce runnable JAR files that can embedd Tomcat, Jetty or Undertow containers. +In addition, Grails 3.0 is built on [Spring Boot|http://projects.spring.io/spring-boot/] which provides the ability to produce runnable JAR files that can embed Tomcat, Jetty or Undertow containers. h4. Gradle Build System From 214f551c25cac114c23217df6bbeed7f9c6940a4 Mon Sep 17 00:00:00 2001 From: Ken Geis Date: Mon, 2 Feb 2015 12:05:29 -0800 Subject: [PATCH 041/230] fix typos --- .../introduction/whatsNew/developmentEnvironmentFeatures.gdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/en/guide/introduction/whatsNew/developmentEnvironmentFeatures.gdoc b/src/en/guide/introduction/whatsNew/developmentEnvironmentFeatures.gdoc index f8c392bbd39..7ceae47a052 100644 --- a/src/en/guide/introduction/whatsNew/developmentEnvironmentFeatures.gdoc +++ b/src/en/guide/introduction/whatsNew/developmentEnvironmentFeatures.gdoc @@ -10,4 +10,4 @@ Since Grails 3.0 is built on Gradle, you can now import a Grails project using I h4. Application Main Class -Each new Grails 3.0 project featurues an @Application@ class that has a traditional @static void main@ signature, meaning to run or debug a Grails 3.0 application from an IDE like Intellij or GGTS you can simply right-click on the @Application@ class and execute to start your Grails application. All Grails 3.0 tests can also just be run from the IDE directly without needing to resort to the command line (even integration / functional tests!). \ No newline at end of file +Each new Grails 3.0 project features an @Application@ class that has a traditional @static void main@ signature, meaning to run or debug a Grails 3.0 application from an IDE like IntelliJ or GGTS you can simply right-click on the @Application@ class and execute to start your Grails application. All Grails 3.0 tests can also just be run from the IDE directly without needing to resort to the command line (even integration / functional tests!). From a6fef8961c97c446870bdaa6e407a69592824214 Mon Sep 17 00:00:00 2001 From: Jeff Scott Brown Date: Mon, 2 Feb 2015 21:02:07 -0600 Subject: [PATCH 042/230] GRAILS-11712 - clarify now empty id params are handled --- src/en/guide/theWebLayer/controllers/commandObjects.gdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/en/guide/theWebLayer/controllers/commandObjects.gdoc b/src/en/guide/theWebLayer/controllers/commandObjects.gdoc index 18d44e246cc..69a8cc5e304 100644 --- a/src/en/guide/theWebLayer/controllers/commandObjects.gdoc +++ b/src/en/guide/theWebLayer/controllers/commandObjects.gdoc @@ -57,7 +57,7 @@ class LoginController { } {code} -If the command object's type is that of a domain class and there is an @id@ request parameter then instead of invoking the domain class constructor to create a new instance a call will be made to the static @get@ method on the domain class and the value of the @id@ parameter will be passed as an argument. Whatever is returned from that call to @get@ is what will be passed into the controller action. This means that if there is an @id@ request parameter and no corresponding record is found in the database then the value of the command object will be @null@. If an error occurs retrieving the instance from the database then @null@ will be passed as an argument to the controller action and an error will be added the controller's @errors@ property. If the command object's type is a domain class and there is no @id@ request parameter then @null@ will be passed into the controller action unless the HTTP request method is "POST", in which case a new instance of the domain class will be created by invoking the domain class constructor. For all of the cases where the domain class instance is non-null, data binding is only performed if the HTTP request method is "POST", "PUT" or "PATCH". +If the command object's type is that of a domain class and there is an @id@ request parameter then instead of invoking the domain class constructor to create a new instance a call will be made to the static @get@ method on the domain class and the value of the @id@ parameter will be passed as an argument. Whatever is returned from that call to @get@ is what will be passed into the controller action. This means that if there is an @id@ request parameter and no corresponding record is found in the database then the value of the command object will be @null@. If an error occurs retrieving the instance from the database then @null@ will be passed as an argument to the controller action and an error will be added the controller's @errors@ property. If the command object's type is a domain class and there is no @id@ request parameter or there is an @id@ request parameter and its value is empty then @null@ will be passed into the controller action unless the HTTP request method is "POST", in which case a new instance of the domain class will be created by invoking the domain class constructor. For all of the cases where the domain class instance is non-null, data binding is only performed if the HTTP request method is "POST", "PUT" or "PATCH". h4. Command Objects And Request Parameter Names From b1a014c1e5087442c99d79e9ba79a11e401b4e63 Mon Sep 17 00:00:00 2001 From: Graeme Rocher Date: Thu, 5 Feb 2015 11:35:41 +0100 Subject: [PATCH 043/230] fix broken link --- src/en/guide/gettingStarted/creatingArtefacts.gdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/en/guide/gettingStarted/creatingArtefacts.gdoc b/src/en/guide/gettingStarted/creatingArtefacts.gdoc index 10e965cd886..7ddeb545354 100644 --- a/src/en/guide/gettingStarted/creatingArtefacts.gdoc +++ b/src/en/guide/gettingStarted/creatingArtefacts.gdoc @@ -22,5 +22,5 @@ class Book { There are many such @create-*@ commands that can be explored in the command line reference guide. {note} -To decrease the amount of time it takes to run Grails scripts, use the [interactive|commandLine] mode. +To decrease the amount of time it takes to run Grails scripts, use the interactive mode. {note} From bee5fa3f753bde5cbdf3ec6dc9db28902131bb12 Mon Sep 17 00:00:00 2001 From: Graeme Rocher Date: Thu, 5 Feb 2015 11:45:58 +0100 Subject: [PATCH 044/230] add content about new functional testing features --- src/en/guide/testing/functionalTesting.gdoc | 67 +++++++-------------- 1 file changed, 21 insertions(+), 46 deletions(-) diff --git a/src/en/guide/testing/functionalTesting.gdoc b/src/en/guide/testing/functionalTesting.gdoc index fed67610e6e..2d08f421d1e 100644 --- a/src/en/guide/testing/functionalTesting.gdoc +++ b/src/en/guide/testing/functionalTesting.gdoc @@ -1,61 +1,36 @@ Functional tests involve making HTTP requests against the running application and verifying the resultant behaviour. The functional testing phase differs from the integration phase in that the Grails application is now listening and responding to actual HTTP requests. This is useful for end-to-end testing scenarios, such as making REST calls against a JSON API. -Grails does not ship with any support for writing functional tests directly, but there are several plugins available for this. +Grails by default ships with support for writing functional tests using the [Geb framework|http://www.gebish.org]. To create a functional test you can use the @create-functional-test@ command which will create a new functional test: -* @Canoo Webtest@ - "http://grails.org/plugin/webtest":http://grails.org/plugin/webtest -* @G-Func@ - "http://grails.org/plugin/functional-test":http://grails.org/plugin/functional-test -* @Geb@ - "http://grails.org/plugin/geb":http://grails.org/plugin/geb -* @Selenium-RC@ - "http://grails.org/plugin/selenium-rc":http://grails.org/plugin/selenium-rc -* @WebDriver@ - "http://grails.org/plugin/webdriver":http://grails.org/plugin/webdriver - -Consult the documentation for each plugin for its capabilities. - -h4. Common Options - -There are options that are common to all plugins that control how the Grails application is launched, if at all. - -h5. inline - -The @-inline@ option specifies that the grails application should be started inline (i.e. like @run-app@). - -*This option is implicitly set unless the @baseUrl@ or @war@ options are set* - -h5. war - -The @-war@ option specifies that the grails application should be packaged as a war and started. This is useful as it tests your application in a production-like state, but it has a longer startup time than the @-inline@ option. It also runs the war in a forked JVM, meaning that you cannot access any internal application objects. - -{code:java} -grails test-app functional: -war +{code} +$ grails create-functional-test MyFunctional {code} -Note that the same build/config options for the [run-war|commandLine] command apply to functional testing against the WAR. - -h5. https - -The @-https@ option results in the application being able to receive https requests as well as http requests. It is compatible with both the @-inline@ and @-war@ options. +The above command will create a new Spock spec called @MyFunctionalSpec.groovy@ in the @src/test/groovy@ directory. The test is annotated with the [Integration|api:grails.test.mixin.integration.Integration] annotation to indicate it is a integration test and extends the @GebSpec@ super class: -{code:java} -grails test-app functional: -https {code} +@Integration +class HomeSpec extends GebSpec { -Note that this does not change the test _base url_ to be https, it will still be http unless the @-httpsBaseUrl@ option is also given. + def setup() { + } -h5. httpsBaseUrl + def cleanup() { + } -The @-httpsBaseUrl@ causes the implicit base url to be used for tests to be a https url. + void "Test the home page renders correctly"() { + when:"The home page is visited" + go '/' -{code:java} -grails test-app functional: -httpsBaseUrl -{code} - -This option is ignored if the @-baseUrl@ option is specified. + then:"The title is correct" + $('title').text() == "Welcome to Grails" + } +} -h5. baseUrl +{code} -The @baseUrl@ option allows the base url for tests to be specified. +When the test is run the application container will be loaded up in the background and you can send requests to the running application using the Geb API. -{code:java} -grails test-app functional: -baseUrl=http://mycompany.com/grailsapp -{code} +Note that the application is only loaded once for the entire test run, so functional tests share the state of the application across the whole suite. -This option will prevent the local grails application being started unless @-inline@ or @-war@ are given as well. To use a custom base url but still test against the local Grails application you *must* specify one of either the @-inline@ or @-war@ options. +In addition the application is loaded in the JVM as the test, this means that the test has full access to the application state and can interact directly with data services such as GORM to setup and cleanup test data. From 556c5113e492e0f1cb27557073a668b0585d692c Mon Sep 17 00:00:00 2001 From: Graeme Rocher Date: Thu, 5 Feb 2015 11:46:12 +0100 Subject: [PATCH 045/230] Remove redundant content on plugin publishing --- src/en/guide/plugins/repositories.gdoc | 74 +------------------------- 1 file changed, 1 insertion(+), 73 deletions(-) diff --git a/src/en/guide/plugins/repositories.gdoc b/src/en/guide/plugins/repositories.gdoc index 35569563183..d446c3c2186 100644 --- a/src/en/guide/plugins/repositories.gdoc +++ b/src/en/guide/plugins/repositories.gdoc @@ -15,77 +15,5 @@ grails plugin-info [plugin-name] which prints extra information about it, such as its description, who wrote, etc. {note} -If you have created a Grails plugin and want it to be hosted in the central repository, you'll find instructions for getting an account on [this wiki page|http://grails.org/Creating+Plugins]. +If you have created a Grails plugin and want it to be hosted in the central repository, you'll find instructions for getting an account on the [plugin portal|http://grails.org/plugins] website. {note} - -When you have access to the Grails Plugin repository, install the [Release Plugin|http://grails-plugins.github.com/grails-release/docs/index.html] by declaring it as a 'build' scoped dependency in @grails-app/conf/BuildConfig.groovy@ file: - -{code:java} -grails.project.dependency.resolution = { - ... - plugins { - build ':release:3.0.0' - } -} - -{code} - -And execute the @publish-plugin@ command to release your plugin: - -{code:java} -grails publish-plugin -{code} - - -This will automatically publish the plugin to the central repository. If the command is successful, it will immediately be available on the plugin portal at http://grails.org/plugin/. You can find out more about the Release plugin and its other features in [its user guide|http://grails-plugins.github.com/grails-release/docs/index.html]. - -h4. Configuring Additional Repositories - -The process for configuring repositories in Grails differs between versions. For version of Grails 1.2 and earlier please refer to the [Grails 1.2 documentation|http://grails.org/doc/1.2.x/guide/12.%20Plug-ins.html#12.2%20Plugin%20Repositories] on the subject. The following sections cover Grails 1.3 and above. - -Grails 1.3 and above use Ivy under the hood to resolve plugin dependencies. The mechanism for defining additional plugin repositories is largely the same as [defining repositories for JAR dependencies|guide:dependencyResolution]. For example you can define a remote Maven repository that contains Grails plugins using the following syntax in @grails-app/conf/BuildConfig.groovy@: - -{code} -repositories { - mavenRepo "http://repository.codehaus.org" - - // ...or with a name - mavenRepo name: "myRepo", - root: "http://myserver:8081/artifactory/plugins-snapshots-local" -} -{code} - -You can also define a SVN-based Grails repository (such as the one hosted at [http://plugins.grails.org|http://plugins.grails.org/]) using the @grailsRepo@ method: - -{code} -repositories { - grailsRepo "http://myserver/mygrailsrepo" - - // ...or with a name - grailsRepo "http://myserver/svn/grails-plugins", "mySvnRepo" -} -{code} - -There is a shortcut to setup the Grails central repository: - -{code} -repositories { - grailsCentral() -} -{code} - -The order in which plugins are resolved is based on the ordering of the repositories. So in this case the Grails central repository will be searched last: - -{code} -repositories { - grailsRepo "http://myserver/mygrailsrepo" - grailsCentral() -} -{code} - - -h4. Publishing to Maven Compatible Repositories - -In general it is recommended for Grails 1.3 and above to use standard Maven-style repositories to self host plugins. The benefits of doing so include the ability for existing tooling and repository managers to interpret the structure of a Maven repository. - -You use the Release plugin to publish a plugin to a Maven repository. Please refer to the section of the [Maven deployment|guide:mavendeploy] user guide on the subject. From 17934f19911bb1f1d49fdb4b55142c2519f9a543 Mon Sep 17 00:00:00 2001 From: Graeme Rocher Date: Thu, 5 Feb 2015 11:53:48 +0100 Subject: [PATCH 046/230] remove redundant line --- src/en/guide/spring/propertyPlaceholderConfiguration.gdoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/en/guide/spring/propertyPlaceholderConfiguration.gdoc b/src/en/guide/spring/propertyPlaceholderConfiguration.gdoc index d2ccc575f29..3fa29fa6f07 100644 --- a/src/en/guide/spring/propertyPlaceholderConfiguration.gdoc +++ b/src/en/guide/spring/propertyPlaceholderConfiguration.gdoc @@ -1,4 +1,4 @@ -Grails supports the notion of property placeholder configuration through an extended version of Spring's [PropertyPlaceholderConfigurer|api:org.springframework.beans.factory.config.PropertyPlaceholderConfigurer], which is typically useful in combination with [externalized configuration|guide:configExternalized]. +Grails supports the notion of property placeholder configuration through an extended version of Spring's [PropertyPlaceholderConfigurer|api:org.springframework.beans.factory.config.PropertyPlaceholderConfigurer]. Settings defined in either "ConfigSlurper":http://groovy.codehaus.org/ConfigSlurper scripts or Java properties files can be used as placeholder values for Spring configuration in @grails-app/conf/spring/resources.xml@ and @grails-app/conf/spring/resources.groovy@. For example given the following entries in @grails-app/conf/Config.groovy@ (or an externalized config): @@ -41,4 +41,4 @@ dataSource(org.springframework.jdbc.datasource.DriverManagerDataSource) { } {code} -Using this approach will keep the types as defined in your config. \ No newline at end of file +Using this approach will keep the types as defined in your config. From 08a9aca3de00e01271e6f658bed16e3137f454df Mon Sep 17 00:00:00 2001 From: Graeme Rocher Date: Thu, 5 Feb 2015 11:54:26 +0100 Subject: [PATCH 047/230] remove redundant line --- src/en/guide/spring/propertyOverrideConfiguration.gdoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/en/guide/spring/propertyOverrideConfiguration.gdoc b/src/en/guide/spring/propertyOverrideConfiguration.gdoc index f02b45fe1b0..07f6de7627c 100644 --- a/src/en/guide/spring/propertyOverrideConfiguration.gdoc +++ b/src/en/guide/spring/propertyOverrideConfiguration.gdoc @@ -1,4 +1,4 @@ -Grails supports setting of bean properties via [configuration|guide:conf]. This is often useful when used in combination with [externalized configuration|guide:configExternalized]. +Grails supports setting of bean properties via [configuration|guide:conf]. You define a @beans@ block with the names of beans and their values: @@ -20,4 +20,4 @@ The same configuration in a Java properties file would be: {code:java} beans.bookService.webServiceURL=http://www.amazon.com -{code} \ No newline at end of file +{code} From 89c1571581755e3db35bc2a5d3ea5afd5987d9bf Mon Sep 17 00:00:00 2001 From: Graeme Rocher Date: Thu, 5 Feb 2015 11:55:54 +0100 Subject: [PATCH 048/230] remove redundant content --- src/en/ref/Command Line/compile.gdoc | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/en/ref/Command Line/compile.gdoc b/src/en/ref/Command Line/compile.gdoc index c28ae8bfd96..4036a37065b 100644 --- a/src/en/ref/Command Line/compile.gdoc +++ b/src/en/ref/Command Line/compile.gdoc @@ -15,12 +15,3 @@ Usage: {code:java} grails compile {code} - -{note} -You can enable verbose compilation for _any_ Grails task by passing the flag @-verboseCompile@ to the task (e.g. @grails run-app -verboseCompile@), or by setting the @verboseCompile@ Grails [build setting|guide:buildCustomising]. -{note} - -Fired Events: - -* @CompileStart@ - Before compilation begins -* @CompileEnd@ - After compilation completes From 8b7b2685ed721ced7077f039742c1b99ccb9b6f7 Mon Sep 17 00:00:00 2001 From: Graeme Rocher Date: Thu, 5 Feb 2015 11:57:47 +0100 Subject: [PATCH 049/230] remove redundant content --- src/en/ref/Command Line/list-plugins.gdoc | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/en/ref/Command Line/list-plugins.gdoc b/src/en/ref/Command Line/list-plugins.gdoc index 6ab383e4558..9e6e5349783 100644 --- a/src/en/ref/Command Line/list-plugins.gdoc +++ b/src/en/ref/Command Line/list-plugins.gdoc @@ -45,7 +45,3 @@ alfresco <0.4> -- Plugin de integracion con Alfresco. {code} The first column contains the plugin name, the second the version and the last the description. If you require more info about a plugin you can use the [plugin-info|commandLine] command. If you wish to install a plugin you can use the plugin name and/or version in combination with the [install-plugin|commandLine]. - -{note} -Note: If you are behind a proxy you may want to consider using the [set-proxy|commandLine] command prior to running this command. -{note} From 63040b21e9e18b97612d9658083a89e2e8136fb8 Mon Sep 17 00:00:00 2001 From: Graeme Rocher Date: Thu, 5 Feb 2015 11:59:40 +0100 Subject: [PATCH 050/230] update package-plugin content --- src/en/ref/Command Line/package-plugin.gdoc | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/src/en/ref/Command Line/package-plugin.gdoc b/src/en/ref/Command Line/package-plugin.gdoc index cdfec51c16e..a70b9e3f137 100644 --- a/src/en/ref/Command Line/package-plugin.gdoc +++ b/src/en/ref/Command Line/package-plugin.gdoc @@ -2,7 +2,7 @@ h1. package-plugin h2. Purpose -Packages a plugin as a ZIP archive which can then be installed into another application +Packages a plugin as a JAR archive which can then be installed into another application h2. Examples @@ -17,16 +17,8 @@ Usage: grails package-plugin {code} -Fired Events: +The plugin archive will be built to the @build/libs@ directory by default. You can also install the plugin to your local Maven repository with the @install@ command: -* @StatusError@ - When there was an error during packaging - -The plugin archive will be named with the convention @grails-\[name\]-\[version\].zip@. The name and version are obtained from the plugin descriptor (the Groovy class ending with the convention @GrailsPlugin.groovy@) in the root of the plugin directory. For example this plugin: - -{code:java} -class SimpleGrailsPlugin { - def version = "0.1" -} {code} - -will result in a ZIP archive called @grails-simple-0.1.zip@, which can then be installed into an application with the [install-plugin|commandLine] command. +grails install +{code} From 140c2d68bb36e73d93144760fa76c210929923d3 Mon Sep 17 00:00:00 2001 From: Graeme Rocher Date: Thu, 5 Feb 2015 12:00:44 +0100 Subject: [PATCH 051/230] update plugin usage content --- src/en/ref/Plug-ins.gdoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/en/ref/Plug-ins.gdoc b/src/en/ref/Plug-ins.gdoc index e751a4f91da..e92c8ad7090 100644 --- a/src/en/ref/Plug-ins.gdoc +++ b/src/en/ref/Plug-ins.gdoc @@ -12,10 +12,10 @@ This will create a plugin project which can then be packaged with [package-plugi grails package-plugin {code} -and installed into Grails applications with [install-plugin|commandLine]: +To install the plugin to your local Maven repository you can use the @install@ command: {code:java} -grails install-plugin ../grails-simple-0.1.zip +grails install {code} Refer to the user guide topic on [plugins|guide:plugins] for more information. From 55a7cdc062cc5ead948c6bbab287199145e86a15 Mon Sep 17 00:00:00 2001 From: Graeme Rocher Date: Thu, 5 Feb 2015 12:05:23 +0100 Subject: [PATCH 052/230] remove redundant content --- .../guide/plugins/hookingIntoBuildEvents.gdoc | 26 -------------- src/en/ref/Command Line/create-filters.gdoc | 35 ------------------- .../ref/Command Line/list-plugin-updates.gdoc | 28 --------------- 3 files changed, 89 deletions(-) delete mode 100644 src/en/guide/plugins/hookingIntoBuildEvents.gdoc delete mode 100644 src/en/ref/Command Line/create-filters.gdoc delete mode 100644 src/en/ref/Command Line/list-plugin-updates.gdoc diff --git a/src/en/guide/plugins/hookingIntoBuildEvents.gdoc b/src/en/guide/plugins/hookingIntoBuildEvents.gdoc deleted file mode 100644 index 726d9e6e567..00000000000 --- a/src/en/guide/plugins/hookingIntoBuildEvents.gdoc +++ /dev/null @@ -1,26 +0,0 @@ -h4. Post-Install Configuration and Participating in Upgrades - -Grails plugins can do post-install configuration. This is achieved using a specially named script under the @scripts@ directory of the plugin - @_Install.groovy@. - -@_Install.groovy@ is executed after the plugin has been installed. - -This scripts is a [Gant|guide:commandLine] script, so you can use the full power of Gant. An addition to the standard Gant variables there is also a @pluginBasedir@ variable which points at the plugin installation basedir. - -As an example this @_Install.groovy@ script will create a new directory type under the @grails-app@ directory and install a configuration template: - -{code:java} -ant.mkdir(dir: "${basedir}/grails-app/jobs") - -ant.copy(file: "${pluginBasedir}/src/samples/SamplePluginConfig.groovy", - todir: "${basedir}/grails-app/conf") -{code} - -The @pluginBasedir@ variable is not available in custom scripts, but you can use @fooPluginDir@, where @foo@ is the name of your plugin. - -h4. Scripting events - -It is also possible to hook into command line scripting events. These are events triggered during execution of Grails target and plugin scripts. - -For example, you can hook into status update output (i.e. "Tests passed", "Server running") and the creation of files or artefacts. - -A plugin just has to provide an @_Events.groovy@ script to listen to the required events. Refer the documentation on [Hooking into Events|guide:events] for further information. diff --git a/src/en/ref/Command Line/create-filters.gdoc b/src/en/ref/Command Line/create-filters.gdoc deleted file mode 100644 index d9416f8df56..00000000000 --- a/src/en/ref/Command Line/create-filters.gdoc +++ /dev/null @@ -1,35 +0,0 @@ -h1. create-filters - -h2. Purpose - -The @create-filters@ command creates a Grails filters class for the given base name. - -h2. Examples - -{code:java} -grails create-filters -grails create-filters logging -grails create-filters org.bookstore.Logging -{code} - -h2. Description - -Creates a filters class for the given base name. For example, for a base name of @org.bookstore.Logging@ a filters class called @LoggingFilters@ will be created in the @grails-app/conf/org/bookstore@ directory. The argument is optional, but if you don't include it the command will ask you for the name of the filters class. - -A [filters class|guide:filters] allows you to execute code before and after a controller action is executed and also after any view is rendered. - -The name of the filters class can include a Java package, such as @org.bookstore@ in the final example above, but if one is not provided a default is used. So the second example will create the file @grails-app/conf//LoggingFilters.groovy@ whereas the last one will create @grails-app/conf/org/bookstore/LoggingFilters.groovy@ directory. Note that the first letter of the name is always upper-cased when determining the class name. - -If you want the command to default to a different package for filters classes, provide a value for @grails.project.groupId@ in the [runtime configuration|guide:config]. - -Note that this command is just for convenience and you can also create filters in your favorite text editor or IDE if you choose. - -Usage: - -{code:java} -grails create-filters [name] -{code} - -Fired Events: - -* @CreatedFile@ - When the filters class has been created diff --git a/src/en/ref/Command Line/list-plugin-updates.gdoc b/src/en/ref/Command Line/list-plugin-updates.gdoc deleted file mode 100644 index 1ada69b45fd..00000000000 --- a/src/en/ref/Command Line/list-plugin-updates.gdoc +++ /dev/null @@ -1,28 +0,0 @@ -h1. list-plugin-updates - -h2. Purpose - -Lists the versions of updated plugins available from the Grails standard repository - -h2. Description - -Usage: -{code:java} -grails list-plugin-updates -{code} - -Lists the plugins that are updateable in the Grails standard repository. Note: This command can take a while to execute depending on your internet connectivity. Typical output looks like this: - -{code} -Plugins with available updates are listed below: -------------------------------------------------------------- - -acegi 0.4 0.5.2 -console 0.1 0.2.2 -{code} - -The first column contains the plugin name, the second the installed version and the last the current version. If you require more info about a plugin you can use the [plugin-info|commandLine] command. If you wish to update a plugin you can use the plugin name and/or version in combination with the [install-plugin|commandLine]. - -{note} -Note: If you are behind a proxy you may want to consider using the [set-proxy|commandLine] command prior to running this command. -{note} From b4eb397714b2c101485de69258b3134c990ed5a5 Mon Sep 17 00:00:00 2001 From: Graeme Rocher Date: Thu, 5 Feb 2015 12:05:35 +0100 Subject: [PATCH 053/230] update TOC --- src/en/guide/toc.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/en/guide/toc.yml b/src/en/guide/toc.yml index a0647ab792e..094e3146ed0 100644 --- a/src/en/guide/toc.yml +++ b/src/en/guide/toc.yml @@ -38,15 +38,15 @@ conf: multipleDatasources: Multiple Datasources versioning: Versioning docengine: Project Documentation - dependencyResolution: Dependency Resolution + dependencyResolution: Dependency Resolution commandLine: title: The Command Line interactiveMode: Interactive Mode - profiles: The Command Line and Profiles + profiles: The Command Line and Profiles creatingCustomScripts: Creating Custom Scripts reusingGrailsScripts: Re-using Grails scripts gradleBuild: - title: Building with Gradle + title: Building with Gradle gradleDependencies: Defining Dependencies with Gradle gradleTasks: Working with Gradle Tasks gradlePlugins: Grails plugins for Gradle @@ -284,7 +284,6 @@ plugins: understandingPluginStructure: Understanding a Plugin's Structure providingBasicArtefacts: Providing Basic Artefacts evaluatingConventions: Evaluating Conventions - hookingIntoBuildEvents: Hooking into Build Events hookingIntoRuntimeConfiguration: Hooking into Runtime Configuration addingDynamicMethodsAtRuntime: Adding Dynamic Methods at Runtime participatingInAutoReloadEvents: Participating in Auto Reload Events From 75c7092a3ddbd0f45803feb1126a13134c42c8c0 Mon Sep 17 00:00:00 2001 From: Graeme Rocher Date: Thu, 5 Feb 2015 12:05:44 +0100 Subject: [PATCH 054/230] Use snapshot --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 30238b500e8..586f1da6a91 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,6 @@ apply plugin: "base" -version = System.getProperty("grails.version") ?: "3.0.0.M1" +version = System.getProperty("grails.version") ?: "3.0.0.BUILD-SNAPSHOT" archivesBaseName = "grails-docs" From 8991c5a975248ce9068bb3cab2c2baab975334a7 Mon Sep 17 00:00:00 2001 From: Graeme Rocher Date: Thu, 5 Feb 2015 16:18:04 +0100 Subject: [PATCH 055/230] Updated documentation on Interceptors --- src/en/guide/theWebLayer/filters.gdoc | 1 - .../theWebLayer/filters/applyingFilters.gdoc | 84 ---------------- .../filters/filterDependencies.gdoc | 51 ---------- .../theWebLayer/filters/filterTypes.gdoc | 99 ------------------- .../filters/filterVariablesAndScopes.gdoc | 17 ---- src/en/guide/theWebLayer/interceptors.gdoc | 29 ++++++ .../interceptors/definingInterceptors.gdoc | 40 ++++++++ .../interceptors/interceptorMatching.gdoc | 42 ++++++++ .../interceptors/interceptorOrdering.gdoc | 1 + src/en/guide/toc.yml | 11 +-- 10 files changed, 117 insertions(+), 258 deletions(-) delete mode 100644 src/en/guide/theWebLayer/filters.gdoc delete mode 100644 src/en/guide/theWebLayer/filters/applyingFilters.gdoc delete mode 100644 src/en/guide/theWebLayer/filters/filterDependencies.gdoc delete mode 100644 src/en/guide/theWebLayer/filters/filterTypes.gdoc delete mode 100644 src/en/guide/theWebLayer/filters/filterVariablesAndScopes.gdoc create mode 100644 src/en/guide/theWebLayer/interceptors.gdoc create mode 100644 src/en/guide/theWebLayer/interceptors/definingInterceptors.gdoc create mode 100644 src/en/guide/theWebLayer/interceptors/interceptorMatching.gdoc create mode 100644 src/en/guide/theWebLayer/interceptors/interceptorOrdering.gdoc diff --git a/src/en/guide/theWebLayer/filters.gdoc b/src/en/guide/theWebLayer/filters.gdoc deleted file mode 100644 index 399f4d278ba..00000000000 --- a/src/en/guide/theWebLayer/filters.gdoc +++ /dev/null @@ -1 +0,0 @@ -Although Grails [controllers|guide:controllers] support fine grained interceptors, these are only really useful when applied to a few controllers and become difficult to manage with larger applications. Filters on the other hand can be applied across a whole group of controllers, a URI space or to a specific action. Filters are far easier to plugin and maintain completely separately to your main controller logic and are useful for all sorts of cross cutting concerns such as security, logging, and so on. diff --git a/src/en/guide/theWebLayer/filters/applyingFilters.gdoc b/src/en/guide/theWebLayer/filters/applyingFilters.gdoc deleted file mode 100644 index 2b1189655b1..00000000000 --- a/src/en/guide/theWebLayer/filters/applyingFilters.gdoc +++ /dev/null @@ -1,84 +0,0 @@ -To create a filter create a class that ends with the convention @Filters@ in the @grails-app/conf@ directory. Within this class define a code block called @filters@ that contains the filter definitions: - -{code:java} -class ExampleFilters { - def filters = { - // your filters here - } -} -{code} - -Each filter you define within the @filters@ block has a name and a scope. The name is the method name and the scope is defined using named arguments. For example to define a filter that applies to all controllers and all actions you can use wildcards: - -{code:java} -sampleFilter(controller:'*', action:'*') { - // interceptor definitions -} -{code} - -The scope of the filter can be one of the following things: - -* A controller and/or action name pairing with optional wildcards -* A URI, with Ant path matching syntax - -Filter rule attributes: -* @controller@ - controller matching pattern, by default \* is replaced with .\* and a regex is compiled -* @controllerExclude@ - controller exclusion pattern, by default \* is replaced with .\* and a regex is compiled -* @action@ - action matching pattern, by default \* is replaced with .\* and a regex is compiled -* @actionExclude@ - action exclusion pattern, by default \* is replaced with .\* and a regex is compiled -* @regex@ (@true@/@false@) - use regex syntax (don't replace '\*' with '.\*') -* @uri@ - a uri to match, expressed with as Ant style path (e.g. /book/\*\*) -* @uriExclude@ - a uri pattern to exclude, expressed with as Ant style path (e.g. /book/\*\*) -* @find@ (@true@/@false@) - rule matches with partial match (see @java.util.regex.Matcher.find()@) -* @invert@ (@true@/@false@) - invert the rule (NOT rule) - -Some examples of filters include: - -* All controllers and actions -{code:java} -all(controller: '*', action: '*') { - -} -{code} -* Only for the @BookController@ -{code:java} -justBook(controller: 'book', action: '*') { - -} -{code} -* All controllers except the @BookController@ -{code:java} -notBook(controller: 'book', invert: true) { - -} -{code} -* All actions containing 'save' in the action name -{code:java} -saveInActionName(action: '*save*', find: true) { - -} -{code} -* All actions starting with the letter 'b' except for actions beginning with the phrase 'bad*' -{code:java} -actionBeginningWithBButNotBad(action: 'b*', actionExclude: 'bad*', find: true) { - -} -{code} -* Applied to a URI space -{code:java} -someURIs(uri: '/book/**') { - -} -{code} -* Applied to all URIs -{code:java} -allURIs(uri: '/**') { - -} -{code} - -In addition, the order in which you define the filters within the @filters@ code block dictates the order in which they are executed. To control the order of execution between @Filters@ classes, you can use the @dependsOn@ property discussed in [filter dependencies|guide:filterDependencies] section. - -{note} -Note: When exclude patterns are used they take precedence over the matching patterns. For example, if action is 'b\*' and actionExclude is 'bad\*' then actions like 'best' and 'bien' will have that filter applied but actions like 'bad' and 'badlands' will not. -{note} diff --git a/src/en/guide/theWebLayer/filters/filterDependencies.gdoc b/src/en/guide/theWebLayer/filters/filterDependencies.gdoc deleted file mode 100644 index e9b73316cc6..00000000000 --- a/src/en/guide/theWebLayer/filters/filterDependencies.gdoc +++ /dev/null @@ -1,51 +0,0 @@ -In a @Filters@ class, you can specify any other @Filters@ classes that should first be executed using the @dependsOn@ property. This is used when a @Filters@ class depends on the behavior of another @Filters@ class (e.g. setting up the environment, modifying the request/session, etc.) and is defined as an array of @Filters@ classes. - -Take the following example @Filters@ classes: - -{code:java} -class MyFilters { - def dependsOn = [MyOtherFilters] - - def filters = { - checkAwesome(uri: "/*") { - before = { - if (request.isAwesome) { // do something awesome } - } - } - - checkAwesome2(uri: "/*") { - before = { - if (request.isAwesome) { // do something else awesome } - } - } - } -} -{code} - -{code:java} -class MyOtherFilters { - def filters = { - makeAwesome(uri: "/*") { - before = { - request.isAwesome = true - } - } - doNothing(uri: "/*") { - before = { - // do nothing - } - } - } -} -{code} - -MyFilters specifically @dependsOn@ MyOtherFilters. This will cause all the filters in MyOtherFilters whose scope matches the current request to be executed before those in MyFilters. For a request of "/test", which will match the scope of every filter in the example, the execution order would be as follows: - -* MyOtherFilters - makeAwesome -* MyOtherFilters - doNothing -* MyFilters - checkAwesome -* MyFilters - checkAwesome2 - -The filters within the MyOtherFilters class are processed in order first, followed by the filters in the MyFilters class. Execution order between @Filters@ classes are enabled and the execution order of filters within each @Filters@ class are preserved. - -If any cyclical dependencies are detected, the filters with cyclical dependencies will be added to the end of the filter chain and processing will continue. Information about any cyclical dependencies that are detected will be written to the logs. Ensure that your root logging level is set to at least WARN or configure an appender for the Grails Filters Plugin (@org.codehaus.groovy.grails.plugins.web.filters.FiltersGrailsPlugin@) when debugging filter dependency issues. diff --git a/src/en/guide/theWebLayer/filters/filterTypes.gdoc b/src/en/guide/theWebLayer/filters/filterTypes.gdoc deleted file mode 100644 index 92bcb4d187f..00000000000 --- a/src/en/guide/theWebLayer/filters/filterTypes.gdoc +++ /dev/null @@ -1,99 +0,0 @@ -Within the body of the filter you can then define one or several of the following interceptor types for the filter: - -* @before@ - Executed before the action. Return @false@ to indicate that the response has been handled that that all future filters and the action should not execute -* @after@ - Executed after an action. Takes a first argument as the view model to allow modification of the model before rendering the view -* @afterView@ - Executed after view rendering. Takes an Exception as an argument which will be non-@null@ if an exception occurs during processing. Note: this Closure is called before the layout is applied. - -For example to fulfill the common simplistic authentication use case you could define a filter as follows: - -{code:java} -class SecurityFilters { - def filters = { - loginCheck(controller: '*', action: '*') { - before = { - if (!session.user && !actionName.equals('login')) { - redirect(action: 'login') - return false - } - } - } - } -} -{code} - -Here the @loginCheck@ filter uses a @before@ interceptor to execute a block of code that checks if a user is in the session and if not redirects to the login action. Note how returning false ensure that the action itself is not executed. - -Here's a more involved example that demonstrates all three filter types: - -{code:java} -import java.util.concurrent.atomic.AtomicLong - -class LoggingFilters { - - private static final AtomicLong REQUEST_NUMBER_COUNTER = new AtomicLong() - private static final String START_TIME_ATTRIBUTE = 'Controller__START_TIME__' - private static final String REQUEST_NUMBER_ATTRIBUTE = 'Controller__REQUEST_NUMBER__' - - def filters = { - - logFilter(controller: '*', action: '*') { - - before = { - if (!log.debugEnabled) return true - - long start = System.currentTimeMillis() - long currentRequestNumber = REQUEST_NUMBER_COUNTER.incrementAndGet() - - request[START_TIME_ATTRIBUTE] = start - request[REQUEST_NUMBER_ATTRIBUTE] = currentRequestNumber - - log.debug "preHandle request #\$currentRequestNumber : " + - "'\$request.servletPath'/'\$request.forwardURI', " + - "from \$request.remoteHost (\$request.remoteAddr) " + - " at \${new Date()}, Ajax: \$request.xhr, controller: \$controllerName, " + - "action: \$actionName, params: \${new TreeMap(params)}" - - return true - } - - after = { Map model -> - - if (!log.debugEnabled) return true - - long start = request[START_TIME_ATTRIBUTE] - long end = System.currentTimeMillis() - long requestNumber = request[REQUEST_NUMBER_ATTRIBUTE] - - def msg = "postHandle request #\$requestNumber: end \${new Date()}, " + - "controller total time \${end - start}ms" - if (log.traceEnabled) { - log.trace msg + "; model: \$model" - } - else { - log.debug msg - } - } - - afterView = { Exception e -> - - if (!log.debugEnabled) return true - - long start = request[START_TIME_ATTRIBUTE] - long end = System.currentTimeMillis() - long requestNumber = request[REQUEST_NUMBER_ATTRIBUTE] - - def msg = "afterCompletion request #\$requestNumber: " + - "end \${new Date()}, total time \${end - start}ms" - if (e) { - log.debug "\$msg \\\n\\\texception: \$e.message", e - } - else { - log.debug msg - } - } - } - } -} -{code} - -In this logging example we just log various request information, but note that the @model@ map in the @after@ filter is mutable. If you need to add or remove items from the model map you can do that in the @after@ filter. diff --git a/src/en/guide/theWebLayer/filters/filterVariablesAndScopes.gdoc b/src/en/guide/theWebLayer/filters/filterVariablesAndScopes.gdoc deleted file mode 100644 index 50bf5e5982a..00000000000 --- a/src/en/guide/theWebLayer/filters/filterVariablesAndScopes.gdoc +++ /dev/null @@ -1,17 +0,0 @@ -Filters support all the common properties available to [controllers|guide:controllers] and [tag libraries|guide:taglibs], plus the application context: - -* [request|controllers] - The HttpServletRequest object -* [response|controllers] - The HttpServletResponse object -* [session|controllers] - The HttpSession object -* [servletContext|controllers] - The ServletContext object -* [flash|controllers] - The flash object -* [params|controllers] - The request parameters object -* [actionName|controllers] - The action name that is being dispatched to -* [controllerName|controllers] - The controller name that is being dispatched to -* [grailsApplication|controllers] - The Grails application currently running -* [applicationContext|api:org.springframework.context.ApplicationContext] - The ApplicationContext object - -However, filters only support a subset of the methods available to controllers and tag libraries. These include: - -* [redirect|controllers] - For redirects to other controllers and actions -* [render|controllers] - For rendering custom responses \ No newline at end of file diff --git a/src/en/guide/theWebLayer/interceptors.gdoc b/src/en/guide/theWebLayer/interceptors.gdoc new file mode 100644 index 00000000000..22eec768e9b --- /dev/null +++ b/src/en/guide/theWebLayer/interceptors.gdoc @@ -0,0 +1,29 @@ +Although Grails [controllers|guide:controllers] support fine grained interceptors, these are only really useful when applied to a few controllers and become difficult to manage with larger applications. + +To solve this you can create standalone Interceptors using the [commandLine|create-interceptors] command: + + {code} + $ grails create-interceptor MyInterceptor + {code} + +The above command will create an Interceptor in the @grails-app/controllers@ directory with the following default contents: + +{code} + class MyInterceptor { + + boolean before() { true } + + boolean after() { true } + + void afterView(Throwable t) { + // no-op + } + +} +{code} + +h4. Interceptors vs Filters + +In versions of Grails prior to Grails 3.0, Grails supported the notion of filters. These are still supported for backwards compatibility but are considered deprecated. + +The new interceptors concept in Grails 3.0 is superior in a number of ways, most significantly interceptors can using Groovy's @CompileStatic@ annotation to optimize performance (something which is often critical as interceptors can be executed for every request.) diff --git a/src/en/guide/theWebLayer/interceptors/definingInterceptors.gdoc b/src/en/guide/theWebLayer/interceptors/definingInterceptors.gdoc new file mode 100644 index 00000000000..06896f1af69 --- /dev/null +++ b/src/en/guide/theWebLayer/interceptors/definingInterceptors.gdoc @@ -0,0 +1,40 @@ +By default interceptors will match the controller name they apply to be convention. For example if you have an interceptor called @BookInterceptor@ then all requests the actions of the @BookController@ will trigger the interceptor. + +An @Interceptor@ implements the [Interceptor|api:grails.artefact.Interceptor] trait and provides 3 methods that can be used to intercept requests: + +{code} + /** + * Executed before a matched action + * + * @return Whether the action should continue and execute + */ + boolean before() { true } + + /** + * Executed after the action executes but prior to view rendering + * + * @return True if view rendering should continue, false otherwise + */ + boolean after() { true } + + /** + * Executed after view rendering completes + * + * @param t The exception instance if an exception was thrown, null otherwise + */ + void afterView(Throwable t) {} +{code} + +As described above the @before@ method is executed prior to an action and can cancel the execution of the action by returning @false. + +The @after@ method is executed after an action executes and can halt view rendering if it returns false. The @after@ method can also modify the view or model using the @view@ and @model@ properties: + +{code} +boolean after() { + model.foo = "bar" // add a new model attribute called 'foo' + view = 'alternate' // render a different view called 'alternate' + true +} +{code} + +The @afterView@ method is executed after view rendering completes and if an exception occurs will receive the exception as the first argument to the method. diff --git a/src/en/guide/theWebLayer/interceptors/interceptorMatching.gdoc b/src/en/guide/theWebLayer/interceptors/interceptorMatching.gdoc new file mode 100644 index 00000000000..39280a487d6 --- /dev/null +++ b/src/en/guide/theWebLayer/interceptors/interceptorMatching.gdoc @@ -0,0 +1,42 @@ +As mention in the previous section, by default an interceptor will match only requests to the associated controller by convention. However you can configure the interceptor to match any request using the @match@ or @matchAll@ methods defined in the [Interceptor API|api:grails.artefact.Interceptor]. + +The matching methods return a [Matcher|api:grails.artefact.Interceptor] instance which can be used to configure how the interceptor matches the request. + +For example the following interceptor will match all requests except those to the @login@ controller: + +{code} +class AuthInterceptor { + AuthInterceptor() { + matchAll() + .excludes(controller:"login") + } + + boolean before() { + // perform authentication + } +} +{code} + +You can also perform matching using named argument: + + +{code} +class LoggingInterceptor { + LoggingInterceptor() { + match(controller:"book", action:"show") // using strings + match(controller: ~/(author|publisher)/) // using regex + } + + boolean before() { + ... + } +} +{code} + +All named arguments accept either a String or a Regex expression. The possible named arguments are: + +* @namespace@ - The namespace of the controller +* @controller@ - The name of the controller +* @action@ - The name of the action +* @method@ - The HTTP method +* @uri@ - The URI of the request (cannot be used in combination with other arguments) diff --git a/src/en/guide/theWebLayer/interceptors/interceptorOrdering.gdoc b/src/en/guide/theWebLayer/interceptors/interceptorOrdering.gdoc new file mode 100644 index 00000000000..a0990367ef8 --- /dev/null +++ b/src/en/guide/theWebLayer/interceptors/interceptorOrdering.gdoc @@ -0,0 +1 @@ +TBD diff --git a/src/en/guide/toc.yml b/src/en/guide/toc.yml index 094e3146ed0..1d022fcbbda 100644 --- a/src/en/guide/toc.yml +++ b/src/en/guide/toc.yml @@ -173,12 +173,11 @@ theWebLayer: namedMappings: Named URL Mappings customizingUrlFormat: Customizing URL Formats namespacedControllers: Namespaced Controllers - filters: - title: Filters - applyingFilters: Applying Filters - filterTypes: Filter Types - filterVariablesAndScopes: Variables and Scopes - filterDependencies: Filter Dependencies + interceptors: + title: Interceptors + definingInterceptors: Defining Interceptors + interceptorMatching: Matching Requests with Inteceptors + interceptorOrdering: Ordering Interceptor Execution ajax: title: Ajax ajaxSupport: From 17cc9854eec56ed4061d33ca7b86ca8750c9ff9c Mon Sep 17 00:00:00 2001 From: Graeme Rocher Date: Thu, 5 Feb 2015 16:33:55 +0100 Subject: [PATCH 056/230] remove redundant content --- src/en/ref/Command Line/create-controller.gdoc | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/en/ref/Command Line/create-controller.gdoc b/src/en/ref/Command Line/create-controller.gdoc index 3cb1f635f02..cf1b95b1ead 100644 --- a/src/en/ref/Command Line/create-controller.gdoc +++ b/src/en/ref/Command Line/create-controller.gdoc @@ -27,7 +27,3 @@ Usage: {code:java} grails create-controller [name] {code} - -Fired Events: - -* @CreatedFile@ - When the controller is created From 4d044ea7d282983c960bf7819b61f8d564669cd6 Mon Sep 17 00:00:00 2001 From: Graeme Rocher Date: Thu, 5 Feb 2015 16:38:21 +0100 Subject: [PATCH 057/230] add 'create-interceptor' doc --- .../ref/Command Line/create-interceptor.gdoc | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 src/en/ref/Command Line/create-interceptor.gdoc diff --git a/src/en/ref/Command Line/create-interceptor.gdoc b/src/en/ref/Command Line/create-interceptor.gdoc new file mode 100644 index 00000000000..efff4b8b00a --- /dev/null +++ b/src/en/ref/Command Line/create-interceptor.gdoc @@ -0,0 +1,29 @@ +h1. create-interceptor + +h2. Purpose + +The @create-interceptor@ command creates an interceptor and associated unit test for the given base name. + +h2. Examples + +bc. +grails create-interceptor +grails create-interceptor Book +grails create-interceptor org.bookstore.book + +h2. Description + +Creates a new interceptor with an empty @before@, @after@ and @afterView@ method definitions. The argument is optional, but if you don't include it the command will ask you for the name of the interceptor. + +A [interceptor|guide:interceptors] is responsible intercepting incoming web requests and performing actions such as authentication, logging and so on. + +The name of the interceptor can include a Java package, such as @org.bookstore@ in the final example above, but if one is not provided a default is used. So the second example will create the file @grails-app/controllers//BookInterceptor.groovy@ whereas the last one will create @grails-app/controllers/org/bookstore/BookInterceptor.groovy@ directory. Note that the first letter of the interceptor name is always upper-cased when determining the class name. + +If you want the command to default to a different package for interceptors, provide a value for @grails.project.groupId@ in the [runtime configuration|guide:config]. + +Note that this command is just for convenience and you can also create interceptors in your favourite text editor or IDE if you choose. + +Usage: +{code:java} +grails create-interceptor [name] +{code} From ae942f6fe819cf6ea0dcb5f7b0574cb0d9e4ab5b Mon Sep 17 00:00:00 2001 From: Graeme Rocher Date: Thu, 5 Feb 2015 18:09:03 +0100 Subject: [PATCH 058/230] Updated documentation on interceptors --- .../introduction/whatsNew/webFeatures.gdoc | 19 +++++++++++++++++++ src/en/guide/theWebLayer/interceptors.gdoc | 2 +- .../interceptors/definingInterceptors.gdoc | 6 ++---- 3 files changed, 22 insertions(+), 5 deletions(-) create mode 100644 src/en/guide/introduction/whatsNew/webFeatures.gdoc diff --git a/src/en/guide/introduction/whatsNew/webFeatures.gdoc b/src/en/guide/introduction/whatsNew/webFeatures.gdoc new file mode 100644 index 00000000000..4ae116d46bd --- /dev/null +++ b/src/en/guide/introduction/whatsNew/webFeatures.gdoc @@ -0,0 +1,19 @@ +h4. New Interceptors API + +In previous versions of Grails, filters were used to define logic that intercepts controller action execution. + +As of Grails 3.0, this API is deprecated and has been replaced by the new [Interceptor API|guide:interceptors]. An example interceptor can be seen below: + +{code} + class MyInterceptor { + + boolean before() { true } + + boolean after() { true } + + void afterView() { + // no-op + } + +} +{code} diff --git a/src/en/guide/theWebLayer/interceptors.gdoc b/src/en/guide/theWebLayer/interceptors.gdoc index 22eec768e9b..6c4a7545c83 100644 --- a/src/en/guide/theWebLayer/interceptors.gdoc +++ b/src/en/guide/theWebLayer/interceptors.gdoc @@ -15,7 +15,7 @@ The above command will create an Interceptor in the @grails-app/controllers@ dir boolean after() { true } - void afterView(Throwable t) { + void afterView() { // no-op } diff --git a/src/en/guide/theWebLayer/interceptors/definingInterceptors.gdoc b/src/en/guide/theWebLayer/interceptors/definingInterceptors.gdoc index 06896f1af69..85bc5fa52f0 100644 --- a/src/en/guide/theWebLayer/interceptors/definingInterceptors.gdoc +++ b/src/en/guide/theWebLayer/interceptors/definingInterceptors.gdoc @@ -19,10 +19,8 @@ An @Interceptor@ implements the [Interceptor|api:grails.artefact.Interceptor] tr /** * Executed after view rendering completes - * - * @param t The exception instance if an exception was thrown, null otherwise */ - void afterView(Throwable t) {} + void afterView() {} {code} As described above the @before@ method is executed prior to an action and can cancel the execution of the action by returning @false. @@ -37,4 +35,4 @@ boolean after() { } {code} -The @afterView@ method is executed after view rendering completes and if an exception occurs will receive the exception as the first argument to the method. +The @afterView@ method is executed after view rendering completes and if an exception occurs, the exception is available using the @throwable@ property of the [Interceptor|api:grails.artefact.Interceptor] trait. From 09a0ccebfebbf2b69963c01500cdf3eda116eab1 Mon Sep 17 00:00:00 2001 From: Graeme Rocher Date: Fri, 6 Feb 2015 07:35:22 +0000 Subject: [PATCH 059/230] disable go github-release installation --- .travis.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index f5e288f2b58..9e46b487abd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,4 @@ script: ./travis-build.sh -before_script: -- go get github.com/aktau/github-release jdk: - openjdk7 env: From c68f61bc1894bf8386f730988614daf729e7d3d2 Mon Sep 17 00:00:00 2001 From: Graeme Rocher Date: Fri, 6 Feb 2015 10:10:32 +0000 Subject: [PATCH 060/230] fix doc build --- src/en/guide/introduction/whatsNew/coreFeatures.gdoc | 6 +++--- .../{interceptors.gdoc => controllerInterceptors.gdoc} | 0 src/en/guide/toc.yml | 3 ++- 3 files changed, 5 insertions(+), 4 deletions(-) rename src/en/guide/theWebLayer/controllers/{interceptors.gdoc => controllerInterceptors.gdoc} (100%) diff --git a/src/en/guide/introduction/whatsNew/coreFeatures.gdoc b/src/en/guide/introduction/whatsNew/coreFeatures.gdoc index 586cd2dde81..01b0d35c6b4 100644 --- a/src/en/guide/introduction/whatsNew/coreFeatures.gdoc +++ b/src/en/guide/introduction/whatsNew/coreFeatures.gdoc @@ -8,16 +8,16 @@ h4. Spring 4.1 and Spring Boot 1.2 Grails 3.0 comes with Spring 4.1 which includes many new features and enhancements. See the (TBD). -In addition, Grails 3.0 is built on [Spring Boot|http://projects.spring.io/spring-boot/] which provides the ability to produce runnable JAR files that can embed Tomcat, Jetty or Undertow containers. +In addition, Grails 3.0 is built on [Spring Boot 1.2|http://projects.spring.io/spring-boot/] which provides the ability to produce runnable JAR files that can embed Tomcat, Jetty or Undertow containers. h4. Gradle Build System Grails 3.0 deprecates the older Gant-based build system in favour of a new [Gradle-based|http://gradle.org] build that integrates closely with the [Gradle plugin ecosystem|http://plugins.gradle.org]. -h4. Application Profiles +h4. Application Profiles Grails 3.0 supports the notion of application profiles via a new [profile repository|https://github.com/grails/grails-profile-repository]. A profile encapsulates an application structure, set of commands, plugins and capabilities. For example the "web" profile allows construction on web applications deployable to a Servlet container. In the future more profiles will be developed targeting different environments. h4. Redesigned API based on Traits -The Grails API has been redesigned so that public API is correctly populated under the @grails.@ package whilst private / internal API that is subject to change can be found in the @org.grails.@ package. The core API has also been rewritten and based around the [Groovy Traits|http://beta.groovy-lang.org/docs/latest/html/documentation/core-traits.html]. +The Grails API has been redesigned so that public API is correctly populated under the @grails.@ package whilst private / internal API that is subject to change can be found in the @org.grails.@ package. The core API has also been rewritten and based around the [Groovy Traits|http://groovy-lang.org/docs/latest/html/documentation/core-traits.html]. diff --git a/src/en/guide/theWebLayer/controllers/interceptors.gdoc b/src/en/guide/theWebLayer/controllers/controllerInterceptors.gdoc similarity index 100% rename from src/en/guide/theWebLayer/controllers/interceptors.gdoc rename to src/en/guide/theWebLayer/controllers/controllerInterceptors.gdoc diff --git a/src/en/guide/toc.yml b/src/en/guide/toc.yml index 1d022fcbbda..d9b36c543cf 100644 --- a/src/en/guide/toc.yml +++ b/src/en/guide/toc.yml @@ -3,6 +3,7 @@ introduction: whatsNew: title: What's new in Grails 3.0? coreFeatures: Core Features + webFeatures: Web Features developmentEnvironmentFeatures: Development Environment Features testingFeatures: Testing Features gettingStarted: @@ -109,7 +110,7 @@ theWebLayer: controllersAndScopes: Controllers and Scopes modelsAndViews: Models and Views redirectsAndChaining: Redirects and Chaining - interceptors: Controller Interceptors + controllerInterceptors: Controller Interceptors dataBinding: Data Binding xmlAndJSON: XML and JSON Responses moreOnJSONBuilder: More on JSONBuilder From a5bc818d61be64810bedd18d8f21c2a1efba7c89 Mon Sep 17 00:00:00 2001 From: Graeme Rocher Date: Fri, 6 Feb 2015 19:58:51 +0000 Subject: [PATCH 061/230] documentation on interceptor ordering --- .../interceptors/interceptorOrdering.gdoc | 53 ++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/src/en/guide/theWebLayer/interceptors/interceptorOrdering.gdoc b/src/en/guide/theWebLayer/interceptors/interceptorOrdering.gdoc index a0990367ef8..e487d2f7166 100644 --- a/src/en/guide/theWebLayer/interceptors/interceptorOrdering.gdoc +++ b/src/en/guide/theWebLayer/interceptors/interceptorOrdering.gdoc @@ -1 +1,52 @@ -TBD +Interceptors can be ordered by defining an @order@ property that defines a priority. + +For example: + +{code} +class AuthInterceptor { + + int order = HIGHEST_PRECEDENCE + + ... +} +{code} + +The default value of the @order@ property is 0. + +The values @HIGHEST_PRECEDENCE@ and @LOWEST_PRECEDENCE@ can be used to define filters that should should run first or last respectively. + +Note that if you write an interceptor that is to be used by others it is better increment or decrement the @HIGHEST_PRECEDENCE@ and @LOWEST_PRECEDENCE@ to allow other interceptors to be inserted before or after the interceptor you are authoring: + +{code} +int order = HIGHEST_PRECEDENCE + 50 + +// or + +int order = LOWEST_PRECEDENCE - 50 +{code} + +To find out the computed order of interceptors you can add a debug logger to @logback.groovy@ as follows: + +{code} +logger 'grails.artefact.Interceptor', DEBUG, ['STDOUT'], false +{code} + +You can override any interceptors default order by using bean override configuration in @grails-app/conf/application.yml@: + +{code} +beans: + authInterceptor: + order: 50 +{code} + +Or in @grails-app/conf/application.groovy@: + +{code} +beans { + authInterceptor { + order = 50 + } +} +{code} + +Thus giving you complete control over interceptor execution order. From 9b7286dabee80fe27772f2564ee1fac1c90a8c57 Mon Sep 17 00:00:00 2001 From: Graeme Rocher Date: Sat, 7 Feb 2015 20:08:00 +0100 Subject: [PATCH 062/230] tweak Gradle opts --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 9e46b487abd..f53d605fd64 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,6 +3,7 @@ jdk: - openjdk7 env: global: + - GRADLE_OPTS="-server -Xmx1024M -Xms768M -XX:PermSize=256m -XX:MaxPermSize=512m" - GIT_NAME="Graeme Rocher" - GIT_EMAIL="graeme.rocher@gmail.com" - secure: SdGzn2ItEkM0UGzByv/0yXLO7g9iJYmrSIgQ3a1yZXvOerQOLuOwwTZIJ4LUBJpJcQRhiAff1HidN/6fAGAd4mwgoQcX1kKdrRHIl0oG7V7DC9YRytPko/gasQ6aPoR3GBBpLqx8hIjGYbVKIrPWgMSRRA7DSvbzI5XlOgAX1Dg= From 18ca99139d7f0d255be92bb6aeef0f833f312bc3 Mon Sep 17 00:00:00 2001 From: Jeff Scott Brown Date: Thu, 12 Feb 2015 12:45:52 -0600 Subject: [PATCH 063/230] GRAILS-9528 - remove reference to mockFor --- src/en/guide/testing/unitTesting.gdoc | 30 ++------------------------- 1 file changed, 2 insertions(+), 28 deletions(-) diff --git a/src/en/guide/testing/unitTesting.gdoc b/src/en/guide/testing/unitTesting.gdoc index 4fe5795f6b1..4e54d8e594d 100644 --- a/src/en/guide/testing/unitTesting.gdoc +++ b/src/en/guide/testing/unitTesting.gdoc @@ -35,33 +35,7 @@ Most testing can be achieved via the @TestFor@ annotation in combination with th The @TestFor@ annotation defines the class under test and will automatically create a field for the type of class under test. For example in the above case a "controller" field will be present, however if @TestFor@ was defined for a service a "service" field would be created and so on. -The @Mock@ annotation creates mock version of any collaborators. There is an in-memory implementation of GORM that will simulate most interactions with the GORM API. For those interactions that are not automatically mocked you can use the built in support for defining mocks and stubs programmatically. For example: - - -{code} -import grails.test.mixin.TestFor -import spock.lang.Specification - -@TestFor(BookController) -@Mock(Book) -class BookControllerSpec extends Specification { - - void "test search"() { - given: - def searchMock = mockFor(SearchService) - searchMock.demand.searchWeb { String q -> ['first result', 'second result'] } - searchMock.demand.static.logResults { List results -> } - controller.searchService = searchMock.createMock() - - when: - controller.search() - - then: - controller.response.text.contains "Found 2 results" - } -} -{code} - +The @Mock@ annotation creates mock version of any collaborators. There is an in-memory implementation of GORM that will simulate most interactions with the GORM API. h4. doWithSpring and doWithConfig callback methods, FreshRuntime annotation @@ -143,7 +117,7 @@ class TestInstanceCallbacksSpec extends Specification { } def "doWithConfig callback is executed"(){ - expect: + expect: config.myConfigValue == 'Hello' } } From f77701fa533440fc991fde20a411a844319cb0fb Mon Sep 17 00:00:00 2001 From: graemerocher Date: Thu, 19 Feb 2015 11:40:55 +0100 Subject: [PATCH 064/230] =?UTF-8?q?fix=20doc=20build:=20don=E2=80=99t=20re?= =?UTF-8?q?ly=20on=20grails-core=20build.properties?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 4 ++-- gradle.properties | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 gradle.properties diff --git a/build.gradle b/build.gradle index 586f1da6a91..b722f94b4ab 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,6 @@ apply plugin: "base" -version = System.getProperty("grails.version") ?: "3.0.0.BUILD-SNAPSHOT" +version = project.getProperty("grails.version") archivesBaseName = "grails-docs" @@ -80,7 +80,7 @@ task publishGuide(type: grails.doc.gradle.PublishGuide, dependsOn: ['apiDocs', ' // generated with a 'en' in the path, but the source is in 'en' // so that it's easy to track with git. sourceDir = new File(projectDir, "src/en") - propertiesFiles = [ new File(project.grailsHome, "build.properties") ] + propertiesFiles = [ new File(projectDir, "gradle.properties") ] macros = [ new grails.doc.macros.GspTagSourceMacro(searchDirs) ] } diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 00000000000..02cb42adb20 --- /dev/null +++ b/gradle.properties @@ -0,0 +1 @@ +grails.version="3.0.0.BUILD-SNAPSHOT" From 4b6a07d6dd87fc719c258b8048a9e2a18b5b149a Mon Sep 17 00:00:00 2001 From: graemerocher Date: Thu, 19 Feb 2015 14:27:28 +0100 Subject: [PATCH 065/230] fix NPE problems and broken API links --- build.gradle | 8 +++-- gradle/wrapper/gradle-wrapper.jar | Bin 51348 -> 51018 bytes gradle/wrapper/gradle-wrapper.properties | 4 +-- resources/doc.properties | 6 ++-- .../gradleBuild/gradleDependencies.gdoc | 29 +++++++++--------- src/en/guide/testing/functionalTesting.gdoc | 2 +- .../interceptors/definingInterceptors.gdoc | 8 +++-- 7 files changed, 31 insertions(+), 26 deletions(-) diff --git a/build.gradle b/build.gradle index b722f94b4ab..029af902e3b 100644 --- a/build.gradle +++ b/build.gradle @@ -22,11 +22,15 @@ buildscript { } dependencies { - classpath "org.grails:grails-docs:3.0.0.M1" + classpath "org.grails:grails-docs:3.0.0.BUILD-SNAPSHOT" classpath 'org.codehaus.groovy:groovy-all:2.4.0' } } +task buildscriptDependencies(type: DependencyReportTask) { + configurations = [buildscript.configurations.classpath] +} + // use jsoup in PdfBuilder for cleaning input html System.setProperty('grails.docs.clean.html','true') // creates single.html.before.xml and single.html.after.xml files for debugging pdf input when enabled @@ -57,7 +61,7 @@ fetchGrailsSource.onlyIf { !explicitGrailsHome } task apiDocs(type: Exec, dependsOn: 'fetchGrailsSource') { commandLine = ["./gradlew", "groovydoc"] workingDir = "${checkOutDir}/grails-src" - + environment "GRADLE_OPTS", "-Xmx2048m -Xms256m -XX:MaxPermSize=512m -XX:+CMSClassUnloadingEnabled -XX:+HeapDumpOnOutOfMemoryError" } apiDocs.onlyIf { !System.getProperty("disable.groovydocs") } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 0087cd3b18659b5577cf6ad3ef61f8eb9416ebba..c97a8bdb9088d370da7e88784a7a093b971aa23a 100644 GIT binary patch delta 10956 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 delta 11402 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.+?/ diff --git a/src/en/guide/commandLine/gradleBuild/gradleDependencies.gdoc b/src/en/guide/commandLine/gradleBuild/gradleDependencies.gdoc index 15717e4e425..7d0b66fcb4e 100644 --- a/src/en/guide/commandLine/gradleBuild/gradleDependencies.gdoc +++ b/src/en/guide/commandLine/gradleBuild/gradleDependencies.gdoc @@ -5,26 +5,26 @@ The default dependencies for the "web" profile can be seen below: {code} dependencies { compile 'org.springframework.boot:spring-boot-starter-logging' - compile("org.springframework.boot:spring-boot-starter-actuator") - compile "org.springframework.boot:spring-boot-autoconfigure" - compile "org.springframework.boot:spring-boot-starter-tomcat" - compile "org.grails:grails-dependencies:$grailsVersion" - compile "org.grails:grails-web-boot:$grailsVersion" + compile('org.springframework.boot:spring-boot-starter-actuator') + compile 'org.springframework.boot:spring-boot-autoconfigure' + compile 'org.springframework.boot:spring-boot-starter-tomcat' + compile 'org.grails:grails-dependencies' + compile 'org.grails:grails-web-boot' - compile "org.grails.plugins:hibernate" - compile "org.grails.plugins:cache" - compile "org.hibernate:hibernate-ehcache" + compile 'org.grails.plugins:hibernate' + compile 'org.grails.plugins:cache' + compile 'org.hibernate:hibernate-ehcache' - runtime "org.grails.plugins:asset-pipeline" - runtime "org.grails.plugins:scaffolding" + runtime 'org.grails.plugins:asset-pipeline' + runtime 'org.grails.plugins:scaffolding' - testCompile "org.grails:grails-plugin-testing" - testCompile "org.grails.plugins:geb" + testCompile "org.grails:grails-plugin-testing' + testCompile "org.grails.plugins:geb' // Note: It is recommended to update to a more robust driver (Chrome, Firefox etc.) testRuntime 'org.seleniumhq.selenium:selenium-htmlunit-driver:2.44.0' - console "org.grails:grails-console" + console 'org.grails:grails-console' } {code} @@ -33,9 +33,8 @@ Note that version numbers are not present in the majority of the dependencies. T {code} dependencyManagement { imports { - mavenBom "org.grails:grails-bom:$grailsVersion" + mavenBom 'org.grails:grails-bom:' + grailsVersion } applyMavenExclusions false } {code} - diff --git a/src/en/guide/testing/functionalTesting.gdoc b/src/en/guide/testing/functionalTesting.gdoc index 2d08f421d1e..adfb23a0bb4 100644 --- a/src/en/guide/testing/functionalTesting.gdoc +++ b/src/en/guide/testing/functionalTesting.gdoc @@ -23,7 +23,7 @@ class HomeSpec extends GebSpec { go '/' then:"The title is correct" - $('title').text() == "Welcome to Grails" + \$('title').text() == "Welcome to Grails" } } diff --git a/src/en/guide/theWebLayer/interceptors/definingInterceptors.gdoc b/src/en/guide/theWebLayer/interceptors/definingInterceptors.gdoc index 85bc5fa52f0..28fb9658528 100644 --- a/src/en/guide/theWebLayer/interceptors/definingInterceptors.gdoc +++ b/src/en/guide/theWebLayer/interceptors/definingInterceptors.gdoc @@ -23,9 +23,11 @@ An @Interceptor@ implements the [Interceptor|api:grails.artefact.Interceptor] tr void afterView() {} {code} -As described above the @before@ method is executed prior to an action and can cancel the execution of the action by returning @false. +As described above the @before@ method is executed prior to an action and can cancel the execution of the action by returning @false@. + +The @after@ method is executed after an action executes and can halt view rendering if it returns false. The @after@ method can also modify the view or model using the @view@ and @model@ properties respectively: + -The @after@ method is executed after an action executes and can halt view rendering if it returns false. The @after@ method can also modify the view or model using the @view@ and @model@ properties: {code} boolean after() { @@ -35,4 +37,4 @@ boolean after() { } {code} -The @afterView@ method is executed after view rendering completes and if an exception occurs, the exception is available using the @throwable@ property of the [Interceptor|api:grails.artefact.Interceptor] trait. +The @afterView@ method is executed after view rendering completes and if an exception occurs, the exception is available using the @throwable@ property of the [Interceptor|api:grails.artefact.Interceptor] trait. From 3fe9774443f1dcc149e41da552bc10d459d8a9e9 Mon Sep 17 00:00:00 2001 From: graemerocher Date: Thu, 19 Feb 2015 16:23:33 +0100 Subject: [PATCH 066/230] use --info to debug build on Travis --- travis-build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/travis-build.sh b/travis-build.sh index ab6e8bc158a..ebc3528d53d 100755 --- a/travis-build.sh +++ b/travis-build.sh @@ -8,7 +8,7 @@ echo "https://$GH_TOKEN:@github.com" > ~/.git-credentials export GRADLE_OPTS="-Xmx2048m -Xms256m -XX:MaxPermSize=512m -XX:+CMSClassUnloadingEnabled -XX:+HeapDumpOnOutOfMemoryError" -./gradlew assemble +./gradlew assemble --info if [[ $TRAVIS_PULL_REQUEST == 'false' ]]; then From 7b1061f19e473bb815dfd9eacbe3a157b681da48 Mon Sep 17 00:00:00 2001 From: Jeff Scott Brown Date: Thu, 19 Feb 2015 15:21:45 -0600 Subject: [PATCH 067/230] Use Gradle 2.3 --- gradle/wrapper/gradle-wrapper.jar | Bin 51018 -> 52141 bytes gradle/wrapper/gradle-wrapper.properties | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index c97a8bdb9088d370da7e88784a7a093b971aa23a..085a1cdc27db1185342f15a00441734e74fe3735 100644 GIT binary patch delta 14216 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
b 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 Date: Thu, 19 Feb 2015 15:39:05 -0600 Subject: [PATCH 068/230] document applicationClass attribute from @Integration --- src/en/guide/testing/functionalTesting.gdoc | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/en/guide/testing/functionalTesting.gdoc b/src/en/guide/testing/functionalTesting.gdoc index adfb23a0bb4..6a63607cef0 100644 --- a/src/en/guide/testing/functionalTesting.gdoc +++ b/src/en/guide/testing/functionalTesting.gdoc @@ -34,3 +34,16 @@ When the test is run the application container will be loaded up in the backgrou Note that the application is only loaded once for the entire test run, so functional tests share the state of the application across the whole suite. In addition the application is loaded in the JVM as the test, this means that the test has full access to the application state and can interact directly with data services such as GORM to setup and cleanup test data. + +The @Integration@ annotation supports an optional @applicationClass@ attribute which may be used to specify the application class to use for the functional test. The class must extend [GrailsAutoConfiguration|api:grails.boot.config.GrailsAutoConfiguration]. + +{code} +@Integration(applicationClass=com.demo.Application) +class HomeSpec extends GebSpec { + + // ... + +} +{code} + +If the @applicationClass@ is not specified then the test runtime environment will attempt to locate the application class dynamically which can be problematic in multiproject builds where multiple application classes may be present. From 5de8ad75d187c3fe1353a736a9c7f61473b9a1b2 Mon Sep 17 00:00:00 2001 From: graemerocher Date: Fri, 20 Feb 2015 09:32:06 +0100 Subject: [PATCH 069/230] add --stacktrace flag --- travis-build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/travis-build.sh b/travis-build.sh index ebc3528d53d..53a698f8351 100755 --- a/travis-build.sh +++ b/travis-build.sh @@ -8,7 +8,7 @@ echo "https://$GH_TOKEN:@github.com" > ~/.git-credentials export GRADLE_OPTS="-Xmx2048m -Xms256m -XX:MaxPermSize=512m -XX:+CMSClassUnloadingEnabled -XX:+HeapDumpOnOutOfMemoryError" -./gradlew assemble --info +./gradlew assemble --info --stacktrace if [[ $TRAVIS_PULL_REQUEST == 'false' ]]; then From 3785ec5cbfbfb08c39ebb3f7e4faaf894e8a67da Mon Sep 17 00:00:00 2001 From: graemerocher Date: Fri, 20 Feb 2015 09:35:10 +0100 Subject: [PATCH 070/230] add --info and --stacktrace to forked process --- build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/build.gradle b/build.gradle index 029af902e3b..bd1badcd87f 100644 --- a/build.gradle +++ b/build.gradle @@ -60,6 +60,7 @@ fetchGrailsSource.onlyIf { !explicitGrailsHome } task apiDocs(type: Exec, dependsOn: 'fetchGrailsSource') { commandLine = ["./gradlew", "groovydoc"] + args = ['--info', '--stacktrace'] workingDir = "${checkOutDir}/grails-src" environment "GRADLE_OPTS", "-Xmx2048m -Xms256m -XX:MaxPermSize=512m -XX:+CMSClassUnloadingEnabled -XX:+HeapDumpOnOutOfMemoryError" } From 9c2be89a51c195b0cd7049d337a3e196f915d47d Mon Sep 17 00:00:00 2001 From: graemerocher Date: Fri, 20 Feb 2015 09:46:55 +0100 Subject: [PATCH 071/230] fix --info and --stactrace use in build.gradle --- build.gradle | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index bd1badcd87f..99102d6dca2 100644 --- a/build.gradle +++ b/build.gradle @@ -59,8 +59,7 @@ task fetchGrailsSource << { fetchGrailsSource.onlyIf { !explicitGrailsHome } task apiDocs(type: Exec, dependsOn: 'fetchGrailsSource') { - commandLine = ["./gradlew", "groovydoc"] - args = ['--info', '--stacktrace'] + commandLine = ["./gradlew", "groovydoc", '--info', '--stacktrace'] workingDir = "${checkOutDir}/grails-src" environment "GRADLE_OPTS", "-Xmx2048m -Xms256m -XX:MaxPermSize=512m -XX:+CMSClassUnloadingEnabled -XX:+HeapDumpOnOutOfMemoryError" } From fa4ff06798167801369432f49f1f3b35b7c44a65 Mon Sep 17 00:00:00 2001 From: graemerocher Date: Fri, 20 Feb 2015 10:25:20 +0100 Subject: [PATCH 072/230] Try container based infrastructure --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index f53d605fd64..c3e82c348d6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,5 @@ script: ./travis-build.sh +sudo: false jdk: - openjdk7 env: From a18415e144fe9e91ebb46df618cc9608ad8c3a85 Mon Sep 17 00:00:00 2001 From: graemerocher Date: Fri, 20 Feb 2015 13:48:15 +0100 Subject: [PATCH 073/230] Some initial docs on upgrading plugins, still a WIP --- .../interceptors/interceptorMatching.gdoc | 2 +- src/en/guide/upgradingFrom2.gdoc | 192 +++++++++++++++++- 2 files changed, 192 insertions(+), 2 deletions(-) diff --git a/src/en/guide/theWebLayer/interceptors/interceptorMatching.gdoc b/src/en/guide/theWebLayer/interceptors/interceptorMatching.gdoc index 39280a487d6..40460720353 100644 --- a/src/en/guide/theWebLayer/interceptors/interceptorMatching.gdoc +++ b/src/en/guide/theWebLayer/interceptors/interceptorMatching.gdoc @@ -1,6 +1,6 @@ As mention in the previous section, by default an interceptor will match only requests to the associated controller by convention. However you can configure the interceptor to match any request using the @match@ or @matchAll@ methods defined in the [Interceptor API|api:grails.artefact.Interceptor]. -The matching methods return a [Matcher|api:grails.artefact.Interceptor] instance which can be used to configure how the interceptor matches the request. +The matching methods return a [Matcher|api:grails.interceptors.Matcher] instance which can be used to configure how the interceptor matches the request. For example the following interceptor will match all requests except those to the @login@ controller: diff --git a/src/en/guide/upgradingFrom2.gdoc b/src/en/guide/upgradingFrom2.gdoc index a0990367ef8..c5a4ce571f3 100644 --- a/src/en/guide/upgradingFrom2.gdoc +++ b/src/en/guide/upgradingFrom2.gdoc @@ -1 +1,191 @@ -TBD +Grails 3.0 is a complete ground up rewrite of Grails and introduces new concepts and components for many parts of the framework. + +When upgrading an application or plugin from Grails 3.0 there are many areas to consider including: + +* Project structure differences +* File location differences +* Configuration differences +* Package name differences +* Legacy Gant Scripts +* Gradle Build System +* Changes to Plugins +* Source vs Binary Plugins + +The best approach to take when upgrading a plugin or application (and if your application is using several plugins the plugins will need upgrading first) is to create a new Grails 3.0 application of the same name and copy the source files into the correct locations in the new application. + +h3. Project Structure Changes + +h4. File Location Differences + +The location of certain files have changed or been replaced with other files in Grails 3.0. The following table lists old default locations and their respective new locations: + +{table} +*Old Location* | *New Location* | *Description* +@grails-app/conf/BuildConfig.groovy@ | @build.gradle@ | Build time configuration is now defined in a Gradle build file +@grails-app/conf/Config.groovy@ | @grails-app/conf/application.groovy@ | Renamed for consistency with Spring Boot +@grails-app/conf/UrlMappings.groovy@ | @grails-app/controllers/UrlMappings.groovy@ | Moved since grails-app/conf is not a source directory anymore +@grails-app/conf/BootStrap.groovy@ | @grails-app/init/BootStrap.groovy@ | Moved since grails-app/conf is not a source directory anymore +@scripts@ | @src/main/scripts@ | Moved for consistency with Gradle +@src/groovy@ | @src/main/groovy@ | Moved for consistency with Gradle +@src/java@ | @src/main/groovy@ | Moved for consistency with Gradle +@test/unit@ | @src/test/groovy@ | Moved for consistency with Gradle +@test/integration@ | @src/integration-test/groovy@ | Moved for consistency with Gradle +@web-app@ | @src/main/webapp@ | Moved for consistency with Gradle +@\*GrailsPlugin.groovy@ | @src/main/groovy@ | The plugin descriptor moved to a source directory +{table} + +For plugins the plugin descriptor (a Groovy file ending with "GrailsPlugin") which was previously located in the root of the plugin directory should be moved to the @src/main/groovy@ directory under an appropriate package. + +h4. New Files Not Present in Grails 2.x + +The reason it is best to create a new application and copy your original sources to it is because there are a number of new files that are not present in Grails 2.x by default. These include: + +{table} +*File* | *Description* +@build.gradle@ | The Gradle build descriptor located in the root of the project +@gradle.properties@ | Properties file defining the Grails and Gradle versions +@grails-app/conf/logback.groovy@ | Logging previously defined in @Config.groovy@ is now defined using Logback +@grails-app/conf/application.yml@ | Configuration can now also be defined using YAML +@grails-app/init/PACKAGE_PATH/Application.groovy@ | The @Application@ class used By Spring Boot to start the application +{table} + +h4. Files Not Present in Grails 3.x + +Some files that were previously created by Grails 2.x are no longer created. These have either been removed or an appropriate replacement added. The following table lists files no longer in use: + +{table} +*File* | *Description* +@application.properties@ | The application name and version is now defined in @build.gradle@ +@grails-app/conf/DataSource.groovy@ | Merged together into @application.yml@ +@lib@ | Dependency resolution should be used to resolve JAR files +@web-app/WEB-INF/applicationContext.xml@ | Removed, beans can be defined in @grails-app/conf/spring/resources.groovy@ +@src/templates/war/web.xml@ | Grails 3.0 no longer requires web.xml. Customizations can be done via Spring +@web-app/WEB-INF/sitemesh.xml@ | Removed, sitemesh filter no longer present. +@web-app/WEB-INF/tld@ | Removed, can be restored in src/main/webapp +{table} + +h3. Upgrading a Plugin to Grails 3.x + +To upgrade a Grails 2.x plugin to Grails 3.x you need to make a number of different changes. This documentation will outline the steps that were taken to upgrade the Quartz plugin to Grails 3, each individual plugin may differ. + +h4. Step 1 - Create a new Grails 3 plugin + +The first step is to create a new Grails 3 plugin using the command line: + +{code} +$ grails create-plugin quartz +{code} + +This will create a Grails 3 plugin in the @quartz@ directory. + +h4. Step 2 - Copy sources from the original Grails 2 plugin + +The next step is to copy the sources from the original Grails 2 plugin to the Grails 3 plugin: + +{code} +# first the sources +cp -rf ../quartz-2.x/src/groovy src/main/groovy +cp -rf ../quartz-2.x/src/java src/main/groovy +cp -rf ../quartz-2.x/grails-app grails-app +cp -rf ../quartz-2.x/QuartzGrailsPlugin.groovy src/main/groovy/grails/plugins/quartz + +# then the tests +cp -rf ../quartz-2.x/test/unit src/test/groovy +mkdir -p src/integration-test/groovy +cp -rf ../quartz-2.x/test/integration src/integration-test/groovy + +# then templates / other resources +cp -rf ../quartz-2.x/src/templates src/main/templates +{code} + +You will need to add a package declaration to the plugin descriptor. In this case @QuartzGrailsPlugin@ is modified as follows: + +{code} +// add package declaration +package grails.plugins.quartz +... +class QuartzGrailsPlugin { + ... +} +{code} + +h4. Step 3 - Update the Gradle build with required dependencies + +The repositories and dependencies defined in @grails-app/conf/BuildConfig.groovy@ of the original Grails 2.x plugin will need to be defined in @build.gradle@ of the new Grails 3.x plugin: + +{code} + compile("org.quartz-scheduler:quartz:2.2.1") { + exclude group: 'slf4j-api', module: 'c3p0' + } +{code} + +h4. Step 4 - Modify Package Imports + +In Grails 3.x all internal APIs can be found in the @org.grails@ package and public facing APIs in the @grails@ package. The @org.codehaus.groovy.grails@ package no longer exists. + +All package declaration in sources should be modified for the new location of the respective classes. Example @org.codehaus.groovy.grails.commons.GrailsApplication@ is now @grails.core.GrailsApplication@. + +h4. Step 5 - Migrate Plugin Specific Config to application.yml + +Some plugins define a default configuration fail. For example the Quartz plugin defines a file called @grails-app/conf/DefaultQuartzConfig.groovy@. In Grails 3.x this default configuration can be migrated to @grails-app/conf/application.yml@ and it will automatically be loaded by Grails without requiring manual configuration merging. + +h4. Step 6 - Register ArtefactHandler Definitions + +In Grails 3.x ArtefactHandler definitions need to be declared in a file called @src/main/resources/META-INF/grails.factories@ since these need to be known at compile time. The Quartz plugin requires the following definition to register the ArtrefactHandler: + +{code} +grails.core.ArtefactHandler=grails.plugins.quartz.JobArtefactHandler +{code} + +h4. Step 7 - Migrate Code Generation Scripts + +Many plugins previously defined command line scripts in Gant. In Grails 3.x command line scripts have been replaced by two new features: Code generation scripts and Gradle tasks. + +If your script is doing simple code generation then for many cases a code generation script can replace an old Gant script. + +The @create-job@ script provided by the Quartz plugin in Grails 2.x was defined in @scripts/CreateJob.groovy@ as: + +{code} +includeTargets << grailsScript("_GrailsCreateArtifacts") + +target(createJob: "Creates a new Quartz scheduled job") { + depends(checkVersion, parseArguments) + + def type = "Job" + promptForName(type: type) + + for (name in argsMap.params) { + name = purgeRedundantArtifactSuffix(name, type) + createArtifact(name: name, suffix: type, type: type, path: "grails-app/jobs") + createUnitTest(name: name, suffix: type) + } +} + +setDefaultTarget 'createJob' +{code} + +A replacement Grails 3.x compatible script can be created using the @create-script@ command: + +{code} +$ grails create-script create-job +{code} + +Which creates a new script called @src/main/scripts/create-job.groovy@. Using the new code generation API it is simple to implement: + +{code} +description("Creates a new Quartz scheduled job") { + usage "grails create-job [JOB NAME]" + argument name:'Job Name', description:"The name of the job" +} + +model = model( args[0] ) +render template:"Job.groovy", + destination: file( "grails-app/jobs/$model.packagePath/${model.simpleName}Job.groovy"), + model: model +{code} + +Please refer to the documentation on [Creating Custom Scripts|guide:creatingCustomScripts] for more information. + +h4. Migrating More Complex Scripts Using Gradle Tasks + +Using the old Grails 2.x build system it was relatively common to spin up Grails inside the command line. In Grails 3.x it is not possible to load a Grails application within a command line script. From ac46416d0209b2348a32349306c60696c327594b Mon Sep 17 00:00:00 2001 From: graemerocher Date: Fri, 20 Feb 2015 13:48:28 +0100 Subject: [PATCH 074/230] cache certain directories to improve build performance --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.travis.yml b/.travis.yml index c3e82c348d6..8ac462544e5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,6 +9,10 @@ env: - GIT_EMAIL="graeme.rocher@gmail.com" - secure: SdGzn2ItEkM0UGzByv/0yXLO7g9iJYmrSIgQ3a1yZXvOerQOLuOwwTZIJ4LUBJpJcQRhiAff1HidN/6fAGAd4mwgoQcX1kKdrRHIl0oG7V7DC9YRytPko/gasQ6aPoR3GBBpLqx8hIjGYbVKIrPWgMSRRA7DSvbzI5XlOgAX1Dg= - secure: R9aL92lh09LniCTbiZuuikiWHXL4ik/DDAKe7NLanqpI126vs5Y9zd56JifgN8Mp7sEbwlaM4RzFXpgkdl57FZqdDzC04ljeqy9Z4CmGthUCF2o2exV98HFWxrL6J18OH5zVSBtZJN0ANcgdJ3/+vMuk2wyS61qhl36uiUM66tM= +cache: + directories: + - $HOME/.gradle/wrapper + - $HOME/.gradle/caches deploy: provider: releases api_key: From 0ef3e027326085451b56695c2428a87ea2f7983f Mon Sep 17 00:00:00 2001 From: graemerocher Date: Fri, 20 Feb 2015 14:16:16 +0100 Subject: [PATCH 075/230] remove quotes from version --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 02cb42adb20..020faca0686 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1 @@ -grails.version="3.0.0.BUILD-SNAPSHOT" +grails.version=3.0.0.BUILD-SNAPSHOT From 71e982f427e76f9816711e104d4e4a9b984ae52a Mon Sep 17 00:00:00 2001 From: Graeme Rocher Date: Sun, 22 Feb 2015 13:19:25 +0100 Subject: [PATCH 076/230] disable snapshot doc publishing for the moment. It results in commits that are too large atm. --- travis-build.sh | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/travis-build.sh b/travis-build.sh index 53a698f8351..45acd387aaa 100755 --- a/travis-build.sh +++ b/travis-build.sh @@ -12,25 +12,16 @@ export GRADLE_OPTS="-Xmx2048m -Xms256m -XX:MaxPermSize=512m -XX:+CMSClassUnloadi if [[ $TRAVIS_PULL_REQUEST == 'false' ]]; then - git clone https://${GH_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git -b gh-pages gh-pages --single-branch > /dev/null - cd gh-pages - - # If this is the master branch then update the snapshot - if [[ $TRAVIS_BRANCH == 'master' ]]; then - mkdir -p snapshot - cp -r ../build/docs/. ./snapshot/ - - git add snapshot/* - fi # If there is a tag present then this becomes the latest if [[ -n $TRAVIS_TAG ]]; then + git clone https://${GH_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git -b gh-pages gh-pages --single-branch > /dev/null + cd gh-pages + version="$TRAVIS_TAG" version=${version:1} zipName="grails-docs-$version" export RELEASE_FILE="${zipName}.zip" -# github-release upload --user grails --repo grails-core --tag $TRAVIS_TAG --name grails-docs-${version}.zip --file build/distributions/$RELEASE_FILE - milestone=${version:5} if [[ -n $milestone ]]; then git rm -rf latest/ @@ -49,11 +40,11 @@ if [[ $TRAVIS_PULL_REQUEST == 'false' ]]; then mkdir -p "$majorVersion" cp -r ../build/docs/. "./$majorVersion/" git add "$majorVersion/*" + git commit -a -m "Updating docs for Travis build: https://travis-ci.org/$TRAVIS_REPO_SLUG/builds/$TRAVIS_BUILD_ID" + git push origin HEAD + cd .. + rm -rf gh-pages fi - git commit -a -m "Updating docs for Travis build: https://travis-ci.org/$TRAVIS_REPO_SLUG/builds/$TRAVIS_BUILD_ID" - git push origin HEAD - cd .. - rm -rf gh-pages fi From 3b4dd8c4a2e6e6e73f13536175fe452e03e30352 Mon Sep 17 00:00:00 2001 From: Graeme Rocher Date: Sun, 22 Feb 2015 13:54:05 +0100 Subject: [PATCH 077/230] update section on creating and installing plugins for Grails 3.0 --- .../plugins/creatingAndInstallingPlugins.gdoc | 98 +++++++++---------- 1 file changed, 46 insertions(+), 52 deletions(-) diff --git a/src/en/guide/plugins/creatingAndInstallingPlugins.gdoc b/src/en/guide/plugins/creatingAndInstallingPlugins.gdoc index adb84adab8f..aa73f2637e1 100644 --- a/src/en/guide/plugins/creatingAndInstallingPlugins.gdoc +++ b/src/en/guide/plugins/creatingAndInstallingPlugins.gdoc @@ -8,15 +8,17 @@ grails create-plugin [PLUGIN NAME] This will create a plugin project for the name you specify. For example running @grails create-plugin example@ would create a new plugin project called @example@. -Make sure the plugin name does not contain more than one capital in a row, or it won't work. Camel case is fine, though. +In Grails 3.0 you should consider whether the plugin you create requires a web environment or whether the plugin can be used with other profiles. If you plugin does not require a web environment then use the "plugin" profile instead of the "web-plugin" profile: -The structure of a Grails plugin is very nearly the same as a Grails application project's except that in the root of the plugin directory you will find a plugin Groovy file called the "plugin descriptor". +{code:java} +grails create-plugin [PLUGIN NAME] --profile=plugin +{code} -{note} -The only plugins included in a new plugin project are Tomcat and Release. Hibernate is not included by default. -{note} +Make sure the plugin name does not contain more than one capital in a row, or it won't work. Camel case is fine, though. -Being a regular Grails project has a number of benefits in that you can immediately test your plugin by running: +The structure of a Grails plugin is very nearly the same as a Grails application project's except that in the @src/main/groovy@ directory under the plugin package structure you will find a plugin descriptor class (a class that ends in "GrailsPlugin"). + +Being a regular Grails project has a number of benefits in that you can immediately test your plugin by running (if the plugin targets the "web" profile): {code:java} grails run-app @@ -30,18 +32,15 @@ The plugin descriptor name ends with the convention @GrailsPlugin@ and is found {code:java} class ExampleGrailsPlugin { - def version = "0.1" - ... } {code} -All plugins must have this class in the root of their directory structure. The plugin class defines the version of the plugin and other metadata, and optionally various hooks into plugin extension points (covered shortly). +All plugins must have this class under the @src/main/groovy@ directory, otherwise they are not regarded as a plugin. The plugin class defines metadata about the plugin, and optionally various hooks into plugin extension points (covered shortly). You can also provide additional information about your plugin using several special properties: * @title@ - short one-sentence description of your plugin -* @version@ - The version of your plugin. Valid values include example "0.1", "0.2-SNAPSHOT", "1.1.4" etc. * @grailsVersion@ - The version of version range of Grails that the plugin supports. eg. "1.2 > *" (indicating 1.2 or higher) * @author@ - plugin author's name * @authorEmail@ - plugin author's contact e-mail @@ -52,7 +51,6 @@ Here is an example from the [Quartz Grails plugin|http://grails.org/plugin/quart {code:java} class QuartzGrailsPlugin { - def version = "0.1" def grailsVersion = "1.1 > *" def author = "Sergey Nebolsin" def authorEmail = "nebolsin@gmail.com" @@ -71,80 +69,76 @@ via Spring, but is made simpler by the coding by convention paradigm.\\\ h4. Installing Local Plugins -To make your plugin available for use in a Grails application run the @maven-install@ command: +To make your plugin available for use in a Grails application run the @install@ command: {code:java} -grails maven-install +grails install {code} -This will install the plugin into your local Maven cache. Then to use the plugin within an application declare a dependency on the plugin in your @grails-app/conf/BuildConfig.groovy@ file: +This will install the plugin into your local Maven cache. Then to use the plugin within an application declare a dependency on the plugin in your @build.gradle@ file: {code:java} -compile "\:quartz:0.1" +compile "org.grails.plugins:quartz:0.1" {code} +{note} +In Grails 2.x plugins were packaged as ZIP files, however in Grails 3.x plugins are simple JAR files that can be added to the classpath of the IDE. +{note} h4. Notes on excluded Artefacts Although the [create-plugin|commandLine] command creates certain files for you so that the plugin can be run as a Grails application, not all of these files are included when packaging a plugin. The following is a list of artefacts created, but not included by [package-plugin|commandLine]: -* @grails-app/conf/BootStrap.groovy@ -* @grails-app/conf/BuildConfig.groovy@ (although it is used to generate @dependencies.groovy@) -* @grails-app/conf/Config.groovy@ -* @grails-app/conf/DataSource.groovy@ (and any other @*DataSource.groovy@) -* @grails-app/conf/UrlMappings.groovy@ +* @grails-app/build.gradle@ (although it is used to generate @dependencies.groovy@) +* @grails-app/conf/application.yml@ (renamed to plugin.yml) * @grails-app/conf/spring/resources.groovy@ -* Everything within @/web-app/WEB-INF@ -* Everything within @/web-app/plugins/\*\*@ -* Everything within @/test/\*\*@ +* @grails-app/conf/logback.groovy@ +* Everything within @/src/test/\*\*@ * SCM management files within @\*\*/.svn/\*\*@ and @\*\*/CVS/\*\*@ -If you need artefacts within @WEB-INF@ it is recommended you use the @_Install.groovy@ script (covered later), which is executed when a plugin is installed, to provide such artefacts. In addition, although @UrlMappings.groovy@ is excluded you are allowed to include a @UrlMappings@ definition with a different name, such as @MyPluginUrlMappings.groovy@. - h4. Customizing the plugin contents -You can specify what to exclude in addition to the default excludes by adding elements to the @pluginExcludes@ descriptor property (described below). In addition, there are two ways to configure the contents of the plugin ZIP or JAR file. +When developing a plugin you may create test classes and sources that are used during the development and testing of the plugin but should not be exported to the application. -One is to create an event handler for the @CreatePluginArchiveStart@ event, which is fired after all of the plugin files have been copied to the staging directory. By adding an event handler you can add, modify, or delete files as needed. Add the handler to @_Events.groovy@ in the @scripts@ directory, for example +To exclude test sources you need to modify the @pluginExcludes@ property of the plugin descriptor AND exclude the resources inside your @build.gradle@ file. For example say you have some classes under the @com.demo@ package that are in your plugin source tree but should not be packaged in the application. In your plugin descriptor you should exclude these: {code} -eventCreatePluginArchiveStart = { stagingDir -> - // update staging directory contents here -} + // resources that should be loaded by the plugin once installed in the application + def pluginExcludes = [ + '**/com/demo/**' + ] {code} -You can customize the location of the staging directory with the @grails.project.plugin.staging.dir@ attribute in @BuildConfig.groovy@ or as as system property. - -Note that there is also a @CreatePluginArchiveEnd@ event which is fired after the ZIP or JAR is packaged. - -You can also do this work in a Closure in @BuildConfig.groovy@ with the property @grails.plugin.resources@ which is analogous to the @grails.war.resources@ property, e.g. +And in your @build.gradle@ you should exclude the compiled classes from the JAR file: {code} -grails.plugin.resources = { stagingDir -> - // update staging directory contents here +jar { + exclude "com/demo/**/**" } {code} -h4. Specifying Plugin Locations -An application can load plugins from anywhere on the file system, even if they have not been installed. Specify the location of the (unpacked) plugin in the application's @grails-app/conf/BuildConfig.groovy@ file: +h4. Inline Plugins in Grails 3.0 -{code:java} -// Useful to test plugins you are developing. -grails.plugin.location.shiro = - "/home/dilbert/dev/plugins/grails-shiro" +In Grails 2.x it was possible to specify inline plugins in @BuildConfig@, in Grails 3.x this functionality has been replaced by Gradle's multi-project build feature. -// Useful for modular applications where all plugins and -// applications are in the same directory. -grails.plugin.location.'grails-ui' = "../grails-grails-ui" +To set up a multi project build create an appliation and a plugin in a parent directory: + +{code} +$ grails create-app myapp +$ grails create-plugin myplugin {code} -This is particularly useful in two cases: +Then create a @settings.gradle@ file in the parent directory specifying the location of your application and plugin: + +{code} +include 'myapp', 'myplugin' +{code} -* You are developing a plugin and want to test it in a real application without packaging and installing it first. -* You have split an application into a set of plugins and an application, all in the same "super-project" directory. +Finally add a dependency in your application's @build.gradle@ on the plugin: -{note} -The Artifactory repository for Grails now includes all the dependencies for published plugins. So, if you are using inline plugins that have dependencies, it is necessary to do a secondary resolve because these dependencies might not be in the repository. Therefore, you should set @legacyResolve@ to @true@ in your @BuildConfig.groovy@ if you are using inline plugins with dependencies. -{note} +{code} +compile project(':myplugin') +{code} +Using this technique you have achieved the equivalent of inline plugins from Grails 2.x. From 996854198a6ca5d8797383774935a860e9a19413 Mon Sep 17 00:00:00 2001 From: Graeme Rocher Date: Tue, 24 Feb 2015 12:29:09 +0100 Subject: [PATCH 078/230] updated plugin docs on providing basic artefacts --- .../guide/plugins/providingBasicArtefacts.gdoc | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/en/guide/plugins/providingBasicArtefacts.gdoc b/src/en/guide/plugins/providingBasicArtefacts.gdoc index 16343923864..125964a1596 100644 --- a/src/en/guide/plugins/providingBasicArtefacts.gdoc +++ b/src/en/guide/plugins/providingBasicArtefacts.gdoc @@ -1,15 +1,13 @@ -h4. Adding a new Script +h4. Add Command Line Commands -A plugin can add a new script simply by providing the relevant Gant script in its scripts directory: +A plugin can add new commands to the Grails 3.0 interactive shell in one of two ways. First, using the [create-script|commandLine] you can create a code generation script which will become available to the application. The @create-script@ command will create the script in the @src/main/scripts@ directory: {code:java} -+ MyPlugin.groovy - + scripts <-- additional scripts here - + grails-app - + controllers - + services - + etc. - + lib + + src/main/scripts <-- additional scripts here + + grails-app + + controllers + + services + + etc. {code} h4. Adding a new grails-app artifact (Controller, Tag Library, Service, etc.) From 68be83002fdc06c4ed05b2811219cf0a03dc039a Mon Sep 17 00:00:00 2001 From: graemerocher Date: Tue, 24 Feb 2015 14:55:57 +0100 Subject: [PATCH 079/230] updated documentation on plugins for Grails 3.0 --- resources/doc.properties | 1 + .../addingDynamicMethodsAtRuntime.gdoc | 27 ++-- .../plugins/addingMethodsAtCompileTime.gdoc | 0 .../guide/plugins/evaluatingConventions.gdoc | 6 +- .../hookingIntoRuntimeConfiguration.gdoc | 104 ++++++-------- .../participatingInAutoReloadEvents.gdoc | 13 +- .../plugins/providingBasicArtefacts.gdoc | 68 ++++++--- .../plugins/understandingPluginStructure.gdoc | 31 ---- src/en/guide/theWebLayer/ajax.gdoc | 5 - .../theWebLayer/ajax/ajaxOnTheServer.gdoc | 126 ---------------- .../guide/theWebLayer/ajax/ajaxSupport.gdoc | 15 -- .../ajax/ajaxSupport/ajaxEvents.gdoc | 33 ----- .../ajaxSupport/remoteFormSubmission.gdoc | 20 --- .../ajax/ajaxSupport/remotingLinking.gdoc | 7 - .../ajax/ajaxSupport/updatingContent.gdoc | 31 ---- .../guide/theWebLayer/ajax/ajaxWithDojo.gdoc | 13 -- .../guide/theWebLayer/ajax/ajaxWithGWT.gdoc | 1 - .../theWebLayer/ajax/ajaxWithPrototype.gdoc | 19 --- .../theWebLayer/gsp/resources/debugging.gdoc | 23 --- .../gsp/resources/declaringResources.gdoc | 48 ------- ...ncludingResourcesUsingTheResourceTags.gdoc | 134 ------------------ .../resources/optimizingYourResources.gdoc | 63 -------- .../gsp/resources/otherResourceTags.gdoc | 13 -- .../gsp/resources/otherResourcesPlugins.gdoc | 8 -- .../resources/overridingPluginResources.gdoc | 47 ------ .../preventingProcessingOfResources.gdoc | 45 ------ src/en/guide/toc.yml | 25 +--- 27 files changed, 118 insertions(+), 808 deletions(-) create mode 100644 src/en/guide/plugins/addingMethodsAtCompileTime.gdoc delete mode 100644 src/en/guide/plugins/understandingPluginStructure.gdoc delete mode 100644 src/en/guide/theWebLayer/ajax.gdoc delete mode 100644 src/en/guide/theWebLayer/ajax/ajaxOnTheServer.gdoc delete mode 100644 src/en/guide/theWebLayer/ajax/ajaxSupport.gdoc delete mode 100644 src/en/guide/theWebLayer/ajax/ajaxSupport/ajaxEvents.gdoc delete mode 100644 src/en/guide/theWebLayer/ajax/ajaxSupport/remoteFormSubmission.gdoc delete mode 100644 src/en/guide/theWebLayer/ajax/ajaxSupport/remotingLinking.gdoc delete mode 100644 src/en/guide/theWebLayer/ajax/ajaxSupport/updatingContent.gdoc delete mode 100644 src/en/guide/theWebLayer/ajax/ajaxWithDojo.gdoc delete mode 100644 src/en/guide/theWebLayer/ajax/ajaxWithGWT.gdoc delete mode 100644 src/en/guide/theWebLayer/ajax/ajaxWithPrototype.gdoc delete mode 100644 src/en/guide/theWebLayer/gsp/resources/debugging.gdoc delete mode 100644 src/en/guide/theWebLayer/gsp/resources/declaringResources.gdoc delete mode 100644 src/en/guide/theWebLayer/gsp/resources/includingResourcesUsingTheResourceTags.gdoc delete mode 100644 src/en/guide/theWebLayer/gsp/resources/optimizingYourResources.gdoc delete mode 100644 src/en/guide/theWebLayer/gsp/resources/otherResourceTags.gdoc delete mode 100644 src/en/guide/theWebLayer/gsp/resources/otherResourcesPlugins.gdoc delete mode 100644 src/en/guide/theWebLayer/gsp/resources/overridingPluginResources.gdoc delete mode 100644 src/en/guide/theWebLayer/gsp/resources/preventingProcessingOfResources.gdoc diff --git a/resources/doc.properties b/resources/doc.properties index 35b250cdb6e..9d87a5b0399 100644 --- a/resources/doc.properties +++ b/resources/doc.properties @@ -84,6 +84,7 @@ alias.XML=6.1.7 XML and JSON Responses # javadoc alias used to link to external javadocs in the form [HttpServletRequest|api:javax.servlet.http.HttpServletRequest] api.org.hibernate=http://docs.jboss.org/hibernate/core/3.6/javadocs +api.org.springframework.boot=http://docs.spring.io/spring-boot/docs/current/api api.org.springframework=http://docs.spring.io/spring/docs/4.0.x/javadoc-api api.javax.servlet=http://download.oracle.com/javaee/1.4/api api.java.=http://docs.oracle.com/javase/6/docs/api diff --git a/src/en/guide/plugins/addingDynamicMethodsAtRuntime.gdoc b/src/en/guide/plugins/addingDynamicMethodsAtRuntime.gdoc index 2689d46c600..8616f7330d0 100644 --- a/src/en/guide/plugins/addingDynamicMethodsAtRuntime.gdoc +++ b/src/en/guide/plugins/addingDynamicMethodsAtRuntime.gdoc @@ -1,13 +1,15 @@ h4. The Basics -Grails plugins let you register dynamic methods with any Grails-managed or other class at runtime. This work is done in a @doWithDynamicMethods@ closure. +Grails plugins let you register dynamic methods with any Grails-managed or other class at runtime. This work is done in a @doWithDynamicMethods@ method. -For Grails-managed classes like controllers, tag libraries and so forth you can add methods, constructors etc. using the "ExpandoMetaClass":http://groovy.codehaus.org/ExpandoMetaClass mechanism by accessing each controller's [MetaClass|api:groovy.lang.MetaClass]: +{note} +Note that Grails 3.x features newer features such as traits that are usable from code compiled with @CompileStatic@. It is recommended that dynamic behavior is only added for cases that are not possible with traits. +{note} {code:java} -class ExamplePlugin { - def doWithDynamicMethods = { applicationContext -> - for (controllerClass in application.controllerClasses) { +class ExamplePlugin extends Plugin { + void doWithDynamicMethods() { + for (controllerClass in grailsApplication.controllerClasses) { controllerClass.metaClass.myNewMethod = {-> println "hello world" } } } @@ -19,9 +21,10 @@ In this case we use the implicit application object to get a reference to all of For example we can add a new method @swapCase@ to @java.lang.String@: {code:java} -class ExamplePlugin { +class ExamplePlugin extends Plugin { - def doWithDynamicMethods = { applicationContext -> + @Override + void doWithDynamicMethods() { String.metaClass.swapCase = {-> def sb = new StringBuilder() delegate.each { @@ -44,11 +47,11 @@ The @doWithDynamicMethods@ closure gets passed the Spring @ApplicationContext@ i {code:java} import org.springframework.orm.hibernate3.HibernateTemplate -class ExampleHibernatePlugin { +class ExampleHibernatePlugin extends Plugin{ - def doWithDynamicMethods = { applicationContext -> + void doWithDynamicMethods() { - for (domainClass in application.domainClasses) { + for (domainClass in grailsApplication.domainClasses) { domainClass.metaClass.static.load = { Long id-> def sf = applicationContext.sessionFactory @@ -65,8 +68,8 @@ Also because of the autowiring and dependency injection capability of the Spring {code:java} class MyConstructorPlugin { - def doWithDynamicMethods = { applicationContext -> - for (domainClass in application.domainClasses) { + void doWithDynamicMethods() + for (domainClass in grailsApplication.domainClasses) { domainClass.metaClass.constructor = {-> return applicationContext.getBean(domainClass.name) } diff --git a/src/en/guide/plugins/addingMethodsAtCompileTime.gdoc b/src/en/guide/plugins/addingMethodsAtCompileTime.gdoc new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/en/guide/plugins/evaluatingConventions.gdoc b/src/en/guide/plugins/evaluatingConventions.gdoc index 6677f5b66c3..c02765aff8a 100644 --- a/src/en/guide/plugins/evaluatingConventions.gdoc +++ b/src/en/guide/plugins/evaluatingConventions.gdoc @@ -1,8 +1,8 @@ -Before looking at providing runtime configuration based on conventions you first need to understand how to evaluate those conventions from a plugin. Every plugin has an implicit @application@ variable which is an instance of the [GrailsApplication|api:org.codehaus.groovy.grails.commons.GrailsApplication] interface. +Before looking at providing runtime configuration based on conventions you first need to understand how to evaluate those conventions from a plugin. Every plugin has an implicit @application@ variable which is an instance of the [GrailsApplication|api:grails.core.GrailsApplication] interface. The @GrailsApplication@ interface provides methods to evaluate the conventions within the project and internally stores references to all artifact classes within your application. -Artifacts implement the [GrailsClass|api:org.codehaus.groovy.grails.commons.GrailsClass] interface, which represents a Grails resource such as a controller or a tag library. For example to get all @GrailsClass@ instances you can do: +Artifacts implement the [GrailsClass|api:grails.core.GrailsClass] interface, which represents a Grails resource such as a controller or a tag library. For example to get all @GrailsClass@ instances you can do: {code:java} for (grailsClass in application.allClasses) { @@ -37,4 +37,4 @@ The @GrailsClass@ interface has a number of useful methods that let you further * @getNaturalName@ - Returns the name of the property in natural terms (e.g. 'lastName' becomes 'Last Name') * @getPackageName@ - Returns the package name -For a full reference refer to the [javadoc API|api:org.codehaus.groovy.grails.commons.GrailsClass]. +For a full reference refer to the [javadoc API|api:grails.core.GrailsClass]. diff --git a/src/en/guide/plugins/hookingIntoRuntimeConfiguration.gdoc b/src/en/guide/plugins/hookingIntoRuntimeConfiguration.gdoc index ca1cddefe46..7849f3ea592 100644 --- a/src/en/guide/plugins/hookingIntoRuntimeConfiguration.gdoc +++ b/src/en/guide/plugins/hookingIntoRuntimeConfiguration.gdoc @@ -2,18 +2,19 @@ Grails provides a number of hooks to leverage the different parts of the system h4. Hooking into the Grails Spring configuration -First, you can hook in Grails runtime configuration by providing a property called @doWithSpring@ which is assigned a block of code. For example the following snippet is from one of the core Grails plugins that provides [i18n|guide:i18n] support: +First, you can hook in Grails runtime configuration overriding the @doWithSpring@ method from the [Plugin|api:grails.plugins.Plugin] class and returning a closure that defines additional beans. For example the following snippet is from one of the core Grails plugins that provides [i18n|guide:i18n] support: {code:java} import org.springframework.web.servlet.i18n.CookieLocaleResolver import org.springframework.web.servlet.i18n.LocaleChangeInterceptor import org.springframework.context.support.ReloadableResourceBundleMessageSource +import grails.plugins.* -class I18nGrailsPlugin { +class I18nGrailsPlugin extends Plugin { def version = "0.1" - def doWithSpring = { + Closure doWithSpring() {{-> messageSource(ReloadableResourceBundleMessageSource) { basename = "WEB-INF/grails-app/i18n/messages" } @@ -21,96 +22,75 @@ class I18nGrailsPlugin { paramName = "lang" } localeResolver(CookieLocaleResolver) - } + }} } {code} This plugin configures the Grails @messageSource@ bean and a couple of other beans to manage Locale resolution and switching. It using the [Spring Bean Builder|guide:spring] syntax to do so. -h4. Participating in web.xml Generation - -Grails generates the @WEB-INF/web.xml@ file at load time, and although plugins cannot change this file directly, they can participate in the generation of the file. A plugin can provide a @doWithWebDescriptor@ property that is assigned a block of code that gets passed the @web.xml@ as an @XmlSlurper@ @GPathResult@. +h4. Customizing the Servlet Environment -h5. Add @servlet@ and @servlet-mapping@ +In previous versions of Grails it was possible to dynamically modify the generated @web.xml@. In Grails 3.x there is no @web.xml@ file and it is not possible to programmatically modify the @web.xml@ file anymore. -Consider this example from the @ControllersPlugin@: +However, it is possible to perform the most commons tasks of modifying the Servlet environment in Grails 3.x. -{code:java} -def doWithWebDescriptor = { webXml -> +h4. Adding New Servlets - def mappingElement = webXml.'servlet-mapping' +If you want to add a new Servlet instance the simplest way is simply to define a new Spring bean in the @doWithSpring@ method: - def lastMapping = mappingElement[mappingElement.size() - 1] - lastMapping + { - 'servlet-mapping' { - 'servlet-name'("grails") - 'url-pattern'("*.dispatch") - } - } -} +{code} +Closure doWithSpring() {{-> + myServlet(MyServlet) +}} {code} -Here the plugin gets a reference to the last @@ element and appends Grails' servlet after it using XmlSlurper's ability to programmatically modify XML using closures and blocks. - -h5. Add @filter@ and @filter-mapping@ - -Adding a filter with its mapping works a little differently. The location of the @@ element doesn't matter since order is not important, so it's simplest to insert your custom filter definition immediately after the last @@ element. Order _is_ important for mappings, but the usual approach is to add it immediately after the last @@ element like so: +If you need to customize the servlet you can use Spring Boot's [ServletRegistrationBean|api:org.springframework.boot.context.embedded.ServletRegistrationBean]: -{code:java} -def doWithWebDescriptor = { webXml -> +{code} +Closure doWithSpring() {{-> + myServlet(ServletRegistrationBean, new MyServlet(), "/myServlet/*") { + loadOnStartup = 2 + } +}} +{code} - def contextParam = webXml.'context-param' +h4. Adding New Servlet Filters - contextParam[contextParam.size() - 1] + { - 'filter' { - 'filter-name'('springSecurityFilterChain') - 'filter-class'(DelegatingFilterProxy.name) - } - } +Just like Servlets, the simplest way to configure a new filter is to simply define a Spring bean: - def filter = webXml.'filter' - filter[filter.size() - 1] + { - 'filter-mapping'{ - 'filter-name'('springSecurityFilterChain') - 'url-pattern'('/*') - } - } -} +{code} +Closure doWithSpring() {{-> + myFilter(MyFilter) +}} {code} -In some cases you need to ensure that your filter comes after one of the standard Grails filters, such as the Spring character encoding filter or the SiteMesh filter. Fortunately you can insert filter mappings immediately after the standard ones (more accurately, any that are in the template web.xml file) like so: - -{code:java} -def doWithWebDescriptor = { webXml -> - ... - - // Insert the Spring Security filter after the Spring - // character encoding filter. - def filter = webXml.'filter-mapping'.find { - it.'filter-name'.text() == "charEncodingFilter" - } +However, if you want to control the order of filter registrations you will need to use Spring Boot's [FilterRegistrationBean|api:org.springframework.boot.context.embedded.FilterRegistrationBean]: - filter + { - 'filter-mapping'{ - 'filter-name'('springSecurityFilterChain') - 'url-pattern'('/*') - } - } +{code} +myFilter(FilterRegistrationBean) { + filter = bean(MyFilter) + urlPatterns = ['/*'] + order = Ordered.HIGHEST_PRECEDENCE } {code} +{note} +Grails' internal registered filters (@GrailsWebRequestFilter@, @HiddenHttpMethodFilter@ etc.) are defined by incrementing @HIGHEST_PRECEDENCE@ by 10 thus allowing several filters to be inserted before or between Grails' filters. +{note} + h4. Doing Post Initialisation Configuration Sometimes it is useful to be able do some runtime configuration after the Spring [ApplicationContext|api:org.springframework.context.ApplicationContext] has been built. In this case you can define a @doWithApplicationContext@ closure property. {code:java} -class SimplePlugin { +class SimplePlugin extends Plugin{ def name = "simple" def version = "1.1" - def doWithApplicationContext = { appCtx -> - def sessionFactory = appCtx.sessionFactory + @Override + void doWithApplicationContext() { + def sessionFactory = applicationContext.sessionFactory // do something here with session factory } } diff --git a/src/en/guide/plugins/participatingInAutoReloadEvents.gdoc b/src/en/guide/plugins/participatingInAutoReloadEvents.gdoc index 8760d5b6f09..36015ba00d3 100644 --- a/src/en/guide/plugins/participatingInAutoReloadEvents.gdoc +++ b/src/en/guide/plugins/participatingInAutoReloadEvents.gdoc @@ -3,25 +3,20 @@ h4. Monitoring Resources for Changes Often it is valuable to monitor resources for changes and perform some action when they occur. This is how Grails implements advanced reloading of application state at runtime. For example, consider this simplified snippet from the Grails @ServicesPlugin@: {code:java} -class ServicesGrailsPlugin { +class ServicesGrailsPlugin extends Plugin { ... def watchedResources = "file:./grails-app/services/*Service.groovy" ... - def onChange = { event -> + void onChange( Map event) { if (event.source) { - def serviceClass = application.addServiceClass(event.source) + def serviceClass = grailsApplication.addServiceClass(event.source) def serviceName = "\${serviceClass.propertyName}" - def beans = beans { + beans { "$serviceName"(serviceClass.getClazz()) { bean -> bean.autowire = true } } - if (event.ctx) { - event.ctx.registerBeanDefinition( - serviceName, - beans.getBeanDefinition(serviceName)) - } } } } diff --git a/src/en/guide/plugins/providingBasicArtefacts.gdoc b/src/en/guide/plugins/providingBasicArtefacts.gdoc index 125964a1596..f7d18760084 100644 --- a/src/en/guide/plugins/providingBasicArtefacts.gdoc +++ b/src/en/guide/plugins/providingBasicArtefacts.gdoc @@ -10,18 +10,58 @@ A plugin can add new commands to the Grails 3.0 interactive shell in one of two + etc. {code} +Code generation scripts can be used to create artefacts within the project tree and automate interactions with Gradle. + +If you want to create a new shell command that interacts with a loaded Grails application instance then you should use the @create-command@ command: + +{code} +$ grails create-command MyExampleCommand +{code} + +This will create a file called @grails-app/commands/PACKAGE_PATH/MyExampleCommand.groovy@ that extends [ApplicationCommand|api:grails.dev.commands.ApplicationCommand]: + +{code} +import grails.dev.commands.* + +class MyExampleCommand implements ApplicationCommand { + + boolean handle(ExecutionContext ctx) { + println "Hello World" + return true + } +} +{code} + +An @ApplicationCommand@ has access to the @GrailsApplication@ instance and is subject to autowiring like any other Spring bean. + +For each @ApplicationCommand@ present Grails will create a shell command and a Gradle task to invoke the @ApplicationCommand@. In the above example you can invoke the @MyExampleCommand@ class using either: + +{code} +$ grails my-example +{code} + +Or + +{code} +$ gradle myExample +{code} + +The Grails version is all lower case hyphen separated and excludes the "Command" suffix. + +The main difference between code generation scripts and @ApplicationCommand@ instances is that the latter has full access to the Grails application state and hence can be used to perform tasks that interactive with the database, call into GORM etc. + +In Grails 2.x Gant scripts could be used to perform both these tasks, in Grails 3.x code generation and interacting with runtime application state has been cleanly separated. + h4. Adding a new grails-app artifact (Controller, Tag Library, Service, etc.) -A plugin can add new artifacts by creating the relevant file within the @grails-app@ tree. Note that the plugin is loaded from where it is installed and not copied into the main application tree. +A plugin can add new artifacts by creating the relevant file within the @grails-app@ tree. {code:java} -+ ExamplePlugin.groovy - + scripts - + grails-app - + controllers <-- additional controllers here - + services <-- additional services here - + etc. <-- additional XXX here - + lib + + grails-app + + controllers <-- additional controllers here + + services <-- additional services here + + etc. <-- additional XXX here + {code} h4. Providing Views, Templates and View resolution @@ -42,18 +82,12 @@ h4. Excluded Artefacts By default Grails excludes the following files during the packaging process: -* @grails-app/conf/BootStrap.groovy@ -* @grails-app/conf/BuildConfig.groovy@ (although it is used to generate @dependencies.groovy@) -* @grails-app/conf/Config.groovy@ -* @grails-app/conf/DataSource.groovy@ (and any other @*DataSource.groovy@) -* @grails-app/conf/UrlMappings.groovy@ +* @grails-app/conf/logback.groovy@ +* @grails-app/conf/application.yml@ (renamed to @plugin.yml@) * @grails-app/conf/spring/resources.groovy@ -* Everything within @/web-app/WEB-INF@ -* Everything within @/web-app/plugins/\*\*@ -* Everything within @/test/\*\*@ +* Everything within @/src/test/\*\*@ * SCM management files within @\*\*/.svn/\*\*@ and @\*\*/CVS/\*\*@ -If your plugin requires files under the @web-app/WEB-INF@ directory it is recommended that you modify the plugin's @scripts/_Install.groovy@ Gant script to install these artefacts into the target project's directory tree. In addition, the default @UrlMappings.groovy@ file is excluded to avoid naming conflicts, however you are free to add a UrlMappings definition under a different name which *will* be included. For example a file called @grails-app/conf/BlogUrlMappings.groovy@ is fine. diff --git a/src/en/guide/plugins/understandingPluginStructure.gdoc b/src/en/guide/plugins/understandingPluginStructure.gdoc deleted file mode 100644 index 3ba5a2600c3..00000000000 --- a/src/en/guide/plugins/understandingPluginStructure.gdoc +++ /dev/null @@ -1,31 +0,0 @@ -As as mentioned previously, a plugin is basically a regular Grails application with a plugin descriptor. However when installed, the structure of a plugin differs slightly. For example, take a look at this plugin directory structure: - -{code:java} -+ grails-app - + controllers - + domain - + taglib - etc. - + lib - + src - + java - + groovy - + web-app - + js - + css{code} - -When a plugin is installed the contents of the @grails-app@ directory will go into a directory such as @plugins/example-1.0/grails-app@. They *will not* be copied into the main source tree. A plugin never interferes with a project's primary source tree. - -Dealing with static resources is slightly different. When developing a plugin, just like an application, all static resources go in the @web-app@ directory. You can then link to static resources just like in an application. This example links to a JavaScript source: - -{code:xml} - -{code} - -When you run the plugin in development mode the link to the resource will resolve to something like @/js/mycode.js@. However, when the plugin is installed into an application the path will automatically change to something like @/plugin/example-0.1/js/mycode.js@ and Grails will deal with making sure the resources are in the right place. - -There is a special @pluginContextPath@ variable that can be used whilst both developing the plugin and when in the plugin is installed into the application to find out what the correct path to the plugin is. - -At runtime the @pluginContextPath@ variable will either evaluate to an empty string or @/plugins/example@ depending on whether the plugin is running standalone or has been installed in an application - -Java and Groovy code that the plugin provides within the lib and @src/java@ and @src/groovy@ directories will be compiled into the main project's @web-app/WEB-INF/classes@ directory so that they are made available at runtime. diff --git a/src/en/guide/theWebLayer/ajax.gdoc b/src/en/guide/theWebLayer/ajax.gdoc deleted file mode 100644 index aaa1139c0e9..00000000000 --- a/src/en/guide/theWebLayer/ajax.gdoc +++ /dev/null @@ -1,5 +0,0 @@ -Ajax is the driving force behind the shift to richer web applications. These types of applications in general are better suited to agile, dynamic frameworks written in languages like "Groovy":http://groovy.codehaus.org and "Ruby":http://www.ruby-lang.org/. Grails provides support for building Ajax applications through its Ajax tag library. For a full list of these see the Tag Library Reference. - -{note} -Note: JavaScript examples use the jQuery library. -{note} diff --git a/src/en/guide/theWebLayer/ajax/ajaxOnTheServer.gdoc b/src/en/guide/theWebLayer/ajax/ajaxOnTheServer.gdoc deleted file mode 100644 index 1d75a48156c..00000000000 --- a/src/en/guide/theWebLayer/ajax/ajaxOnTheServer.gdoc +++ /dev/null @@ -1,126 +0,0 @@ -There are a number of different ways to implement Ajax which are typically broken down into: - -* Content Centric Ajax - Where you just use the HTML result of a remote call to update the page -* Data Centric Ajax - Where you actually send an XML or JSON response from the server and programmatically update the page -* Script Centric Ajax - Where the server sends down a stream of JavaScript to be evaluated on the fly - -Most of the examples in the [Ajax|guide:ajax] section cover Content Centric Ajax where you are updating the page, but you may also want to use Data Centric or Script Centric. This guide covers the different styles of Ajax. - -h4. Content Centric Ajax - -Just to re-cap, content centric Ajax involves sending some HTML back from the server and is typically done by rendering a template with the [render|controllers] method: - -{code:java} -def showBook() { - def b = Book.get(params.id) - - render(template: "bookTemplate", model: [book: b]) -} -{code} - -Calling this on the client involves using the [remoteLink|tags] tag: - -{code:xml} -Update Book - -
- -
-{code} - -h4. Data Centric Ajax with JSON - -Data Centric Ajax typically involves evaluating the response on the client and updating programmatically. For a JSON response with Grails you would typically use Grails' [JSON marshalling|guide:xmlAndJSON] capability: - -{code:java} -import grails.converters.JSON - -def showBook() { - def b = Book.get(params.id) - - render b as JSON -} -{code} - -And then on the client parse the incoming JSON request using an Ajax event handler: - -{code:xml} - -function updateBook(data) { - $("#book" + data.id + "_title").html( data.title ); -} - - - Update Book - -book${book.id} -
-
The Stand
-
-{code} - -h4. Data Centric Ajax with XML - -On the server side using XML is equally simple: - -{code:java} -import grails.converters.XML - -def showBook() { - def b = Book.get(params.id) - - render b as XML -} -{code} - -However, since DOM is involved the client gets more complicated: - -{code:xml} - -function updateBook(data) { - var id = $(data).find("book").attr("id"); - $("#book" + id + "_title").html( $(data).find("title").text() ); -} - - - Update Book - -book${book.id} -
-
The Stand
-
-{code} - -h4. Script Centric Ajax with JavaScript - -Script centric Ajax involves actually sending JavaScript back that gets evaluated on the client. An example of this can be seen below: - -{code:java} -def showBook() { - def b = Book.get(params.id) - - response.contentType = "text/javascript" - String title = b.title.encodeAsJavaScript() - render "\$('#book${b.id}_title').html('${title}');" -} -{code} - -The important thing to remember is to set the @contentType@ to @text/javascript@. If you use Prototype on the client the returned JavaScript will automatically be evaluated due to this @contentType@ setting. - -Obviously in this case it is critical that you have an agreed client-side API as you don't want changes on the client breaking the server. This is one of the reasons Rails has something like RJS. Although Grails does not currently have a feature such as RJS there is a [Dynamic JavaScript Plugin|http://grails.org/plugin/dynamic-javascript] that offers similar capabilities. - -h4. Responding to both Ajax and non-Ajax requests - -It's straightforward to have the same Grails controller action handle both Ajax and non-Ajax requests. Grails adds the @isXhr()@ method to @HttpServletRequest@ which can be used to identify Ajax requests. For example you could render a page fragment using a template for Ajax requests or the full page for regular HTTP requests: - -{code:java} -def listBooks() { - def books = Book.list(params) - if (request.xhr) { - render template: "bookTable", model: [books: books] - } else { - render view: "list", model: [books: books] - } -} -{code} diff --git a/src/en/guide/theWebLayer/ajax/ajaxSupport.gdoc b/src/en/guide/theWebLayer/ajax/ajaxSupport.gdoc deleted file mode 100644 index 99da92fd8d5..00000000000 --- a/src/en/guide/theWebLayer/ajax/ajaxSupport.gdoc +++ /dev/null @@ -1,15 +0,0 @@ -By default Grails ships with the "jQuery":http://jquery.com/ library, but through the [Plugin system|guide:plugins] provides support for other frameworks such as [Prototype|http://www.prototypejs.org/], [Dojo:http://dojotoolkit.org/], [Yahoo UI:http://developer.yahoo.com/yui/] and the [Google Web Toolkit|http://code.google.com/webtoolkit/]. - -This section covers Grails' support for Ajax in general. To get started, add this line to the @@ tag of your page: - -{code:xml} - -{code} - -You can replace @jQuery@ with any other library supplied by a plugin you have installed. This works because of Grails' support for adaptive tag libraries. Thanks to Grails' plugin system there is support for a number of different Ajax libraries including (but not limited to): - -* jQuery -* Prototype -* Dojo -* YUI -* MooTools diff --git a/src/en/guide/theWebLayer/ajax/ajaxSupport/ajaxEvents.gdoc b/src/en/guide/theWebLayer/ajax/ajaxSupport/ajaxEvents.gdoc deleted file mode 100644 index 617f7c55454..00000000000 --- a/src/en/guide/theWebLayer/ajax/ajaxSupport/ajaxEvents.gdoc +++ /dev/null @@ -1,33 +0,0 @@ -Specific JavaScript can be called if certain events occur, all the events start with the "on" prefix and let you give feedback to the user where appropriate, or take other action: - -{code:xml} -Show Book 1 -{code} - -The above code will execute the "showProgress()" function which may show a progress bar or whatever is appropriate. Other events include: - -* @onSuccess@ - The JavaScript function to call if successful -* @onFailure@ - The JavaScript function to call if the call failed -* @onERROR_CODE@ - The JavaScript function to call to handle specified error codes (e.g. @on404="alert('not found!')"@) -* @onUninitialized@ - The JavaScript function to call the a Ajax engine failed to initialise -* @onLoading@ - The JavaScript function to call when the remote function is loading the response -* @onLoaded@ - The JavaScript function to call when the remote function is completed loading the response -* @onComplete@ - The JavaScript function to call when the remote function is complete, including any updates - -You can simply refer to the @XMLHttpRequest@ variable to obtain the request: - -{code:xml} - - function fireMe(event) { - alert("XmlHttpRequest = " + event) - } -} - -Ajax Link -{code} diff --git a/src/en/guide/theWebLayer/ajax/ajaxSupport/remoteFormSubmission.gdoc b/src/en/guide/theWebLayer/ajax/ajaxSupport/remoteFormSubmission.gdoc deleted file mode 100644 index 4d64e89bf97..00000000000 --- a/src/en/guide/theWebLayer/ajax/ajaxSupport/remoteFormSubmission.gdoc +++ /dev/null @@ -1,20 +0,0 @@ -An HTML form can also be submitted asynchronously in one of two ways. Firstly using the [formRemote|tags] tag which expects similar attributes to those for the [remoteLink|tags] tag: - -{code:xml} - - - - -{code} - -Or alternatively you can use the [submitToRemote|tags] tag to create a submit button. This allows some buttons to submit remotely and some not depending on the action: - -{code:xml} -
- - - -{code} - diff --git a/src/en/guide/theWebLayer/ajax/ajaxSupport/remotingLinking.gdoc b/src/en/guide/theWebLayer/ajax/ajaxSupport/remotingLinking.gdoc deleted file mode 100644 index fa1fa0fc293..00000000000 --- a/src/en/guide/theWebLayer/ajax/ajaxSupport/remotingLinking.gdoc +++ /dev/null @@ -1,7 +0,0 @@ -Remote content can be loaded in a number of ways, the most commons way is through the [remoteLink|tags] tag. This tag allows the creation of HTML anchor tags that perform an asynchronous request and optionally set the response in an element. The simplest way to create a remote link is as follows: - -{code:xml} -Delete Book -{code} - -The above link sends an asynchronous request to the @delete@ action of the current controller with an id of @1@. diff --git a/src/en/guide/theWebLayer/ajax/ajaxSupport/updatingContent.gdoc b/src/en/guide/theWebLayer/ajax/ajaxSupport/updatingContent.gdoc deleted file mode 100644 index 559c93a22d3..00000000000 --- a/src/en/guide/theWebLayer/ajax/ajaxSupport/updatingContent.gdoc +++ /dev/null @@ -1,31 +0,0 @@ -This is great, but usually you provide feedback to the user about what happened: - -{code:java} -def delete() { - def b = Book.get(params.id) - b.delete() - render "Book ${b.id} was deleted" -} -{code} - -GSP code: - -{code:xml} -
- -Delete Book - -{code} - -The above example will call the action and set the contents of the @message@ @div@ to the response in this case @"Book 1 was deleted"@. This is done by the @update@ attribute on the tag, which can also take a Map to indicate what should be updated on failure: - -{code:xml} -
-
- -Delete Book - -{code} - -Here the @error@ div will be updated if the request failed. diff --git a/src/en/guide/theWebLayer/ajax/ajaxWithDojo.gdoc b/src/en/guide/theWebLayer/ajax/ajaxWithDojo.gdoc deleted file mode 100644 index 0008c23294f..00000000000 --- a/src/en/guide/theWebLayer/ajax/ajaxWithDojo.gdoc +++ /dev/null @@ -1,13 +0,0 @@ -Grails features an external plugin to add "Dojo":http://dojotoolkit.org/ support to Grails. To install the plugin, list it in BuildConfig.groovy: - -{code:java} -compile "\:dojo\:latest.release" -{code} - -This will download the current supported version of Dojo and install it into your Grails project. With that done you can add the following reference to the top of your page: - -{code:xml} - -{code} - -Now all of Grails tags such as [remoteLink|tags], [formRemote|tags] and [submitToRemote|tags] work with Dojo remoting. diff --git a/src/en/guide/theWebLayer/ajax/ajaxWithGWT.gdoc b/src/en/guide/theWebLayer/ajax/ajaxWithGWT.gdoc deleted file mode 100644 index 8a8ceb75ecb..00000000000 --- a/src/en/guide/theWebLayer/ajax/ajaxWithGWT.gdoc +++ /dev/null @@ -1 +0,0 @@ -Grails also features support for the "Google Web Toolkit":http://code.google.com/webtoolkit/ through a plugin. There is comprehensive [documentation|http://grails.org/plugin/gwt] available on the Grails wiki. diff --git a/src/en/guide/theWebLayer/ajax/ajaxWithPrototype.gdoc b/src/en/guide/theWebLayer/ajax/ajaxWithPrototype.gdoc deleted file mode 100644 index 9f329068bb8..00000000000 --- a/src/en/guide/theWebLayer/ajax/ajaxWithPrototype.gdoc +++ /dev/null @@ -1,19 +0,0 @@ -Grails features an external plugin to add "Prototype":http://www.prototypejs.org/ support to Grails. To install the plugin, list it in BuildConfig.groovy: - -{code:java} -runtime "\:prototype\:latest.release" -{code} - -This will download the current supported version of the Prototype plugin and install it into your Grails project. With that done you can add the following reference to the top of your page: - -{code:xml} - -{code} - -If you require "Scriptaculous":http://script.aculo.us/ too you can do the following instead: - -{code:xml} - -{code} - -Now all of Grails tags such as [remoteLink|tags], [formRemote|tags] and [submitToRemote|tags] work with Prototype remoting. diff --git a/src/en/guide/theWebLayer/gsp/resources/debugging.gdoc b/src/en/guide/theWebLayer/gsp/resources/debugging.gdoc deleted file mode 100644 index 25cfb26c44c..00000000000 --- a/src/en/guide/theWebLayer/gsp/resources/debugging.gdoc +++ /dev/null @@ -1,23 +0,0 @@ -When your resources are being moved around, renamed and otherwise mutated, it can be hard to debug client-side issues. Modern browsers, especially Safari, Chrome and Firefox have excellent tools that let you view all the resources requested by a page, including the headers and other information about them. - -There are several debugging features built in to the Resources framework. - -h4. X-Grails-Resources-Original-Src Header - -Every resource served in development mode will have the X-Grails-Resources-Original-Src: header added, indicating the original source file(s) that make up the response. - -h4. Adding the debug flag - -If you add a query parameter *_debugResources=y* to your URL and request the page, Resources will bypass any processing so that you can see your original source files. - -This also adds a unique timestamp to all your resource URLs, to defeat any caching that browsers may use. This means that you should always see your very latest code when you reload the page. - -h4. Turning on debug all the time - -You can turn on the aforementioned debug mechanism without requiring a query parameter, but turning it on in Config.groovy: - -{code} -grails.resources.debug = true -{code} - -You can of course set this per-environment. diff --git a/src/en/guide/theWebLayer/gsp/resources/declaringResources.gdoc b/src/en/guide/theWebLayer/gsp/resources/declaringResources.gdoc deleted file mode 100644 index 454c3b41c78..00000000000 --- a/src/en/guide/theWebLayer/gsp/resources/declaringResources.gdoc +++ /dev/null @@ -1,48 +0,0 @@ -A DSL is provided for declaring resources and modules. This can go either in your @Config.groovy@ in the case of application-specific resources, or more commonly in a resources artefact in @grails-app/conf@. - -Note that you do not need to declare all your static resources, especially images. However you must to establish dependencies or other resources-specific attributes. Any resource that is not declared is called "ad-hoc" and will still be processed using defaults for that resource type. - -Consider this example resource configuration file, @grails-app/conf/MyAppResources.groovy@: - -{code:java} -modules = { - core { - dependsOn 'jquery, utils' - - resource url: '/js/core.js', disposition: 'head' - resource url: '/js/ui.js' - resource url: '/css/main.css', - resource url: '/css/branding.css' - resource url: '/css/print.css', attrs: [media: 'print'] - } - - utils { - dependsOn 'jquery' - - resource url: '/js/utils.js' - } - - forms { - dependsOn 'core,utils' - - resource url: '/css/forms.css' - resource url: '/js/forms.js' - } -} -{code} - -This defines three resource modules; 'core', 'utils' and 'forms'. The resources in these modules will be automatically bundled out of the box according to the module name, resulting in fewer files. You can override this with @bundle:'someOtherName'@ on each resource, or call @defaultBundle@ on the module (see [resources plugin documentation|http://grails-plugins.github.com/grails-resources]). - -It declares dependencies between them using @dependsOn@, which controls the load order of the resources. - -When you include an @@ in your GSP, it will pull in all the resources from 'core' and 'utils' as well as 'jquery', all in the correct order. - -You'll also notice the @disposition:'head'@ on the @core.js@ file. This tells Resources that while it can defer all the other JS files to the end of the body, this one must go into the @@. - -The CSS file for print styling adds custom attributes using the @attrs@ map option, and these are passed through to the @r:external@ tag when the engine renders the link to the resource, so you can customize the HTML attributes of the generated link. - -There is no limit to the number of modules or xxxResources.groovy artefacts you can provide, and plugins can supply them to expose modules to applications, which is exactly how the jQuery plugin works. - -To define modules like this in your application's Config.groovy, you simply assign the DSL closure to the @grails.resources.modules@ Config variable. - -For full details of the resource DSL please see the [resources plugin documentation|http://grails-plugins.github.com/grails-resources]. diff --git a/src/en/guide/theWebLayer/gsp/resources/includingResourcesUsingTheResourceTags.gdoc b/src/en/guide/theWebLayer/gsp/resources/includingResourcesUsingTheResourceTags.gdoc deleted file mode 100644 index ab0eba494db..00000000000 --- a/src/en/guide/theWebLayer/gsp/resources/includingResourcesUsingTheResourceTags.gdoc +++ /dev/null @@ -1,134 +0,0 @@ -h4. Pulling in resources with r:require - -To use resources, your GSP page must indicate which resource modules it requires. For example with the [jQuery plugin|http://grails.org/plugin/jquery], which exposes a "jquery" resource module, to use jQuery in any page on your site you simply add: - -{code:xml} - - - - - - - ... - - - -{code} - -This will automatically include all resources needed for jQuery, including them at the correct locations in the page. By default the plugin sets the disposition to be "head", so they load early in the page. - -You can call @r:require@ multiple times in a GSP page, and you use the "modules" attribute to provide a list of modules: - -{code:xml} - - - - - - - ... - - - -{code} - -The above may result in many JavaScript and CSS files being included, in the correct order, with some JavaScript files loading at the end of the body to improve the apparent page load time. - -However you cannot use r:require in isolation - as per the examples you must have the tag to actually perform the render. - -h4. Rendering the links to resources with r:layoutResources - -When you have declared the resource modules that your GSP page requires, the framework needs to render the links to those resources at the correct time. - -To achieve this correctly, you must include the r:layoutResources tag twice in your page, or more commonly, in your GSP layout: - -{code:xml} - - - - - - - - - - -{code} - -This represents the simplest Sitemesh layout you can have that supports Resources. - -The Resources framework has the concept of a "disposition" for every resource. This is an indication of where in the page the resource should be included. - -The default disposition applied depends on the type of resource. All CSS must be rendered in in HTML, so "head" is the default for all CSS, and will be rendered by the first r:layoutResources. Page load times are improved when JavaScript is loaded after the page content, so the default for JavaScript files is "defer", which means it is rendered when the second r:layoutResources is invoked. - -Note that both your GSP page and your Sitemesh layout (as well as any GSP template fragments) can call r:require to depend on resources. The only limitation is that you must call r:require before the r:layoutResources that should render it. - -h4. Adding page-specific JavaScript code with r:script - -Grails has the [javascript|tags] tag which is adapted to defer to Resources plugin if installed, but it is recommended that you call @r:script@ directly when you need to include fragments of JavaScript code. - -This lets you write some "inline" JavaScript which is actually *not* rendered inline, but either in the or at the end of the body, based on the disposition. - -Given a Sitemesh layout like this: - -{code:xml} - - - - - - - - - - -{code} - -...in your GSP you can inject some JavaScript code into the head or deferred regions of the page like this: - -{code:xml} - - - Testing r:script magic! - - - - window.alert('This is at the end of '); - - - window.alert('This is at the end of the body, and the page has loaded.'); - - - -{code} - -The default disposition is "defer", so the disposition in the latter r:script is purely included for demonstration. - -Note that such r:script code fragments *always* load after any modules that you have used, to ensure that any required libraries have loaded. - -h4. Linking to images with r:img - -This tag is used to render @@ markup, using the Resources framework to process the resource on the fly (if configured to do so - e.g. make it eternally cacheable). - -This includes any extra attributes on the @@ tag if the resource has been previously declared in a module. - -With this mechanism you can specify the width, height and any other attributes in the resource declaration in the module, and they will be pulled in as necessary. - -Example: - -{code:xml} - - - Testing r:img - - - - - -{code} - -Note that Grails has a built-in @g:img@ tag as a shortcut for rendering @@ tags that refer to a static resource. The Grails [img|tags] tag is Resources-aware and will delegate to @r:img@ if found. However it is recommended that you use @r:img@ directly if using the Resources plugin. - -Alongside the regular Grails [resource|tags] tag attributes, this also supports the "uri" attribute for increased brevity. - -See [r:resource documentation|http://grails-plugins.github.com/grails-resources] for full details. diff --git a/src/en/guide/theWebLayer/gsp/resources/optimizingYourResources.gdoc b/src/en/guide/theWebLayer/gsp/resources/optimizingYourResources.gdoc deleted file mode 100644 index 6728d661d11..00000000000 --- a/src/en/guide/theWebLayer/gsp/resources/optimizingYourResources.gdoc +++ /dev/null @@ -1,63 +0,0 @@ -The Resources framework uses "mappers" to mutate the resources into the final format served to the user. - -The resource mappers are applied to each static resource once, in a specific order. You can create your own resource mappers, and several plugins provide some already for zipping, caching and minifying. - -Out of the box, the Resources plugin provides bundling of resources into fewer files, which is achieved with a few mappers that also perform CSS re-writing to handle when your CSS files are moved into a bundle. - -h4. Bundling multiple resources into fewer files - -The 'bundle' mapper operates by default on any resource with a "bundle" defined - or inherited from a @defaultBundle@ clause on the module. Modules have an implicit default bundle name the same as the name of the module. - -Files of the same kind will be aggregated into this bundle file. Bundles operate across module boundaries: - -{code:java} -modules = { - core { - dependsOn 'jquery, utils' - defaultBundle 'common' - - resource url: '/js/core.js', disposition: 'head' - resource url: '/js/ui.js', bundle: 'ui' - resource url: '/css/main.css', bundle: 'theme' - resource url: '/css/branding.css' - resource url: '/css/print.css', attrs: [media: 'print'] - } - - utils { - dependsOn 'jquery' - - resource url: '/js/utils.js', bundle: 'common' - } - - forms { - dependsOn 'core,utils' - - resource url: '/css/forms.css', bundle: 'ui' - resource url: '/js/forms.js', bundle: 'ui' - } -} -{code} - -Here you see that resources are grouped into bundles; 'common', 'ui' and 'theme' - across module boundaries. - -Note that auto-bundling by module does *not* occur if there is only one resource in the module. - -h4. Making resources cache "eternally" in the client browser - -Caching resources "eternally" in the client is only viable if the resource has a unique name that changes whenever the contents change, and requires caching headers to be set on the response. - -The [cached-resources|http://grails.org/plugin/cached-resources] plugin provides a mapper that achieves this by hashing your files and renaming them based on this hash. It also sets the caching headers on every response for those resources. To use, simply install the cached-resources plugin. - -Note that the caching headers can only be set if your resources are being served by your application. If you have another server serving the static content from your app (e.g. Apache HTTPD), configure it to send caching headers. Alternatively you can configure it to request and proxy the resources from your container. - -h4. Zipping resources - -Returning gzipped resources is another way to reduce page load times and reduce bandwidth. - -The [zipped-resources|http://grails.org/plugin/zipped-resources] plugin provides a mapper that automatically compresses your content, excluding by default already compressed formats such as gif, jpeg and png. - -Simply install the zipped-resources plugin and it works. - -h4. Minifying - -There are a number of CSS and JavaScript minifiers available to obfuscate and reduce the size of your code. At the time of writing none are publicly released but releases are imminent. diff --git a/src/en/guide/theWebLayer/gsp/resources/otherResourceTags.gdoc b/src/en/guide/theWebLayer/gsp/resources/otherResourceTags.gdoc deleted file mode 100644 index fbfc826a51e..00000000000 --- a/src/en/guide/theWebLayer/gsp/resources/otherResourceTags.gdoc +++ /dev/null @@ -1,13 +0,0 @@ -h4. r:resource - -This is equivalent to the Grails [resource|Tags] tag, returning a link to the processed static resource. Grails' own @g:resource@ tag delegates to this implementation if found, but if your code requires the Resources plugin, you should use @r:resource@ directly. - -Alongside the regular Grails [resource|Tags] tag attributes, this also supports the "uri" attribute for increased brevity. - -See [r:resource documentation|http://grails-plugins.github.com/grails-resources] for full details. - -h4. r:external - -This is a resource-aware version of Grails [external|Tags] tag which renders the HTML markup necessary to include an external file resource such as CSS, JS or a favicon. - -See [r:resource documentation|http://grails-plugins.github.com/grails-resources] for full details. diff --git a/src/en/guide/theWebLayer/gsp/resources/otherResourcesPlugins.gdoc b/src/en/guide/theWebLayer/gsp/resources/otherResourcesPlugins.gdoc deleted file mode 100644 index 6fd07129f90..00000000000 --- a/src/en/guide/theWebLayer/gsp/resources/otherResourcesPlugins.gdoc +++ /dev/null @@ -1,8 +0,0 @@ -At the time of writing, the following plugins include support for the Resources framework: - -* [jquery|http://grails.org/plugin/jquery] -* [jquery-ui|http://grails.org/plugin/jquery-ui] -* [blueprint|http://grails.org/plugin/blueprint] -* [lesscss-resources|http://grails.org/plugin/lesscss-resources] -* [zipped-resources|http://grails.org/plugin/zipped-resources] -* [cached-resources|http://grails.org/plugin/cached-resources] diff --git a/src/en/guide/theWebLayer/gsp/resources/overridingPluginResources.gdoc b/src/en/guide/theWebLayer/gsp/resources/overridingPluginResources.gdoc deleted file mode 100644 index f5ebe5e43d0..00000000000 --- a/src/en/guide/theWebLayer/gsp/resources/overridingPluginResources.gdoc +++ /dev/null @@ -1,47 +0,0 @@ -Because a resource module can define the bundle groupings and other attributes of resources, you may find that the settings provided are not correct for your application. - -For example, you may wish to bundle jQuery and some other libraries all together in one file. There is a load-time and caching trade-off here, but often it is the case that you'd like to override some of these settings. - -To do this, the DSL supports an "overrides" clause, within which you can change the @defaultBundle@ setting for a module, or attributes of individual resources that have been declared with a unique id: - -{code:java} -modules = { - core { - dependsOn 'jquery, utils' - defaultBundle 'monolith' - - resource url: '/js/core.js', disposition: 'head' - resource url: '/js/ui.js' - resource url: '/css/main.css', - resource url: '/css/branding.css' - resource url: '/css/print.css', attrs: [media: 'print'] - } - - utils { - dependsOn 'jquery' - defaultBundle 'monolith' - - resource url: '/js/utils.js' - } - - forms { - dependsOn 'core,utils' - defaultBundle 'monolith' - - resource url: '/css/forms.css' - resource url: '/js/forms.js' - } - - overrides { - jquery { - defaultBundle 'monolith' - } - } -} -{code} - -This will put all code into a single bundle named 'monolith'. Note that this can still result in multiple files, as separate bundles are required for head and defer dispositions, and JavaScript and CSS files are bundled separately. - -Note that overriding individual resources requires the original declaration to have included a unique id for the resource. - -For full details of the resource DSL please see the [resources plugin documentation|http://grails-plugins.github.com/grails-resources]. diff --git a/src/en/guide/theWebLayer/gsp/resources/preventingProcessingOfResources.gdoc b/src/en/guide/theWebLayer/gsp/resources/preventingProcessingOfResources.gdoc deleted file mode 100644 index 48510c2ab76..00000000000 --- a/src/en/guide/theWebLayer/gsp/resources/preventingProcessingOfResources.gdoc +++ /dev/null @@ -1,45 +0,0 @@ -Sometimes you do not want a resource to be processed in a particular way, or even at all. Occasionally you may also want to disable all resource mapping. - -h4. Preventing the application of a specific mapper to an individual resource - -All resource declarations support a convention of noXXXX:true where XXXX is a mapper name. - -So for example to prevent the "hashandcache" mapper from being applied to a resource (which renames and moves it, potentially breaking relative links written in JavaScript code), you would do this: - -{code:java} -modules = { - forms { - resource url: '/css/forms.css', nohashandcache: true - resource url: '/js/forms.js', nohashandcache: true - } -} -{code} - -h4. Excluding/including paths and file types from specific mappers - -Mappers have includes/excludes Ant patterns to control whether they apply to a given resource. Mappers set sensible defaults for these based on their activity, for example the zipped-resources plugin's "zip" mapper is set to exclude images by default. - -You can configure this in your @Config.groovy@ using the mapper name e.g: - -{code:java} -// We wouldn't link to .exe files using Resources but for the sake of example: -grails.resources.zip.excludes = ['**/*.zip', '**/*.exe'] - -// Perhaps for some reason we want to prevent bundling on "less" CSS files: -grails.resources.bundle.excludes = ['**/*.less'] -{code} - -There is also an "includes" inverse. Note that settings these replaces the default includes/excludes for that mapper - it is not additive. - -h4. Controlling what is treated as an "ad-hoc" (legacy) resource - -Ad-hoc resources are those undeclared, but linked to directly in your application *without* using the Grails or Resources linking tags (resource, img or external). - -These may occur with some legacy plugins or code with hardcoded paths in. - -There is a Config.groovy setting *grails.resources.adhoc.patterns* which defines a list of Servlet API compliant filter URI mappings, which the Resources filter will use to detect such "ad-hoc resource" requests. - -By default this is set to: -{code:java} -grails.resources.adhoc.patterns = ['images/*', '*.js', '*.css'] -{code} diff --git a/src/en/guide/toc.yml b/src/en/guide/toc.yml index d9b36c543cf..d8a30db7ebb 100644 --- a/src/en/guide/toc.yml +++ b/src/en/guide/toc.yml @@ -137,16 +137,7 @@ theWebLayer: tagsAsMethodCalls: Tags as Method Calls viewsAndTemplates: Views and Templates layouts: Layouts with Sitemesh - resources: - title: Static Resources - includingResourcesUsingTheResourceTags: Including resources using the resource tags - otherResourceTags: Other resource tags - declaringResources: Declaring resources - overridingPluginResources: Overriding plugin resources - optimizingYourResources: Optimizing your resources - debugging: Debugging - preventingProcessingOfResources: Preventing processing of resources - otherResourcesPlugins: Other Resources-aware plugins + resources: Static Resources sitemeshContentBlocks: Sitemesh Content Blocks makingChangesToADeployedApplication: Making Changes to a Deployed Application GSPDebugging: GSP Debugging @@ -179,18 +170,6 @@ theWebLayer: definingInterceptors: Defining Interceptors interceptorMatching: Matching Requests with Inteceptors interceptorOrdering: Ordering Interceptor Execution - ajax: - title: Ajax - ajaxSupport: - title: Ajax Support - remotingLinking: Remoting Linking - updatingContent: Updating Content - remoteFormSubmission: Remote Form Submission - ajaxEvents: Ajax Events - ajaxWithPrototype: Ajax with Prototype - ajaxWithDojo: Ajax with Dojo - ajaxWithGWT: Ajax with GWT - ajaxOnTheServer: Ajax on the Server contentNegotiation: Content Negotiation webServices: title: Web Services @@ -281,10 +260,10 @@ plugins: title: Plugins creatingAndInstallingPlugins: Creating and Installing Plugins repositories: Plugin Repositories - understandingPluginStructure: Understanding a Plugin's Structure providingBasicArtefacts: Providing Basic Artefacts evaluatingConventions: Evaluating Conventions hookingIntoRuntimeConfiguration: Hooking into Runtime Configuration + addingMethodsAtCompileTime: Adding Methods at Compile Time addingDynamicMethodsAtRuntime: Adding Dynamic Methods at Runtime participatingInAutoReloadEvents: Participating in Auto Reload Events understandingPluginLoadOrder: Understanding Plugin Load Order From c4816bc24e333150085dbcbbc738f2e5f583988d Mon Sep 17 00:00:00 2001 From: graemerocher Date: Tue, 24 Feb 2015 15:00:45 +0100 Subject: [PATCH 080/230] more docs on TraitInjector --- .../plugins/addingMethodsAtCompileTime.gdoc | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/en/guide/plugins/addingMethodsAtCompileTime.gdoc b/src/en/guide/plugins/addingMethodsAtCompileTime.gdoc index e69de29bb2d..03ebac316bb 100644 --- a/src/en/guide/plugins/addingMethodsAtCompileTime.gdoc +++ b/src/en/guide/plugins/addingMethodsAtCompileTime.gdoc @@ -0,0 +1,41 @@ +Grails 3.0 makes it easy to add new traits to existing artefact types from a plugin. For example say you wanted to add methods for manipulating dates to controllers. This can be done by first defining a trait in @src/main/groovy@: + +{code} +package myplugin + +trait DateTrait { + Date currentDate() { + return new Date() + } +} +{code} + +Once you have a trait you must tell Grails which artefacts you want to inject the trait into at compile time. To do this you implement a [TraitInjector|api:grails.compiler.traits.TraitInjector]: + +{code} +package myplugin + +@CompileStatic +class ControllerTraitInjector implements TraitInjector { + + static Pattern CONTROLLER_PATTERN = Pattern.compile(".+/" + + GrailsResourceUtils.GRAILS_APP_DIR + "/controllers/(.+)Controller\\.groovy"); + + @Override + Class getTrait() { + DateTrait + } + + @Override + boolean shouldInject(URL url) { + return url != null && CONTROLLER_PATTERN.matcher(url.getFile()).find(); + } + + @Override + String[] getArtefactTypes() { + ['Controller'] as String[] + } +} +{code} + +The above @TraitInjector@ will add the @DateTrait@ to all controllers. The @shouldInject@ method is used to restrict which source files will have the trait compiled into it. And the @getArtefactTypes@ method defines the supported artefact types. From a51c996880a5569b1c75ca301ea2bff38cb85f67 Mon Sep 17 00:00:00 2001 From: Jeff Scott Brown Date: Tue, 24 Feb 2015 11:49:09 -0600 Subject: [PATCH 081/230] Start filling in some trait docs --- src/en/guide/toc.yml | 8 +++++ src/en/guide/traits.gdoc | 1 + src/en/guide/traits/list.gdoc | 11 +++++++ src/en/guide/traits/overview.gdoc | 4 +++ src/en/guide/traits/overview/example.gdoc | 39 +++++++++++++++++++++++ 5 files changed, 63 insertions(+) create mode 100644 src/en/guide/traits.gdoc create mode 100644 src/en/guide/traits/list.gdoc create mode 100644 src/en/guide/traits/overview.gdoc create mode 100644 src/en/guide/traits/overview/example.gdoc diff --git a/src/en/guide/toc.yml b/src/en/guide/toc.yml index d8a30db7ebb..28bf3296c1e 100644 --- a/src/en/guide/toc.yml +++ b/src/en/guide/toc.yml @@ -171,6 +171,14 @@ theWebLayer: interceptorMatching: Matching Requests with Inteceptors interceptorOrdering: Ordering Interceptor Execution contentNegotiation: Content Negotiation +traits: + title: Traits + overview: + title: Overview + example: + title: WebAttributes Trait Example + list: + title: Traits Provided webServices: title: Web Services REST: diff --git a/src/en/guide/traits.gdoc b/src/en/guide/traits.gdoc new file mode 100644 index 00000000000..817a2181ce0 --- /dev/null +++ b/src/en/guide/traits.gdoc @@ -0,0 +1 @@ +h2. Traits Provided By Grails diff --git a/src/en/guide/traits/list.gdoc b/src/en/guide/traits/list.gdoc new file mode 100644 index 00000000000..084803e8658 --- /dev/null +++ b/src/en/guide/traits/list.gdoc @@ -0,0 +1,11 @@ +Below is a list of traits provided by the framework. The javadocs provide more detail about methods and properties related to each trait. + +{table} + *Trait* | *Brief Description* + [WebAttributes|api:grails.web.api.WebAttributes] | Common Web Attributes + [ServletAttributes|api:grails.web.api.ServletAttributes] | Servlet API Attributes + [DataBinder|api:grails.web.databinding.DataBinder] | Data Binding API + [RequestForwarder|api:grails.artefact.controller.support.RequestForwarder] | Request Forwarding API + [ResponseRedirector|api:grails.artefact.controller.support.ResponseRedirector] | Response Redirecting API + [ResponseRenderer|api:grails.artefact.controller.support.ResponseRenderer] | Response Rendering API +{table} diff --git a/src/en/guide/traits/overview.gdoc b/src/en/guide/traits/overview.gdoc new file mode 100644 index 00000000000..cbc8863c212 --- /dev/null +++ b/src/en/guide/traits/overview.gdoc @@ -0,0 +1,4 @@ +h3. Overview + +Grails provides a number of traits which provide access to properties and behavior that may be accessed from various Grails artefacts as well as arbitrary Groovy classes which are part of a Grails project. Many of these traits are automatically added to Grails artefact classes (like controllers and taglibs, for example) and are easy to add to other classes. + diff --git a/src/en/guide/traits/overview/example.gdoc b/src/en/guide/traits/overview/example.gdoc new file mode 100644 index 00000000000..3a5f8c7f627 --- /dev/null +++ b/src/en/guide/traits/overview/example.gdoc @@ -0,0 +1,39 @@ +[WebAttributes|api:grails.web.api.WebAttributes] is one of the traits provided by the framework. Any Groovy class may implement this trait to inherit all of the properties and behaviors provided by the trait. + +{code:title=src/main/groovy/demo/Helper.groovy} +// src/main/groovy/demo/Helper.groovy +package demo + +import grails.web.api.WebAttributes + +class Helper implements WebAttributes { + + List getControllerNames() { + // There is no need to pass grailsApplication as an argument + // or otherwise inject the grailsApplication property. The + // WebAttributes trait provides access to grailsApplication. + grailsApplication.getArtefacts('Controller')*.name + } +} +{code} + +The traits are compatible with static compilation... + +{code:title=src/main/groovy/demo/Helper.groovy} +// src/main/groovy/demo/Helper.groovy +package demo + +import grails.web.api.WebAttributes +import groovy.transform.CompileStatic + +@CompileStatic +class Helper implements WebAttributes { + + List getControllerNames() { + // There is no need to pass grailsApplication as an argument + // or otherwise inject the grailsApplication property. The + // WebAttributes trait provides access to grailsApplication. + grailsApplication.getArtefacts('Controller')*.name + } +} +{code} From 0d9f62842e75a53e5d1cd404d8ac8061b9feac55 Mon Sep 17 00:00:00 2001 From: Jeff Scott Brown Date: Tue, 24 Feb 2015 22:31:52 -0600 Subject: [PATCH 082/230] mention Validateable --- src/en/guide/traits/list.gdoc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/en/guide/traits/list.gdoc b/src/en/guide/traits/list.gdoc index 084803e8658..648e4a9dca6 100644 --- a/src/en/guide/traits/list.gdoc +++ b/src/en/guide/traits/list.gdoc @@ -8,4 +8,5 @@ Below is a list of traits provided by the framework. The javadocs provide more [RequestForwarder|api:grails.artefact.controller.support.RequestForwarder] | Request Forwarding API [ResponseRedirector|api:grails.artefact.controller.support.ResponseRedirector] | Response Redirecting API [ResponseRenderer|api:grails.artefact.controller.support.ResponseRenderer] | Response Rendering API + [Validateable|api:grails.validation.Validateable] | Validation API {table} From e3577816daf4bc5bb7c4b78a034066f40586905c Mon Sep 17 00:00:00 2001 From: Jeff Scott Brown Date: Tue, 24 Feb 2015 22:37:34 -0600 Subject: [PATCH 083/230] document fully qualified trait names --- src/en/guide/traits/list.gdoc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/en/guide/traits/list.gdoc b/src/en/guide/traits/list.gdoc index 648e4a9dca6..fd55755e495 100644 --- a/src/en/guide/traits/list.gdoc +++ b/src/en/guide/traits/list.gdoc @@ -2,11 +2,11 @@ Below is a list of traits provided by the framework. The javadocs provide more {table} *Trait* | *Brief Description* - [WebAttributes|api:grails.web.api.WebAttributes] | Common Web Attributes - [ServletAttributes|api:grails.web.api.ServletAttributes] | Servlet API Attributes - [DataBinder|api:grails.web.databinding.DataBinder] | Data Binding API - [RequestForwarder|api:grails.artefact.controller.support.RequestForwarder] | Request Forwarding API - [ResponseRedirector|api:grails.artefact.controller.support.ResponseRedirector] | Response Redirecting API - [ResponseRenderer|api:grails.artefact.controller.support.ResponseRenderer] | Response Rendering API - [Validateable|api:grails.validation.Validateable] | Validation API + [grails.web.api.WebAttributes|api:grails.web.api.WebAttributes] | Common Web Attributes + [grails.web.api.ServletAttributes|api:grails.web.api.ServletAttributes] | Servlet API Attributes + [grails.web.databinding.DataBinder|api:grails.web.databinding.DataBinder] | Data Binding API + [grails.artefact.controller.support.RequestForwarder|api:grails.artefact.controller.support.RequestForwarder] | Request Forwarding API + [grails.artefact.controller.support.ResponseRedirector|api:grails.artefact.controller.support.ResponseRedirector] | Response Redirecting API + [grails.artefact.controller.support.ResponseRenderer|api:grails.artefact.controller.support.ResponseRenderer] | Response Rendering API + [grails.validation.Validateable|api:grails.validation.Validateable] | Validation API {table} From 2f7b4e2d09e218ad51842f5559dbe2b73606e129 Mon Sep 17 00:00:00 2001 From: graemerocher Date: Wed, 25 Feb 2015 11:52:58 +0100 Subject: [PATCH 084/230] More docs on upgrading plugins and applications --- src/en/guide/toc.yml | 5 +- src/en/guide/upgrading.gdoc | 65 +++++++ src/en/guide/upgrading/upgradingApps.gdoc | 54 ++++++ src/en/guide/upgrading/upgradingPlugins.gdoc | 180 +++++++++++++++++ src/en/guide/upgradingFrom2.gdoc | 191 ------------------- src/en/ref/Command Line/bootstrap.gdoc | 42 ---- src/en/ref/Command Line/clean-all.gdoc | 18 -- src/en/ref/Command Line/create-command.gdoc | 62 ++++++ src/en/ref/Command Line/create-script.gdoc | 35 ++-- src/en/ref/Command Line/init.gdoc | 19 -- 10 files changed, 383 insertions(+), 288 deletions(-) create mode 100644 src/en/guide/upgrading.gdoc create mode 100644 src/en/guide/upgrading/upgradingApps.gdoc create mode 100644 src/en/guide/upgrading/upgradingPlugins.gdoc delete mode 100644 src/en/guide/upgradingFrom2.gdoc delete mode 100644 src/en/ref/Command Line/bootstrap.gdoc delete mode 100644 src/en/ref/Command Line/clean-all.gdoc create mode 100644 src/en/ref/Command Line/create-command.gdoc delete mode 100644 src/en/ref/Command Line/init.gdoc diff --git a/src/en/guide/toc.yml b/src/en/guide/toc.yml index 28bf3296c1e..f9c91ea1f88 100644 --- a/src/en/guide/toc.yml +++ b/src/en/guide/toc.yml @@ -21,7 +21,10 @@ gettingStarted: supportedJavaEEContainers: Supported Java EE Containers creatingArtefacts: Creating Artefacts generatingAnApplication: Generating an Application -upgradingFrom2: Upgrading from Grails 2.x +upgrading: + title: Upgrading from Grails 2.x + upgradingPlugins: Upgrading Plugins + upgradingApps: Upgrading Applications conf: title: Configuration config: diff --git a/src/en/guide/upgrading.gdoc b/src/en/guide/upgrading.gdoc new file mode 100644 index 00000000000..0d31c0ff9f5 --- /dev/null +++ b/src/en/guide/upgrading.gdoc @@ -0,0 +1,65 @@ +Grails 3.0 is a complete ground up rewrite of Grails and introduces new concepts and components for many parts of the framework. + +When upgrading an application or plugin from Grails 3.0 there are many areas to consider including: + +* Project structure differences +* File location differences +* Configuration differences +* Package name differences +* Legacy Gant Scripts +* Gradle Build System +* Changes to Plugins +* Source vs Binary Plugins + +The best approach to take when upgrading a plugin or application (and if your application is using several plugins the plugins will need upgrading first) is to create a new Grails 3.0 application of the same name and copy the source files into the correct locations in the new application. + +h3. Project Structure Changes + +h4. File Location Differences + +The location of certain files have changed or been replaced with other files in Grails 3.0. The following table lists old default locations and their respective new locations: + +{table} +*Old Location* | *New Location* | *Description* +@grails-app/conf/BuildConfig.groovy@ | @build.gradle@ | Build time configuration is now defined in a Gradle build file +@grails-app/conf/Config.groovy@ | @grails-app/conf/application.groovy@ | Renamed for consistency with Spring Boot +@grails-app/conf/UrlMappings.groovy@ | @grails-app/controllers/UrlMappings.groovy@ | Moved since grails-app/conf is not a source directory anymore +@grails-app/conf/BootStrap.groovy@ | @grails-app/init/BootStrap.groovy@ | Moved since grails-app/conf is not a source directory anymore +@scripts@ | @src/main/scripts@ | Moved for consistency with Gradle +@src/groovy@ | @src/main/groovy@ | Moved for consistency with Gradle +@src/java@ | @src/main/groovy@ | Moved for consistency with Gradle +@test/unit@ | @src/test/groovy@ | Moved for consistency with Gradle +@test/integration@ | @src/integration-test/groovy@ | Moved for consistency with Gradle +@web-app@ | @src/main/webapp@ | Moved for consistency with Gradle +@\*GrailsPlugin.groovy@ | @src/main/groovy@ | The plugin descriptor moved to a source directory +{table} + +For plugins the plugin descriptor (a Groovy file ending with "GrailsPlugin") which was previously located in the root of the plugin directory should be moved to the @src/main/groovy@ directory under an appropriate package. + +h4. New Files Not Present in Grails 2.x + +The reason it is best to create a new application and copy your original sources to it is because there are a number of new files that are not present in Grails 2.x by default. These include: + +{table} +*File* | *Description* +@build.gradle@ | The Gradle build descriptor located in the root of the project +@gradle.properties@ | Properties file defining the Grails and Gradle versions +@grails-app/conf/logback.groovy@ | Logging previously defined in @Config.groovy@ is now defined using Logback +@grails-app/conf/application.yml@ | Configuration can now also be defined using YAML +@grails-app/init/PACKAGE_PATH/Application.groovy@ | The @Application@ class used By Spring Boot to start the application +{table} + +h4. Files Not Present in Grails 3.x + +Some files that were previously created by Grails 2.x are no longer created. These have either been removed or an appropriate replacement added. The following table lists files no longer in use: + +{table} +*File* | *Description* +@application.properties@ | The application name and version is now defined in @build.gradle@ +@grails-app/conf/DataSource.groovy@ | Merged together into @application.yml@ +@lib@ | Dependency resolution should be used to resolve JAR files +@web-app/WEB-INF/applicationContext.xml@ | Removed, beans can be defined in @grails-app/conf/spring/resources.groovy@ +@src/templates/war/web.xml@ | Grails 3.0 no longer requires web.xml. Customizations can be done via Spring +@web-app/WEB-INF/sitemesh.xml@ | Removed, sitemesh filter no longer present. +@web-app/WEB-INF/tld@ | Removed, can be restored in src/main/webapp +{table} diff --git a/src/en/guide/upgrading/upgradingApps.gdoc b/src/en/guide/upgrading/upgradingApps.gdoc new file mode 100644 index 00000000000..c7ee1cb06b9 --- /dev/null +++ b/src/en/guide/upgrading/upgradingApps.gdoc @@ -0,0 +1,54 @@ +Upgrading applications to Grails 3.x will require that you upgrade all plugins the application uses first, hence you should follow the steps in the previous section to first upgrade your plugins. + +h4. Step 1 - Create a New Application + +Once the plugins are Grails 3.x compatible you can upgrade the application. To upgrade an application it is again best to create a new Grails 3 application using the "web" profile: + +{code} +$ grails create-app myapp +$ cd myapp +{code} + +h4. Step 2 - Migrate Sources + +The next step is to copy the sources from the original Grails 2 application to the Grails 3 application: + +{code} +# first the sources +cp -rf ../old_app/src/groovy src/main/groovy +cp -rf ../old_app/src/java src/main/groovy +cp -rf ../old_app/grails-app grails-app + +# then the tests +cp -rf ../old_app/test/unit src/test/groovy +mkdir -p src/integration-test/groovy +cp -rf ../old_app/test/integration src/integration-test/groovy +{code} + +h4. Step 3 - Update the Gradle build with required dependencies + +The repositories and dependencies defined in @grails-app/conf/BuildConfig.groovy@ of the original Grails 2.x application will need to be defined in @build.gradle@ of the new Grails 3.x application. + +h4. Step 4 - Modify Package Imports + +In Grails 3.x all internal APIs can be found in the @org.grails@ package and public facing APIs in the @grails@ package. The @org.codehaus.groovy.grails@ package no longer exists. + +All package declaration in sources should be modified for the new location of the respective classes. Example @org.codehaus.groovy.grails.commons.GrailsApplication@ is now @grails.core.GrailsApplication@. + +h4. Step 5 - Migrate Configuration + +The configuration of the application will need to be migrated, this can normally be done by simply renaming @grails-app/conf/Config.groovy@ to @grails-app/conf/application.groovy@ and merging the content of @grails-app/conf/DataSource.groovy@ into @grails-app/conf/application.groovy@. + +Note however that Log4j has been replaced by @grails-app/conf/logback.groovy@ for logging, so any logging configuration in @grails-app/conf/Config.groovy@ should be migrated to [logback format|http://logback.qos.ch/manual/groovy.html]. + +h4. Step 6 - Migrate web.xml Modifications to Spring + +If you have a modified @web.xml@ template then you will need to migrate this to Spring as Grails 3.x does not use a web.xml (although it is still possible to have on in @src/main/webapp/WEB-INF/web.xml@). + +New servlets and filters can be registered as Spring beans or with [ServletRegistrationBean|api:org.springframework.boot.context.embedded.ServletRegistrationBean] and [FilterRegistrationBean|api:org.springframework.boot.context.embedded.FilterRegistrationBean] respectively. + +h4. Step 7 - Migrate Tests + +Once the package names are corrected unit tests will continue to run, however any tests that extend the deprecated and removed JUnit 3 hierarchy will need to be migrated to Spock or JUnit 4. + +Integration tests will need to be annotated with the [Integration|api:grails.test.mixin.integration.Integration] annotation and should not extend GroovyTestCase or any JUnit 3 super class. diff --git a/src/en/guide/upgrading/upgradingPlugins.gdoc b/src/en/guide/upgrading/upgradingPlugins.gdoc new file mode 100644 index 00000000000..c2bdbddb44e --- /dev/null +++ b/src/en/guide/upgrading/upgradingPlugins.gdoc @@ -0,0 +1,180 @@ +To upgrade a Grails 2.x plugin to Grails 3.x you need to make a number of different changes. This documentation will outline the steps that were taken to upgrade the Quartz plugin to Grails 3, each individual plugin may differ. + +h4. Step 1 - Create a new Grails 3 plugin + +The first step is to create a new Grails 3 plugin using the command line: + +{code} +$ grails create-plugin quartz +{code} + +This will create a Grails 3 plugin in the @quartz@ directory. + +h4. Step 2 - Copy sources from the original Grails 2 plugin + +The next step is to copy the sources from the original Grails 2 plugin to the Grails 3 plugin: + +{code} +# first the sources +cp -rf ../quartz-2.x/src/groovy src/main/groovy +cp -rf ../quartz-2.x/src/java src/main/groovy +cp -rf ../quartz-2.x/grails-app grails-app +cp -rf ../quartz-2.x/QuartzGrailsPlugin.groovy src/main/groovy/grails/plugins/quartz + +# then the tests +cp -rf ../quartz-2.x/test/unit src/test/groovy +mkdir -p src/integration-test/groovy +cp -rf ../quartz-2.x/test/integration src/integration-test/groovy + +# then templates / other resources +cp -rf ../quartz-2.x/src/templates src/main/templates +{code} + +h4. Step 3 - Alter the plugin descriptor + +You will need to add a package declaration to the plugin descriptor. In this case @QuartzGrailsPlugin@ is modified as follows: + +{code} +// add package declaration +package grails.plugins.quartz +... +class QuartzGrailsPlugin { + ... +} +{code} + +In addition you should remove the @version@ property from the descriptor as this is now defined in @build.gradle@. + +h4. Step 4 - Update the Gradle build with required dependencies + +The repositories and dependencies defined in @grails-app/conf/BuildConfig.groovy@ of the original Grails 2.x plugin will need to be defined in @build.gradle@ of the new Grails 3.x plugin: + +{code} + compile("org.quartz-scheduler:quartz:2.2.1") { + exclude group: 'slf4j-api', module: 'c3p0' + } +{code} + +h4. Step 5 - Modify Package Imports + +In Grails 3.x all internal APIs can be found in the @org.grails@ package and public facing APIs in the @grails@ package. The @org.codehaus.groovy.grails@ package no longer exists. + +All package declaration in sources should be modified for the new location of the respective classes. Example @org.codehaus.groovy.grails.commons.GrailsApplication@ is now @grails.core.GrailsApplication@. + +h4. Step 5 - Migrate Plugin Specific Config to application.yml + +Some plugins define a default configuration file. For example the Quartz plugin defines a file called @grails-app/conf/DefaultQuartzConfig.groovy@. In Grails 3.x this default configuration can be migrated to @grails-app/conf/application.yml@ and it will automatically be loaded by Grails without requiring manual configuration merging. + +h4. Step 6 - Register ArtefactHandler Definitions + +In Grails 3.x [ArtefactHandler|api:grails.core.ArtefactHandler] definitions written in Java need to be declared in a file called @src/main/resources/META-INF/grails.factories@ since these need to be known at compile time. + +{note} +If the @ArtefactHandler@ is written in Groovy this step can be skipped as Grails will automatically create the @grails.factories@ file during compilation. +{note} + +The Quartz plugin requires the following definition to register the @ArtrefactHandler@: + +{code} +grails.core.ArtefactHandler=grails.plugins.quartz.JobArtefactHandler +{code} + +h4. Step 7 - Migrate Code Generation Scripts + +Many plugins previously defined command line scripts in Gant. In Grails 3.x command line scripts have been replaced by two new features: Code generation scripts and Gradle tasks. + +If your script is doing simple code generation then for many cases a code generation script can replace an old Gant script. + +The @create-job@ script provided by the Quartz plugin in Grails 2.x was defined in @scripts/CreateJob.groovy@ as: + +{code} +includeTargets << grailsScript("_GrailsCreateArtifacts") + +target(createJob: "Creates a new Quartz scheduled job") { + depends(checkVersion, parseArguments) + + def type = "Job" + promptForName(type: type) + + for (name in argsMap.params) { + name = purgeRedundantArtifactSuffix(name, type) + createArtifact(name: name, suffix: type, type: type, path: "grails-app/jobs") + createUnitTest(name: name, suffix: type) + } +} + +setDefaultTarget 'createJob' +{code} + +A replacement Grails 3.x compatible script can be created using the @create-script@ command: + +{code} +$ grails create-script create-job +{code} + +Which creates a new script called @src/main/scripts/create-job.groovy@. Using the new code generation API it is simple to implement: + +{code} +description("Creates a new Quartz scheduled job") { + usage "grails create-job [JOB NAME]" + argument name:'Job Name', description:"The name of the job" +} + +model = model( args[0] ) +render template:"Job.groovy", + destination: file( "grails-app/jobs/$model.packagePath/${model.simpleName}Job.groovy"), + model: model +{code} + +Please refer to the documentation on [Creating Custom Scripts|guide:creatingCustomScripts] for more information. + +h4. Migrating More Complex Scripts Using Gradle Tasks + +Using the old Grails 2.x build system it was relatively common to spin up Grails inside the command line. In Grails 3.x it is not possible to load a Grails application within a code generation script created by the [create-script|commandLine] command. + +Instead a new mechanism specific to plugins exists via the [create-command|commandLine] command. The @create-command@ command will create a new [ApplicationCommand|api:grails.dev.commands.ApplicationCommand], for example the following command will execute a query: + +{code} +import grails.dev.commands.* +import javax.sql.* +import groovy.sql.* +import org.springframework.beans.factory.annotation.* + +class RunQueryCommand implements ApplicationCommand { + + @Autowired + DataSource dataSource + + boolean handle(ExecutionContext ctx) { + def sql = new Sql(dataSource) + println sql.executeQuery("select * from foo") + return true + } +} +{code} + +With this command in place once the plugin is installed into your local Maven cache you can add the plugin to both the build classpath and the runtime classpath of the application's @build.gradle@ file: + +{code} +buildscript { + ... + dependencies { + classpath "org.grails.plugins:myplugin:0.1-SNAPSHOT" + } + ... + dependencies { + runtime "org.grails.plugins:myplugin:0.1-SNAPSHOT" + } +} +{code} + +Grails will automatically create a Gradle task called @runQuery@ and a command named @run-query@ so both the following examples will execute the command: + +{code} +$ grails run-query +$ gradle runQuery +{code} + +h4. Step 8 - Delete Files that were migrated or no longer used + +You should now delete and cleanup the project of any files no longer required by Grails 3.x (@BuildConfig.groovy@, @Config.groovy@, @DataSource.groovy@ etc.) diff --git a/src/en/guide/upgradingFrom2.gdoc b/src/en/guide/upgradingFrom2.gdoc deleted file mode 100644 index c5a4ce571f3..00000000000 --- a/src/en/guide/upgradingFrom2.gdoc +++ /dev/null @@ -1,191 +0,0 @@ -Grails 3.0 is a complete ground up rewrite of Grails and introduces new concepts and components for many parts of the framework. - -When upgrading an application or plugin from Grails 3.0 there are many areas to consider including: - -* Project structure differences -* File location differences -* Configuration differences -* Package name differences -* Legacy Gant Scripts -* Gradle Build System -* Changes to Plugins -* Source vs Binary Plugins - -The best approach to take when upgrading a plugin or application (and if your application is using several plugins the plugins will need upgrading first) is to create a new Grails 3.0 application of the same name and copy the source files into the correct locations in the new application. - -h3. Project Structure Changes - -h4. File Location Differences - -The location of certain files have changed or been replaced with other files in Grails 3.0. The following table lists old default locations and their respective new locations: - -{table} -*Old Location* | *New Location* | *Description* -@grails-app/conf/BuildConfig.groovy@ | @build.gradle@ | Build time configuration is now defined in a Gradle build file -@grails-app/conf/Config.groovy@ | @grails-app/conf/application.groovy@ | Renamed for consistency with Spring Boot -@grails-app/conf/UrlMappings.groovy@ | @grails-app/controllers/UrlMappings.groovy@ | Moved since grails-app/conf is not a source directory anymore -@grails-app/conf/BootStrap.groovy@ | @grails-app/init/BootStrap.groovy@ | Moved since grails-app/conf is not a source directory anymore -@scripts@ | @src/main/scripts@ | Moved for consistency with Gradle -@src/groovy@ | @src/main/groovy@ | Moved for consistency with Gradle -@src/java@ | @src/main/groovy@ | Moved for consistency with Gradle -@test/unit@ | @src/test/groovy@ | Moved for consistency with Gradle -@test/integration@ | @src/integration-test/groovy@ | Moved for consistency with Gradle -@web-app@ | @src/main/webapp@ | Moved for consistency with Gradle -@\*GrailsPlugin.groovy@ | @src/main/groovy@ | The plugin descriptor moved to a source directory -{table} - -For plugins the plugin descriptor (a Groovy file ending with "GrailsPlugin") which was previously located in the root of the plugin directory should be moved to the @src/main/groovy@ directory under an appropriate package. - -h4. New Files Not Present in Grails 2.x - -The reason it is best to create a new application and copy your original sources to it is because there are a number of new files that are not present in Grails 2.x by default. These include: - -{table} -*File* | *Description* -@build.gradle@ | The Gradle build descriptor located in the root of the project -@gradle.properties@ | Properties file defining the Grails and Gradle versions -@grails-app/conf/logback.groovy@ | Logging previously defined in @Config.groovy@ is now defined using Logback -@grails-app/conf/application.yml@ | Configuration can now also be defined using YAML -@grails-app/init/PACKAGE_PATH/Application.groovy@ | The @Application@ class used By Spring Boot to start the application -{table} - -h4. Files Not Present in Grails 3.x - -Some files that were previously created by Grails 2.x are no longer created. These have either been removed or an appropriate replacement added. The following table lists files no longer in use: - -{table} -*File* | *Description* -@application.properties@ | The application name and version is now defined in @build.gradle@ -@grails-app/conf/DataSource.groovy@ | Merged together into @application.yml@ -@lib@ | Dependency resolution should be used to resolve JAR files -@web-app/WEB-INF/applicationContext.xml@ | Removed, beans can be defined in @grails-app/conf/spring/resources.groovy@ -@src/templates/war/web.xml@ | Grails 3.0 no longer requires web.xml. Customizations can be done via Spring -@web-app/WEB-INF/sitemesh.xml@ | Removed, sitemesh filter no longer present. -@web-app/WEB-INF/tld@ | Removed, can be restored in src/main/webapp -{table} - -h3. Upgrading a Plugin to Grails 3.x - -To upgrade a Grails 2.x plugin to Grails 3.x you need to make a number of different changes. This documentation will outline the steps that were taken to upgrade the Quartz plugin to Grails 3, each individual plugin may differ. - -h4. Step 1 - Create a new Grails 3 plugin - -The first step is to create a new Grails 3 plugin using the command line: - -{code} -$ grails create-plugin quartz -{code} - -This will create a Grails 3 plugin in the @quartz@ directory. - -h4. Step 2 - Copy sources from the original Grails 2 plugin - -The next step is to copy the sources from the original Grails 2 plugin to the Grails 3 plugin: - -{code} -# first the sources -cp -rf ../quartz-2.x/src/groovy src/main/groovy -cp -rf ../quartz-2.x/src/java src/main/groovy -cp -rf ../quartz-2.x/grails-app grails-app -cp -rf ../quartz-2.x/QuartzGrailsPlugin.groovy src/main/groovy/grails/plugins/quartz - -# then the tests -cp -rf ../quartz-2.x/test/unit src/test/groovy -mkdir -p src/integration-test/groovy -cp -rf ../quartz-2.x/test/integration src/integration-test/groovy - -# then templates / other resources -cp -rf ../quartz-2.x/src/templates src/main/templates -{code} - -You will need to add a package declaration to the plugin descriptor. In this case @QuartzGrailsPlugin@ is modified as follows: - -{code} -// add package declaration -package grails.plugins.quartz -... -class QuartzGrailsPlugin { - ... -} -{code} - -h4. Step 3 - Update the Gradle build with required dependencies - -The repositories and dependencies defined in @grails-app/conf/BuildConfig.groovy@ of the original Grails 2.x plugin will need to be defined in @build.gradle@ of the new Grails 3.x plugin: - -{code} - compile("org.quartz-scheduler:quartz:2.2.1") { - exclude group: 'slf4j-api', module: 'c3p0' - } -{code} - -h4. Step 4 - Modify Package Imports - -In Grails 3.x all internal APIs can be found in the @org.grails@ package and public facing APIs in the @grails@ package. The @org.codehaus.groovy.grails@ package no longer exists. - -All package declaration in sources should be modified for the new location of the respective classes. Example @org.codehaus.groovy.grails.commons.GrailsApplication@ is now @grails.core.GrailsApplication@. - -h4. Step 5 - Migrate Plugin Specific Config to application.yml - -Some plugins define a default configuration fail. For example the Quartz plugin defines a file called @grails-app/conf/DefaultQuartzConfig.groovy@. In Grails 3.x this default configuration can be migrated to @grails-app/conf/application.yml@ and it will automatically be loaded by Grails without requiring manual configuration merging. - -h4. Step 6 - Register ArtefactHandler Definitions - -In Grails 3.x ArtefactHandler definitions need to be declared in a file called @src/main/resources/META-INF/grails.factories@ since these need to be known at compile time. The Quartz plugin requires the following definition to register the ArtrefactHandler: - -{code} -grails.core.ArtefactHandler=grails.plugins.quartz.JobArtefactHandler -{code} - -h4. Step 7 - Migrate Code Generation Scripts - -Many plugins previously defined command line scripts in Gant. In Grails 3.x command line scripts have been replaced by two new features: Code generation scripts and Gradle tasks. - -If your script is doing simple code generation then for many cases a code generation script can replace an old Gant script. - -The @create-job@ script provided by the Quartz plugin in Grails 2.x was defined in @scripts/CreateJob.groovy@ as: - -{code} -includeTargets << grailsScript("_GrailsCreateArtifacts") - -target(createJob: "Creates a new Quartz scheduled job") { - depends(checkVersion, parseArguments) - - def type = "Job" - promptForName(type: type) - - for (name in argsMap.params) { - name = purgeRedundantArtifactSuffix(name, type) - createArtifact(name: name, suffix: type, type: type, path: "grails-app/jobs") - createUnitTest(name: name, suffix: type) - } -} - -setDefaultTarget 'createJob' -{code} - -A replacement Grails 3.x compatible script can be created using the @create-script@ command: - -{code} -$ grails create-script create-job -{code} - -Which creates a new script called @src/main/scripts/create-job.groovy@. Using the new code generation API it is simple to implement: - -{code} -description("Creates a new Quartz scheduled job") { - usage "grails create-job [JOB NAME]" - argument name:'Job Name', description:"The name of the job" -} - -model = model( args[0] ) -render template:"Job.groovy", - destination: file( "grails-app/jobs/$model.packagePath/${model.simpleName}Job.groovy"), - model: model -{code} - -Please refer to the documentation on [Creating Custom Scripts|guide:creatingCustomScripts] for more information. - -h4. Migrating More Complex Scripts Using Gradle Tasks - -Using the old Grails 2.x build system it was relatively common to spin up Grails inside the command line. In Grails 3.x it is not possible to load a Grails application within a command line script. diff --git a/src/en/ref/Command Line/bootstrap.gdoc b/src/en/ref/Command Line/bootstrap.gdoc deleted file mode 100644 index 57e65a5dec4..00000000000 --- a/src/en/ref/Command Line/bootstrap.gdoc +++ /dev/null @@ -1,42 +0,0 @@ -h1. bootstrap - -h2. Purpose - -The [bootstrap|commandLine] command is mainly intended to be used by other scripts and enables the ability to bootstrap a Grails application instance outside of the container for usage in tools that require a reference to Grails' @ApplicationContext@. - -Examples of its usage include Grails' [shell|commandLine] and [console|commandLine] - -h2. Examples - -Add this to the top of your Gant script to use this as an include: - -{code:java} -includeTargets << grailsScript("_GrailsBootstrap") -{code} - -Once this is in place you can bootstrap Grails using either of these methods: - -* @loadApp@ - Loads and creates the @GrailsApplication@ instance -* @configureApp@ - Loads all plugins and creates the Spring @ApplicationContext@ - -After running @loadApp@ the @GrailsApplication@ instance will be available as the @grailsApp@ variable: - -{code:java} -loadApp() -for (grailsClass in grailsApp.allClasses) { println grailsClass } -{code} - -After running @configureApp@ the [GrailsPluginManager|api:org.codehaus.groovy.grails.plugins.GrailsPluginManager] instance will be available as the @pluginManager@ variable and the Spring @ApplicationContext@ instance will be available as the @appCtx@ variable: - -{code:java} -configureApp() -Connection c = appCtx.getBean('dataSource').getConnection() -// do something with connection -{code} - -h2. Description - -Usage: -{code:java} -grails bootstrap -{code} diff --git a/src/en/ref/Command Line/clean-all.gdoc b/src/en/ref/Command Line/clean-all.gdoc deleted file mode 100644 index 4584efedf45..00000000000 --- a/src/en/ref/Command Line/clean-all.gdoc +++ /dev/null @@ -1,18 +0,0 @@ -h1. clean-all - -h2. Purpose - -The @clean-all@ command deletes all compiled resources from the application including the work directory, which contains project-specific temporary files. Since Groovy is a compiled language, as with Java, this is sometimes useful to clear old instances of classes and ensure correct compilation. It's also a good idea to run this script before running tests or creating a WAR file to ensure a full compilation occurs. - -h2. Examples - -{code} -grails clean-all -{code} - -h2. Description - -Usage: -{code:java} -grails clean-all -{code} diff --git a/src/en/ref/Command Line/create-command.gdoc b/src/en/ref/Command Line/create-command.gdoc new file mode 100644 index 00000000000..b589ea71213 --- /dev/null +++ b/src/en/ref/Command Line/create-command.gdoc @@ -0,0 +1,62 @@ +h1. create-command + +h2. Purpose + +The @create-command@ command creates a new Grails Gradle task and shell command that can be run with the @grails@ command from a terminal window. + +h2. Examples + +The command: + +{code:java} +grails create-command MyExample +{code} + +Creates a class called @grails-app/commands/PACKAGE_PATH/MyExampleCommand.groovy@ such as: + +{code:java} +import grails.dev.commands.* + +class MyExampleCommand implements ApplicationCommand { + + boolean handle(ExecutionContext ctx) { + def dataSource = applicationContext.getBean(DataSource) + return true + } +} + +{code} + +The command can then be run with: + +{code:java} +grails my-example +{code} + +Or as a Gradle task: + +{code:java} +gradle myExample +{code} + +Note that the plugin should be on both the build classpath and the runtime classpath in @build.gradle@: + +{code} +buildscript { + ... + dependencies { + classpath "org.grails.plugins:myplugin:0.1-SNAPSHOT" + } + ... + dependencies { + runtime "org.grails.plugins:myplugin:0.1-SNAPSHOT" + } +} +{code} + + +h2. Description + +In order to separate the code generation and build layer, in Grails 3.x scripts created with @create-script@ do not have access to the running application instance. + +Instead, Grails 3.x features a new concept called an [ApplicationCommand|api:grails.dev.commands.ApplicationCommand] that is invoked via Gradle to perform tasks such as interact with the database etc. diff --git a/src/en/ref/Command Line/create-script.gdoc b/src/en/ref/Command Line/create-script.gdoc index e5445166e21..189dfcc0c19 100644 --- a/src/en/ref/Command Line/create-script.gdoc +++ b/src/en/ref/Command Line/create-script.gdoc @@ -2,45 +2,46 @@ h1. create-script h2. Purpose -The @create-script@ command creates a new Grails executable script that can be run with the @grails@ command from a terminal window. +The @create-script@ command creates a new Grails code generation script that can be run with the @grails@ command from a terminal window. h2. Examples The command: {code:java} -grails create-script execute-report +grails create-script my-script {code} -Creates a script called @scripts/ExecuteReport.groovy@ such as: +Creates a script called @src/main/scripts/my-script.groovy@ such as: {code:java} -target('default': "The description of the script goes here!") { - doStuff() -} -target(doStuff: "The implementation task") { - // logic here -} +description "Example description", "grails example-usage" + +println "Example Script" {code} The command can then be run with: {code:java} -grails execute-report +grails my-script {code} h2. Description -The command will translate lower case command names separated by hyphens into a valid Groovy camel-cased class name. For example @create-controller@ would become a script called @scripts/CreateController.groovy@. +Each script extends from the super class [GroovyScriptCommand|api:org.grails.cli.profile.commands.script.GroovyScriptCommand] which provides an API for achieving a number of different tasks. -The script generated is a "Gant":http://groovy.codehaus.org/Gant script which can use Gant's capabilities to depend on other scripts from Grails core. Refer to the section on [Command Line Scripting|guide:commandLine] in the user guide. +h3. Invoking Gradle -Usage: +You can invoke Gradle using the @gradle@ property: -{code:java} -grails create-script [name] +{code} +gradle.assemble() {code} -Fired Events: +You can run any other Grails scripts by simply invoking the method: + +{code} +testApp() +{code} -* @CreatedFile@ - When the script has been created +Code generation can be performed using the [TemplateRenderer API|api:org.grails.cli.profile.commands.templates.TemplateRenderer] diff --git a/src/en/ref/Command Line/init.gdoc b/src/en/ref/Command Line/init.gdoc deleted file mode 100644 index d4f4b361cbd..00000000000 --- a/src/en/ref/Command Line/init.gdoc +++ /dev/null @@ -1,19 +0,0 @@ -h1. init - -h2. Purpose - -The @init@ command initialises the appropriate directory structure for a Grails application and sets some common variables for use by the calling script. It is typically used as an include. - -h2. Examples - -Command line: - -{code} -grails init -{code} - -or as an include: - -{code:java} -includeTargets << grailsScript("_GrailsInit") -{code} From 3b7fb4b1827a9edf6fafb40cdc58901ee6eba1fc Mon Sep 17 00:00:00 2001 From: graemerocher Date: Wed, 25 Feb 2015 14:27:44 +0100 Subject: [PATCH 085/230] =?UTF-8?q?rename=20packages=20=E2=80=98org.codeha?= =?UTF-8?q?us=E2=80=99=20->=20=E2=80=98org.grails=E2=80=99=20or=20?= =?UTF-8?q?=E2=80=98grails.=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/en/guide/conf/versioning.gdoc | 2 +- .../plugins/artefactApi/customArtefacts.gdoc | 4 +-- .../artefactApi/queryingArtefacts.gdoc | 4 +-- .../plugins/understandingPluginLoadOrder.gdoc | 2 +- src/en/guide/security/codecs.gdoc | 12 ++++---- src/en/guide/spring/springdsl.gdoc | 6 ++-- .../spring/theUnderpinningsOfGrails.gdoc | 2 +- src/en/guide/testing/unitTesting.gdoc | 8 ++--- .../unitTesting/unitTestingTagLibraries.gdoc | 2 +- .../gsp/GSPBasics/variablesAndScopes.gdoc | 4 +-- .../taglibs/taglibVariablesAndScopes.gdoc | 4 +-- src/en/guide/webServices/REST/binding.gdoc | 24 +++++++-------- .../webServices/REST/hypermedia/hal.gdoc | 6 ++-- .../REST/renderers/customRenderers.gdoc | 4 +-- .../renderers/objectMarshallerInterface.gdoc | 30 +++++++++---------- .../REST/renderers/objectMarshallers.gdoc | 6 ++-- .../webServices/REST/versioningResources.gdoc | 9 ++---- src/en/ref/Controllers/grailsApplication.gdoc | 4 +-- src/en/ref/Domain Classes/constraints.gdoc | 2 +- src/en/ref/Plug-ins/URL mappings.gdoc | 2 +- src/en/ref/Plug-ins/controllers.gdoc | 7 ++--- src/en/ref/Plug-ins/domainClasses.gdoc | 4 +-- src/en/ref/Plug-ins/filters.gdoc | 4 +-- src/en/ref/Plug-ins/hibernate.gdoc | 8 ++--- 24 files changed, 75 insertions(+), 85 deletions(-) diff --git a/src/en/guide/conf/versioning.gdoc b/src/en/guide/conf/versioning.gdoc index 9b23f4f5b5b..a1ed2cf223e 100644 --- a/src/en/guide/conf/versioning.gdoc +++ b/src/en/guide/conf/versioning.gdoc @@ -1,6 +1,6 @@ h4. Detecting Versions at Runtime -You can detect the application version using Grails' support for application metadata using the [GrailsApplication|api:org.codehaus.groovy.grails.commons.GrailsApplication] class. For example within [controllers|guide:controllers] there is an implicit [grailsApplication|controllers] variable that can be used: +You can detect the application version using Grails' support for application metadata using the [GrailsApplication|api:grails.core.GrailsApplication] class. For example within [controllers|guide:controllers] there is an implicit [grailsApplication|controllers] variable that can be used: {code:java} def version = grailsApplication.metadata.getApplicationVersion() diff --git a/src/en/guide/plugins/artefactApi/customArtefacts.gdoc b/src/en/guide/plugins/artefactApi/customArtefacts.gdoc index 179b393e5a5..615d1226997 100644 --- a/src/en/guide/plugins/artefactApi/customArtefacts.gdoc +++ b/src/en/guide/plugins/artefactApi/customArtefacts.gdoc @@ -9,9 +9,9 @@ class MyGrailsPlugin { The @artefacts@ list can contain either handler classes (as above) or instances of handlers. -So, what does an artefact handler look like? Well, put simply it is an implementation of the [ArtefactHandler|api:org.codehaus.groovy.grails.commons.ArtefactHandler] interface. To make life a bit easier, there is a skeleton implementation that can readily be extended: [ArtefactHandlerAdapter|api:org.codehaus.groovy.grails.commons.ArtefactHandlerAdapter]. +So, what does an artefact handler look like? Well, put simply it is an implementation of the [ArtefactHandler|api:grails.core.ArtefactHandler] interface. To make life a bit easier, there is a skeleton implementation that can readily be extended: [ArtefactHandlerAdapter|api:grails.core.ArtefactHandlerAdapter]. -In addition to the handler itself, every new artefact needs a corresponding wrapper class that implements [GrailsClass|api:org.codehaus.groovy.grails.commons.GrailsClass]. Again, skeleton implementations are available such as [AbstractInjectableGrailsClass|api:org.codehaus.groovy.grails.commons.AbstractInjectableGrailsClass], which is particularly useful as it turns your artefact into a Spring bean that is auto-wired, just like controllers and services. +In addition to the handler itself, every new artefact needs a corresponding wrapper class that implements [GrailsClass|api:grails.core.GrailsClass]. Again, skeleton implementations are available such as [AbstractInjectableGrailsClass|api:org.grails.core.AbstractInjectableGrailsClass], which is particularly useful as it turns your artefact into a Spring bean that is auto-wired, just like controllers and services. The best way to understand how both the handler and wrapper classes work is to look at the Quartz plugin: diff --git a/src/en/guide/plugins/artefactApi/queryingArtefacts.gdoc b/src/en/guide/plugins/artefactApi/queryingArtefacts.gdoc index 927cfd99c6f..00946a1aee9 100644 --- a/src/en/guide/plugins/artefactApi/queryingArtefacts.gdoc +++ b/src/en/guide/plugins/artefactApi/queryingArtefacts.gdoc @@ -1,4 +1,4 @@ -As a plugin developer, it can be important for you to find out about what domain classes, controllers, or other types of artefact are available in an application. For example, the [Searchable plugin|http://grails.org/plugin/searchable] needs to know what domain classes exist so it can check them for any @searchable@ properties and index the appropriate ones. So how does it do it? The answer lies with the @grailsApplication@ object, and instance of [GrailsApplication|api:org.codehaus.groovy.grails.commons.GrailsApplication] that's available automatically in controllers and GSPs and can be [injected|guide:dependencyInjectionServices] everywhere else. +As a plugin developer, it can be important for you to find out about what domain classes, controllers, or other types of artefact are available in an application. For example, the [Searchable plugin|http://grails.org/plugin/searchable] needs to know what domain classes exist so it can check them for any @searchable@ properties and index the appropriate ones. So how does it do it? The answer lies with the @grailsApplication@ object, and instance of [GrailsApplication|api:grails.core.GrailsApplication] that's available automatically in controllers and GSPs and can be [injected|guide:dependencyInjectionServices] everywhere else. The @grailsApplication@ object has several important properties and methods for querying artefacts. Probably the most common is the one that gives you all the classes of a particular artefact type: @@ -34,7 +34,7 @@ for (cls in grailsApplication.urlMappingsClasses) { } {code} -You need to be aware that the objects returned by these properties are not instances of [Class|api:java.lang.Class]. Instead, they are instances of [GrailsClass|api:org.codehaus.groovy.grails.commons.GrailsClass] that has some particularly useful properties and methods, including one for the underlying @Class@: +You need to be aware that the objects returned by these properties are not instances of [Class|api:java.lang.Class]. Instead, they are instances of [GrailsClass|api:grails.core.GrailsClass] that has some particularly useful properties and methods, including one for the underlying @Class@: * @shortName@ - the class name of the artefact without the package (equivalent of @Class.simpleName@). * @logicalPropertyName@ - the artefact name in property form without the 'type' suffix. So @MyGreatController@ becomes 'myGreat'. diff --git a/src/en/guide/plugins/understandingPluginLoadOrder.gdoc b/src/en/guide/plugins/understandingPluginLoadOrder.gdoc index 2850adbf1e0..546f80f7c82 100644 --- a/src/en/guide/plugins/understandingPluginLoadOrder.gdoc +++ b/src/en/guide/plugins/understandingPluginLoadOrder.gdoc @@ -54,7 +54,7 @@ if (manager?.hasGrailsPlugin("controllers")) { } {code} -Here the Hibernate plugin will only register an @OpenSessionInViewInterceptor@ if the @controllers@ plugin has been loaded. The @manager@ variable is an instance of the [GrailsPluginManager|api:org.codehaus.groovy.grails.plugins.GrailsPluginManager] interface and it provides methods to interact with other plugins. +Here the Hibernate plugin will only register an @OpenSessionInViewInterceptor@ if the @controllers@ plugin has been loaded. The @manager@ variable is an instance of the [GrailsPluginManager|api:grails.plugins.GrailsPluginManager] interface and it provides methods to interact with other plugins. You can also use the @loadBefore@ property to specify one or more plugins that your plugin should load before: diff --git a/src/en/guide/security/codecs.gdoc b/src/en/guide/security/codecs.gdoc index f066053edd9..1254090c6b8 100644 --- a/src/en/guide/security/codecs.gdoc +++ b/src/en/guide/security/codecs.gdoc @@ -18,10 +18,10 @@ Decoding is performed using @value.decodeHTML()@ syntax. h4. Encoder and Decoder interfaces for staticly compiled code -A preferred way to use codecs is to use the codecLookup bean to get hold of @Encoder@ and @Decoder@ instances . +A preferred way to use codecs is to use the codecLookup bean to get hold of @Encoder@ and @Decoder@ instances . {code:java} -package org.codehaus.groovy.grails.support.encoding; +package org.grails.encoder; public interface CodecLookup { public Encoder lookupEncoder(String codecName); @@ -31,10 +31,10 @@ public interface CodecLookup { example of using @CodecLookup@ and @Encoder@ interface {code:java} -import org.codehaus.groovy.grails.support.encoding.CodecLookup +import org.grails.encoder.CodecLookup class CustomTagLib { - CodecLookup codecLookup + CodecLookup codecLookup def myTag = { Map attrs, body -> out << codecLookup.lookupEncoder('HTML').encode(attrs.something) @@ -58,7 +58,7 @@ Example of usage: Note that the HTML encoding does not re-encode apostrophe/single quote so you must use double quotes on attribute values to avoid text with apostrophes affecting your page. {note} -HTMLCodec defaults to HTML4 style escaping (legacy HTMLCodec implementation in Grails versions before 2.3.0) which escapes non-ascii characters. +HTMLCodec defaults to HTML4 style escaping (legacy HTMLCodec implementation in Grails versions before 2.3.0) which escapes non-ascii characters. You can use plain XML escaping instead of HTML4 escaping by setting this config property in Config.groovy: {code} @@ -68,7 +68,7 @@ grails.views.gsp.htmlcodec = 'xml' *XMLCodec* -This codec performs XML escaping and unescaping. It escapes & , < , > , " , ' , \\\\ , @ , ` , non breaking space (\\\\u00a0), line separator (\\\\u2028) and paragraph separator (\\\\u2029). +This codec performs XML escaping and unescaping. It escapes & , < , > , " , ' , \\\\ , @ , ` , non breaking space (\\\\u00a0), line separator (\\\\u2028) and paragraph separator (\\\\u2029). *HTMLJSCodec* diff --git a/src/en/guide/spring/springdsl.gdoc b/src/en/guide/spring/springdsl.gdoc index d43d1d88a9d..4aa2ca6d6ce 100644 --- a/src/en/guide/spring/springdsl.gdoc +++ b/src/en/guide/spring/springdsl.gdoc @@ -10,7 +10,7 @@ Grails provides a [grails.spring.BeanBuilder|api:grails.spring.BeanBuilder] clas {code:java} import org.apache.commons.dbcp.BasicDataSource -import org.codehaus.groovy.grails.orm.hibernate.ConfigurableLocalSessionFactoryBean +import org.grails.orm.hibernate.ConfigurableLocalSessionFactoryBean import org.springframework.context.ApplicationContext import grails.spring.BeanBuilder @@ -78,7 +78,7 @@ Include the @grails-spring-.jar@ file in your classpath to use BeanBuil contextClass - org.codehaus.groovy.grails.commons.spring.GrailsWebApplicationContext + grails.web.servlet.context.GrailsWebApplicationContext {code} @@ -113,7 +113,7 @@ Here the @BeanBuilder@ loads all Groovy files on the classpath ending with @Spri {code:java} import org.apache.commons.dbcp.BasicDataSource -import org.codehaus.groovy.grails.orm.hibernate.ConfigurableLocalSessionFactoryBean +import org.grails.orm.hibernate.ConfigurableLocalSessionFactoryBean beans { diff --git a/src/en/guide/spring/theUnderpinningsOfGrails.gdoc b/src/en/guide/spring/theUnderpinningsOfGrails.gdoc index b9816ed4902..99878731e8a 100644 --- a/src/en/guide/spring/theUnderpinningsOfGrails.gdoc +++ b/src/en/guide/spring/theUnderpinningsOfGrails.gdoc @@ -13,7 +13,7 @@ h4. The Grails ApplicationContext Spring developers are often keen to understand how the Grails @ApplicationContext@ instance is constructed. The basics of it are as follows. -* Grails constructs a parent @ApplicationContext@ from the @web-app/WEB-INF/applicationContext.xml@ file. This @ApplicationContext@ configures the [GrailsApplication|api:org.codehaus.groovy.grails.commons.GrailsApplication] instance and the [GrailsPluginManager|api:org.codehaus.groovy.grails.plugins.GrailsPluginManager]. +* Grails constructs a parent @ApplicationContext@ from the @web-app/WEB-INF/applicationContext.xml@ file. This @ApplicationContext@ configures the [GrailsApplication|api:grails.core.GrailsApplication] instance and the [GrailsPluginManager|api:grails.plugins.GrailsPluginManager]. * Using this @ApplicationContext@ as a parent Grails' analyses the conventions with the @GrailsApplication@ instance and constructs a child @ApplicationContext@ that is used as the root @ApplicationContext@ of the web application h4. Configured Spring Beans diff --git a/src/en/guide/testing/unitTesting.gdoc b/src/en/guide/testing/unitTesting.gdoc index 4e54d8e594d..ee9e671e2a1 100644 --- a/src/en/guide/testing/unitTesting.gdoc +++ b/src/en/guide/testing/unitTesting.gdoc @@ -125,13 +125,13 @@ class TestInstanceCallbacksSpec extends Specification { -You can use @[org.codehaus.groovy.grails.commons.InstanceFactoryBean|api:org.codehaus.groovy.grails.commons.InstanceFactoryBean]@ together with doWithSpring and the [FreshRuntime|api:grails.test.runtime.FreshRuntime] annotation to mock beans in tests. +You can use @[org.grails.spring.beans.factory.InstanceFactoryBean|api:org.grails.spring.beans.factory.InstanceFactoryBean]@ together with doWithSpring and the [FreshRuntime|api:grails.test.runtime.FreshRuntime] annotation to mock beans in tests. {code} import grails.test.mixin.support.GrailsUnitTestMixin import grails.test.runtime.FreshRuntime -import org.codehaus.groovy.grails.commons.InstanceFactoryBean +import org.grails.spring.beans.factory.InstanceFactoryBean import org.junit.ClassRule import spock.lang.Shared @@ -213,7 +213,3 @@ class LoadExternalBeansSpec extends Specification { } } {code} - - - - diff --git a/src/en/guide/testing/unitTesting/unitTestingTagLibraries.gdoc b/src/en/guide/testing/unitTesting/unitTestingTagLibraries.gdoc index 5a2fae97fc8..5f75633ae19 100644 --- a/src/en/guide/testing/unitTesting/unitTestingTagLibraries.gdoc +++ b/src/en/guide/testing/unitTesting/unitTestingTagLibraries.gdoc @@ -17,7 +17,7 @@ class SimpleTagLibSpec extends Specification { {code} Adding the @TestFor@ annotation to a TagLib class causes a new @tagLib@ field to be automatically created for the TagLib class under test. -The tagLib field can be used to test calling tags as function calls. The return value of a function call is either a [StreamCharBuffer|api:org.codehaus.groovy.grails.web.util.StreamCharBuffer] instance or +The tagLib field can be used to test calling tags as function calls. The return value of a function call is either a [StreamCharBuffer|api:org.grails.buffer.StreamCharBuffer] instance or the object returned from the tag closure when [returnObjectForTags|guide:tagReturnValue] feature is used. Note that if you are testing invocation of a custom tag from a controller you can combine the @ControllerUnitTestMixin@ and the @GroovyPageUnitTestMixin@ using the @Mock@ annotation: diff --git a/src/en/guide/theWebLayer/gsp/GSPBasics/variablesAndScopes.gdoc b/src/en/guide/theWebLayer/gsp/GSPBasics/variablesAndScopes.gdoc index 89daf82b493..12e8529657e 100644 --- a/src/en/guide/theWebLayer/gsp/GSPBasics/variablesAndScopes.gdoc +++ b/src/en/guide/theWebLayer/gsp/GSPBasics/variablesAndScopes.gdoc @@ -15,10 +15,10 @@ Within the scope of a GSP there are a number of pre-defined variables, including * @application@ - The [javax.servlet.ServletContext|api:javax.servlet.ServletContext] instance * @applicationContext@ The Spring [ApplicationContext|api:org.springframework.context.ApplicationContext] instance * @flash@ - The [flash|controllers] object -* @grailsApplication@ - The [GrailsApplication|api:org.codehaus.groovy.grails.commons.GrailsApplication] instance +* @grailsApplication@ - The [GrailsApplication|api:grails.core.GrailsApplication] instance * @out@ - The response writer for writing to the output stream * @params@ - The [params|controllers] object for retrieving request parameters * @request@ - The [HttpServletRequest|api:javax.servlet.http.HttpServletRequest] instance * @response@ - The [HttpServletResponse|api:javax.servlet.http.HttpServletResponse] instance * @session@ - The [HttpSession|api:javax.servlet.http.HttpSession] instance -* @webRequest@ - The [GrailsWebRequest|api:org.codehaus.groovy.grails.web.servlet.mvc.GrailsWebRequest] instance +* @webRequest@ - The [GrailsWebRequest|api:org.grails.web.servlet.mvc.GrailsWebRequest] instance diff --git a/src/en/guide/theWebLayer/taglibs/taglibVariablesAndScopes.gdoc b/src/en/guide/theWebLayer/taglibs/taglibVariablesAndScopes.gdoc index bc32d8ff7a9..8343d9ee166 100644 --- a/src/en/guide/theWebLayer/taglibs/taglibVariablesAndScopes.gdoc +++ b/src/en/guide/theWebLayer/taglibs/taglibVariablesAndScopes.gdoc @@ -3,7 +3,7 @@ Within the scope of a tag library there are a number of pre-defined variables in * @actionName@ - The currently executing action name * @controllerName@ - The currently executing controller name * @flash@ - The [flash|controllers] object -* @grailsApplication@ - The [GrailsApplication|api:org.codehaus.groovy.grails.commons.GrailsApplication] instance +* @grailsApplication@ - The [GrailsApplication|api:grails.core.GrailsApplication] instance * @out@ - The response writer for writing to the output stream * @pageScope@ - A reference to the [pageScope|tagLibraries] object used for GSP rendering (i.e. the binding) * @params@ - The [params|controllers] object for retrieving request parameters @@ -11,4 +11,4 @@ Within the scope of a tag library there are a number of pre-defined variables in * @request@ - The [HttpServletRequest|api:javax.servlet.http.HttpServletRequest] instance * @response@ - The [HttpServletResponse|api:javax.servlet.http.HttpServletResponse] instance * @servletContext@ - The [javax.servlet.ServletContext|api:javax.servlet.ServletContext] instance -* @session@ - The [HttpSession|api:javax.servlet.http.HttpSession] instance \ No newline at end of file +* @session@ - The [HttpSession|api:javax.servlet.http.HttpSession] instance diff --git a/src/en/guide/webServices/REST/binding.gdoc b/src/en/guide/webServices/REST/binding.gdoc index aa7e74cae58..e383260aaad 100644 --- a/src/en/guide/webServices/REST/binding.gdoc +++ b/src/en/guide/webServices/REST/binding.gdoc @@ -76,7 +76,7 @@ class BookController { } {code} -The data binding depends on an instance of the [DataBindingSource|api:org.grails.databinding.DataBindingSource] interface created by an instance of the [DataBindingSourceCreator|api:org.grails.databinding.bindingsource.DataBindingSourceCreator] interface. The specific implementation of @DataBindingSourceCreator@ will be selected based on the @contentType@ of the request. Several implementations are provided to handle common content types. The default implementations will be fine for most use cases. The following table lists the content types which are supported by the core framework and which @DataBindingSourceCreator@ implementations are used for each. All of the implementation classes are in the @org.codehaus.groovy.grails.web.binding.bindingsource@ package. +The data binding depends on an instance of the [DataBindingSource|api:org.grails.databinding.DataBindingSource] interface created by an instance of the [DataBindingSourceCreator|api:org.grails.databinding.bindingsource.DataBindingSourceCreator] interface. The specific implementation of @DataBindingSourceCreator@ will be selected based on the @contentType@ of the request. Several implementations are provided to handle common content types. The default implementations will be fine for most use cases. The following table lists the content types which are supported by the core framework and which @DataBindingSourceCreator@ implementations are used for each. All of the implementation classes are in the @org.grails.databinding.bindingsource@ package. {table} Content Type(s) | Bean Name | DataBindingSourceCreator Impl. @@ -97,27 +97,27 @@ The @DataBindingSourceCreator@ interface defines just 2 methods: {code:java} package org.grails.databinding.bindingsource -import org.codehaus.groovy.grails.web.mime.MimeType -import org.grails.databinding.DataBindingSource +import grails.web.mime.MimeType +import grails.databinding.DataBindingSource /** * A factory for DataBindingSource instances - * + * * @since 2.3 * @see DataBindingSourceRegistry * @see DataBindingSource * */ interface DataBindingSourceCreator { - + /** * @return All of the {@link MimeType} supported by this helper */ MimeType[] getMimeTypes() - + /** * Creates a DataBindingSource suitable for binding bindingSource to bindingTarget - * + * * @param mimeType a mime type * @param bindingTarget the target of the data binding * @param bindingSource the value being bound @@ -142,8 +142,8 @@ The code below shows a simple implementation. // src/groovy/com/demo/myapp/databinding package com.demo.myapp.databinding -import org.codehaus.groovy.grails.web.mime.MimeType -import org.grails.databinding.DataBindingSource +import grails.web.mime.MimeType +import grails.databinding.DataBindingSource import org...databinding.SimpleMapDataBindingSource import org...databinding.bindingsource.AbstractRequestBodyDataBindingSourceCreator @@ -164,9 +164,9 @@ class MyCustomDataBindingSourceCreator extends AbstractRequestBodyDataBindingSou @Override protected DataBindingSource createBindingSource(InputStream inputStream) { def map = [:] - + def reader = new InputStreamReader(inputStream) - + // this is an obviously naive parser and is intended // for demonstration purposes only. @@ -181,7 +181,7 @@ class MyCustomDataBindingSourceCreator extends AbstractRequestBodyDataBindingSou } } } - + // create and return a DataBindingSource which contains the parsed data new SimpleMapDataBindingSource(map) } diff --git a/src/en/guide/webServices/REST/hypermedia/hal.gdoc b/src/en/guide/webServices/REST/hypermedia/hal.gdoc index ccd9bc97d0a..5c4b07ce7c9 100644 --- a/src/en/guide/webServices/REST/hypermedia/hal.gdoc +++ b/src/en/guide/webServices/REST/hypermedia/hal.gdoc @@ -43,7 +43,7 @@ } {code} -h4. Exposing Resources Using HAL +h4. Exposing Resources Using HAL To return HAL instead of regular JSON for a resource you can simply override the renderer in @grails-app/conf/spring/resources.groovy@ with an instance of @grails.rest.render.hal.HalJsonRenderer@ (or @HalXmlRenderer@ for the XML variation): @@ -237,7 +237,7 @@ Then override the renderer to return HAL using the custom Mime Types: {code} import grails.rest.render.hal.* -import org.codehaus.groovy.grails.web.mime.* +import grails.web.mime.* beans = { halBookRenderer(HalJsonRenderer, rest.test.Book, new MimeType("application/vnd.books.org.book+json", [v:"1.0"])) @@ -283,7 +283,7 @@ def show(Book book) { } {code} -Which will result in output such as: +Which will result in output such as: {code} diff --git a/src/en/guide/webServices/REST/renderers/customRenderers.gdoc b/src/en/guide/webServices/REST/renderers/customRenderers.gdoc index 6e9a0bde699..6d00d222267 100644 --- a/src/en/guide/webServices/REST/renderers/customRenderers.gdoc +++ b/src/en/guide/webServices/REST/renderers/customRenderers.gdoc @@ -3,7 +3,7 @@ If you want even more control of the rendering or prefer to use your own marshal {code} package myapp import grails.rest.render.* -import org.codehaus.groovy.grails.web.mime.MimeType +import grails.web.mime.MimeType class BookXmlRenderer extends AbstractRenderer { BookXmlRenderer() { @@ -53,5 +53,3 @@ class BookListRenderer implements ContainerRenderer { } } {code} - - diff --git a/src/en/guide/webServices/REST/renderers/objectMarshallerInterface.gdoc b/src/en/guide/webServices/REST/renderers/objectMarshallerInterface.gdoc index d0feea14b75..144d09883a0 100644 --- a/src/en/guide/webServices/REST/renderers/objectMarshallerInterface.gdoc +++ b/src/en/guide/webServices/REST/renderers/objectMarshallerInterface.gdoc @@ -1,4 +1,4 @@ -For more complex marshallers it is recommended you implement the [ObjectMarshaller|api:org.codehaus.groovy.grails.web.converters.marshaller.ObjectMarshaller] interface. For example given a domain class: +For more complex marshallers it is recommended you implement the [ObjectMarshaller|api:org.grails.web.converters.marshaller.ObjectMarshaller] interface. For example given a domain class: {code} class Book { @@ -24,13 +24,13 @@ To write a custom marshaller you can do the following: {code} class BookMarshaller implements ObjectMarshaller { - + public boolean supports(Object object) { return object instanceof Book } - + public void marshalObject(Object object, XML converter) { - Book book = (Book)object + Book book = (Book)object converter.chars book.title } } @@ -50,11 +50,11 @@ With the custom @ObjectMarshaller@ in place, the output is now: h4. Customizing the Name of the Root Element -If you wish the customize the name of the surrounding element, you can implement [NameAwareMarshaller|api:org.codehaus.groovy.grails.web.converters.marshaller.NameAwareMarshaller]: +If you wish the customize the name of the surrounding element, you can implement [NameAwareMarshaller|api:org.grails.web.converters.marshaller.NameAwareMarshaller]: {code} class BookMarshaller implements ObjectMarshaller,NameAwareMarshaller { - + ... String getElementName(Object o) { @@ -77,14 +77,14 @@ With the passed Converter object you can explicitly code to the Converters API t {code} public void marshalObject(Object object, XML converter) { Book book = (Book)object - + converter.attribute 'id', book.id.toString() converter.attribute 'date-released', book.dateReleased.toString() - + converter.startNode 'title' converter.chars book.title converter.end() - + } {code} @@ -101,12 +101,12 @@ You can also use a builder notation to achieve a similar result (although the bu {code} public void marshalObject(Object object, XML converter) { Book b = (Book)object - + converter.build { book(id: b.id) { title b.title } - } + } } {code} @@ -116,17 +116,17 @@ To create more complex responses you can use the @convertAnother@ method to conv {code} public void marshalObject(Object object, XML converter) { - Book book = (Book)object - + Book book = (Book)object + converter.startNode 'title' converter.chars book.title converter.end() - + if (book.authors) { converter.startNode 'authors' for(author in book.authors) { converter.convertAnother author - } + } converter.end() } } diff --git a/src/en/guide/webServices/REST/renderers/objectMarshallers.gdoc b/src/en/guide/webServices/REST/renderers/objectMarshallers.gdoc index 647fb23b058..10dcc6c9d24 100644 --- a/src/en/guide/webServices/REST/renderers/objectMarshallers.gdoc +++ b/src/en/guide/webServices/REST/renderers/objectMarshallers.gdoc @@ -1,4 +1,4 @@ -Grails' Converters feature the notion of an [ObjectMarshaller|api:org.codehaus.groovy.grails.web.converters.marshaller.ObjectMarshaller] and each type can have a registered @ObjectMarshaller@. You can register custom @ObjectMarshaller@ instances to completely customize response rendering. For example, you can define the following in @BootStrap.init@: +Grails' Converters feature the notion of an [ObjectMarshaller|api:org.grails.web.converters.marshaller.ObjectMarshaller] and each type can have a registered @ObjectMarshaller@. You can register custom @ObjectMarshaller@ instances to completely customize response rendering. For example, you can define the following in @BootStrap.init@: {code} XML.registerObjectMarshaller Book, { Book book, XML xml -> @@ -24,7 +24,7 @@ JSON.registerObjectMarshaller(Book) { def map= [:] map['titl'] = it.title map['auth'] = it.author - return map + return map } {code} @@ -39,7 +39,7 @@ class CustomMarshallerRegistrar { void registerMarshallers() { JSON.registerObjectMarshaller(DateTime) { return it?.toString("yyyy-MM-dd'T'HH:mm:ss'Z'") - } + } } } {code} diff --git a/src/en/guide/webServices/REST/versioningResources.gdoc b/src/en/guide/webServices/REST/versioningResources.gdoc index 43c59740c93..6dbbbc7bf9f 100644 --- a/src/en/guide/webServices/REST/versioningResources.gdoc +++ b/src/en/guide/webServices/REST/versioningResources.gdoc @@ -64,11 +64,11 @@ Then override the renderer (see the section on "Customizing Response Rendering" {code} import grails.rest.render.json.* -import org.codehaus.groovy.grails.web.mime.* +import grails.web.mime.* beans = { - bookRendererV1(JsonRenderer, myapp.v1.Book, new MimeType("application/vnd.books.org.book+json", [v:"1.0"])) - bookRendererV2(JsonRenderer, myapp.v2.Book, new MimeType("application/vnd.books.org.book+json", [v:"2.0"])) + bookRendererV1(JsonRenderer, myapp.v1.Book, new MimeType("application/vnd.books.org.book+json", [v:"1.0"])) + bookRendererV2(JsonRenderer, myapp.v2.Book, new MimeType("application/vnd.books.org.book+json", [v:"2.0"])) } {code} @@ -77,6 +77,3 @@ Then using the @Accept@ header you can specify which version you need using the {code} $ curl -i -H "Accept: application/vnd.books.org.book+json;v=1.0" -X GET http://localhost:8080/myapp/books {code} - - - diff --git a/src/en/ref/Controllers/grailsApplication.gdoc b/src/en/ref/Controllers/grailsApplication.gdoc index c55a9962daf..9616f8ec905 100644 --- a/src/en/ref/Controllers/grailsApplication.gdoc +++ b/src/en/ref/Controllers/grailsApplication.gdoc @@ -2,7 +2,7 @@ h1. grailsApplication h2. Purpose -An instance of the [GrailsApplication|api:org.codehaus.groovy.grails.commons.GrailsApplication] class. +An instance of the [GrailsApplication|api:grails.core.GrailsApplication] class. h2. Examples @@ -17,4 +17,4 @@ class BookController { h2. Description -The @GrailsApplication@ class provides information about the conventions within Grails and access to [metadata|api:org.codehaus.groovy.grails.commons.GrailsApplication#getMetadata()], [config|api:org.codehaus.groovy.grails.commons.GrailsApplication#getConfig()] and the [ClassLoader|api:org.codehaus.groovy.grails.commons.GrailsApplication#getClassLoader()] +The @GrailsApplication@ class provides information about the conventions within Grails and access to [metadata|api:grails.core.GrailsApplication#getMetadata()], [config|api:grails.core.GrailsApplication#getConfig()] and the [ClassLoader|api:grails.core.GrailsApplication#getClassLoader()] diff --git a/src/en/ref/Domain Classes/constraints.gdoc b/src/en/ref/Domain Classes/constraints.gdoc index 1b7e92dbc3c..64a3c933e0e 100644 --- a/src/en/ref/Domain Classes/constraints.gdoc +++ b/src/en/ref/Domain Classes/constraints.gdoc @@ -28,7 +28,7 @@ def b = new Book() assert !b.validate() {code} -At runtime the static @constraints@ property is a Map such that the keys in the Map are property names and the values associated with the keys are instances of [ConstrainedProperty|api:org.codehaus.groovy.grails.validation.ConstrainedProperty]: +At runtime the static @constraints@ property is a Map such that the keys in the Map are property names and the values associated with the keys are instances of [ConstrainedProperty|api:grails.validation.ConstrainedProperty]: {code:java} def constraintsMap = Book.constraints diff --git a/src/en/ref/Plug-ins/URL mappings.gdoc b/src/en/ref/Plug-ins/URL mappings.gdoc index d19cff02f78..f1fec48d328 100644 --- a/src/en/ref/Plug-ins/URL mappings.gdoc +++ b/src/en/ref/Plug-ins/URL mappings.gdoc @@ -30,6 +30,6 @@ Refer to the section on [URL Mapping|guide:urlmappings] in the Grails user guide Configured Spring Beans: -* @grailsUrlMappingsHolderBean@ - A [UrlMappingsHolderFactoryBean|api:org.codehaus.groovy.grails.web.mapping.UrlMappingsHolderFactoryBean] factory bean that constructs a [org.codehaus.groovy.grails.web.mapping.UrlMappingsHolder|api:org.codehaus.groovy.grails.web.mapping.UrlMappingsHolder] instance that stores all of the URL mappings. +* @grailsUrlMappingsHolderBean@ - A [UrlMappingsHolderFactoryBean|api:org.grails.web.mappings.UrlMappingsHolderFactoryBean] factory bean that constructs a [grails.web.mapping.UrlMappingsHolder|api:grails.web.mapping.UrlMappingsHolder] instance that stores all of the URL mappings. * @urlMappingsTargetSource@ - A Spring [HotSwappableTargetSource|api:org.springframework.aop.target.HotSwappableTargetSource] used in auto-reloading to automatically update URL mappings when changed. * @grailsUrlMappingsHolder@ - A Spring [ProxyFactoryBean|api:org.springframework.aop.framework.ProxyFactoryBean] that proxies onto the actual @UrlMappingsHolder@ instance using the @HotSwappableTargetSource@ diff --git a/src/en/ref/Plug-ins/controllers.gdoc b/src/en/ref/Plug-ins/controllers.gdoc index 8bb16b09520..2cfb21e4621 100644 --- a/src/en/ref/Plug-ins/controllers.gdoc +++ b/src/en/ref/Plug-ins/controllers.gdoc @@ -34,11 +34,10 @@ This plugin configures Grails to use Spring MVC at its core to deal with web req Configured Spring Beans: -* @exceptionHandler@ - An instance of [GrailsExceptionResolver|api:org.codehaus.groovy.grails.web.errors.GrailsExceptionResolver] for dealing with exceptions +* @exceptionHandler@ - An instance of [GrailsExceptionResolver|api:org.grails.web.errors.GrailsExceptionResolver] for dealing with exceptions * @multipartResolver@ - An instance of [CommonsMultipartResolver|api:org.springframework.web.multipart.commons.CommonsMultipartResolver] used for dealing with file uploads using Apache Commons File Upload. If you do not wish to use this, set grails.disableCommonsMultipart to true in Config.groovy. Be aware that disabling multipart handling will effect the behaviour of g:actionSubmit which needs to inspect the parameters (requiring the multipart request to be parsed) during the URL mapping phase. -* @simpleGrailsController@ - An instance of [SimpleGrailsController|api:org.codehaus.groovy.grails.web.servlet.mvc.SimpleGrailsController], which is an instance of the Spring MVC Controller interface and deals with delegating onto actual Grails controller classes * @groovyPageResourceLoader@ - Configured in @development@ mode only or when the @grails.gsp.view.dir@ is set. This is a Spring ResourceLoader that knows how to load GSP views from the an arbitrary location -* @groovyPagesTemplateEngine@ - An instance of [GroovyPagesTemplateEngine|api:org.codehaus.groovy.grails.web.pages.GroovyPagesTemplateEngine], this class deals with rendering of GSP views -* @jspViewResolver@ - An instance of [GrailsViewResolver|api:org.codehaus.groovy.grails.web.servlet.view.GrailsViewResolver] that knows how to resolve GSP views and is environment aware +* @groovyPagesTemplateEngine@ - An instance of [GroovyPagesTemplateEngine|api:org.grails.gsp.GroovyPagesTemplateEngine], this class deals with rendering of GSP views +* @jspViewResolver@ - An instance of [GrailsViewResolver|api:org.grails.web.servlet.view.GrailsViewResolver] that knows how to resolve GSP views and is environment aware The plugin also configures each Grails controller class as a prototyped Spring bean and each Grails tag library as a singleton Spring bean diff --git a/src/en/ref/Plug-ins/domainClasses.gdoc b/src/en/ref/Plug-ins/domainClasses.gdoc index 211d5df3131..1e9c9367313 100644 --- a/src/en/ref/Plug-ins/domainClasses.gdoc +++ b/src/en/ref/Plug-ins/domainClasses.gdoc @@ -22,7 +22,7 @@ Refer to the section on [GORM|guide:GORM] in the Grails user guide which details Configured Spring Beans given a domain class of @Book@: -* @BookValidator@ - A [GrailsDomainClassValidator|api:org.codehaus.groovy.grails.validation.GrailsDomainClassValidator] that validates a domain class' defined [constraints|guide:constraints]. +* @BookValidator@ - A [GrailsDomainClassValidator|api:org.grails.validation.GrailsDomainClassValidator] that validates a domain class' defined [constraints|guide:constraints]. * @BookPersistentClass@ - The @Class@ for the domain class @Book@ -* @BookDomainClass@ - The [GrailsDomainClass|api:org.codehaus.groovy.grails.commons.GrailsDomainClass] instance which understands the conventions defined within a domain class and is used by [GORM|guide:GORM] to perform ORM mapping. +* @BookDomainClass@ - The [GrailsDomainClass|api:grails.core.GrailsDomainClass] instance which understands the conventions defined within a domain class and is used by [GORM|guide:GORM] to perform ORM mapping. * @Book@ - A prototyped bean that will create a new instance of @Book@ every time requested. This bean is used to perform auto-wiring of domain classes when constructed with the @new@ operator. diff --git a/src/en/ref/Plug-ins/filters.gdoc b/src/en/ref/Plug-ins/filters.gdoc index 95027c45e60..d4a606ad16f 100644 --- a/src/en/ref/Plug-ins/filters.gdoc +++ b/src/en/ref/Plug-ins/filters.gdoc @@ -36,7 +36,7 @@ Refer to the section on [Filters|guide:filters] in the Grails user guide which d Configured Spring Beans: -* @filterInterceptor@ - An instance of [CompositeInterceptor|api:org.codehaus.groovy.grails.plugins.web.filters.CompositeInterceptor] that composes all the filters together into a single Spring @Interceptor@. +* @filterInterceptor@ - An instance of [CompositeInterceptor|api:org.grails.plugins.web.filters.CompositeInterceptor] that composes all the filters together into a single Spring @Interceptor@. Configured Spring Beans given a filter called @SecurityFilters@: -* @SecurityFiltersClass@ - The [GrailsFiltersClass|api:org.codehaus.groovy.grails.web.filters.GrailsFiltersClass] instance which aids in analyzing the conventions within the filter. +* @SecurityFiltersClass@ - The [GrailsFiltersClass|api:org.grails.plugins.web.filters.GrailsFiltersClass] instance which aids in analyzing the conventions within the filter. * @SecurityFilters@ - A singleton reference to the filter itself to support auto-wiring into a Filter diff --git a/src/en/ref/Plug-ins/hibernate.gdoc b/src/en/ref/Plug-ins/hibernate.gdoc index b003e3d2acc..110d93a2aec 100644 --- a/src/en/ref/Plug-ins/hibernate.gdoc +++ b/src/en/ref/Plug-ins/hibernate.gdoc @@ -22,10 +22,10 @@ Refer to the section on [GORM|guide:GORM] in the Grails user guide which details Configured Spring Beans: -* @dialectDetector@ - An instance of [HibernateDialectDetectorFactoryBean|api:org.codehaus.groovy.grails.orm.hibernate.support.HibernateDialectDetectorFactoryBean] that attempts to automatically detect the Hibernate [Dialect|api:org.hibernate.dialect.Dialect] which is used to communicate with the database. +* @dialectDetector@ - An instance of [HibernateDialectDetectorFactoryBean|api:org.grails.orm.hibernate.support.HibernateDialectDetectorFactoryBean] that attempts to automatically detect the Hibernate [Dialect|api:org.hibernate.dialect.Dialect] which is used to communicate with the database. * @hibernateProperties@ - A @Map@ of Hibernate properties passed to the @SessionFactory@ -* @lobHandlerDetector@ - An instance of [SpringLobHandlerDetectorFactoryBean|api:org.codehaus.groovy.grails.orm.hibernate.support.SpringLobHandlerDetectorFactoryBean] that attempts to automatically detect the Spring LobHandler to use based on the database. +* @lobHandlerDetector@ - An instance of [SpringLobHandlerDetectorFactoryBean|api:org.grails.orm.hibernate.support.SpringLobHandlerDetectorFactoryBean] that attempts to automatically detect the Spring LobHandler to use based on the database. * @sessionFactory@ - An instance of the Hibernate [SessionFactory|api:org.hibernate.SessionFactory] class * @transactionManager@ - An instance of Spring's [HibernateTransactionManager|api:org.springframework.orm.hibernate3.HibernateTransactionManager] class -* @persistenceInterceptor@ - An instance of [HibernatePersistenceContextInterceptor|api:org.codehaus.groovy.grails.orm.hibernate.support.HibernatePersistenceContextInterceptor] that abstracts away how persistence is used from the controller/view layer so that Grails can be used without GORM. -* @openSessionInViewInterceptor@ - An instance of [GrailsOpenSessionInViewFilter|api:org.codehaus.groovy.grails.orm.hibernate.support.GrailsOpenSessionInViewFilter] that deals with Grails' [Session|api:org.hibernate.Session] management. +* @persistenceInterceptor@ - An instance of [HibernatePersistenceContextInterceptor|api:org.grails.orm.hibernate.support.HibernatePersistenceContextInterceptor] that abstracts away how persistence is used from the controller/view layer so that Grails can be used without GORM. +* @openSessionInViewInterceptor@ - An instance of [GrailsOpenSessionInViewFilter|api:org.grails.orm.hibernate.support.GrailsOpenSessionInViewFilter] that deals with Grails' [Session|api:org.hibernate.Session] management. From b1e4eedc506641d1aba51347b659d7d4e578f59f Mon Sep 17 00:00:00 2001 From: graemerocher Date: Wed, 25 Feb 2015 14:49:04 +0100 Subject: [PATCH 086/230] remove dead or deprecated features or features that will be moved to external plugins --- src/en/guide/security/authentication.gdoc | 30 ++++--- .../controllers/controllerInterceptors.gdoc | 2 +- .../theWebLayer/gsp/viewsAndTemplates.gdoc | 2 +- src/en/guide/theWebLayer/interceptors.gdoc | 2 +- src/en/ref/Command Line/list-plugins.gdoc | 32 +++---- src/en/ref/Plug-ins/filters.gdoc | 42 --------- src/en/ref/Tags/formRemote.gdoc | 89 ------------------ src/en/ref/Tags/remoteField.gdoc | 66 -------------- src/en/ref/Tags/remoteFunction.gdoc | 85 ------------------ src/en/ref/Tags/remoteLink.gdoc | 90 ------------------- src/en/ref/Tags/setProvider.gdoc | 23 ----- src/en/ref/Tags/submitToRemote.gdoc | 62 ------------- 12 files changed, 31 insertions(+), 494 deletions(-) delete mode 100644 src/en/ref/Plug-ins/filters.gdoc delete mode 100644 src/en/ref/Tags/formRemote.gdoc delete mode 100644 src/en/ref/Tags/remoteField.gdoc delete mode 100644 src/en/ref/Tags/remoteFunction.gdoc delete mode 100644 src/en/ref/Tags/remoteLink.gdoc delete mode 100644 src/en/ref/Tags/setProvider.gdoc delete mode 100644 src/en/ref/Tags/submitToRemote.gdoc diff --git a/src/en/guide/security/authentication.gdoc b/src/en/guide/security/authentication.gdoc index 190c0e2b7f2..71ee0f82b3d 100644 --- a/src/en/guide/security/authentication.gdoc +++ b/src/en/guide/security/authentication.gdoc @@ -1,29 +1,33 @@ -Grails has no default mechanism for authentication as it is possible to implement authentication in many different ways. It is however, easy to implement a simple authentication mechanism using either [interceptors|guide:interceptors] or [filters|guide:filters]. This is sufficient for simple use cases but it's highly preferable to use an established security framework, for example by using the [Spring Security|guide:springSecurity] or the [Shiro|guide:shiro] plugin. +Grails has no default mechanism for authentication as it is possible to implement authentication in many different ways. It is however, easy to implement a simple authentication mechanism using [interceptors|guide:interceptors]. This is sufficient for simple use cases but it's highly preferable to use an established security framework, for example by using the [Spring Security|guide:springSecurity] or the [Shiro|guide:shiro] plugin. -Filters let you apply authentication across all controllers or across a URI space. For example you can create a new set of filters in a class called @grails-app/conf/SecurityFilters.groovy@ by running: +Interceptors let you apply authentication across all controllers or across a URI space. For example you can create a new set of filters in a class called @grails-app/controllers/SecurityInterceptor.groovy@ by running: {code} -grails create-filters security +grails create-interceptor security {code} and implement your interception logic there: {code:java} -class SecurityFilters { - def filters = { - loginCheck(controller: '*', action: '*') { - before = { - if (!session.user && actionName != "login") { - redirect(controller: "user", action: "login") - return false - } - } +class SecurityInterceptor { + + SecurityInterceptor() { + matchAll() + except(controller:'user', action:'login') + } + + boolean before() { + if (!session.user && actionName != "login") { + redirect(controller: "user", action: "login") + return false } + return true } + } {code} -Here the @loginCheck@ filter intercepts execution _before_ all actions except @login@ are executed, and if there is no user in the session then redirect to the @login@ action. +Here the interceptor intercepts execution _before_ all actions except @login@ are executed, and if there is no user in the session then redirect to the @login@ action. The @login@ action itself is simple too: diff --git a/src/en/guide/theWebLayer/controllers/controllerInterceptors.gdoc b/src/en/guide/theWebLayer/controllers/controllerInterceptors.gdoc index f147da5d013..06ef752fa66 100644 --- a/src/en/guide/theWebLayer/controllers/controllerInterceptors.gdoc +++ b/src/en/guide/theWebLayer/controllers/controllerInterceptors.gdoc @@ -1,7 +1,7 @@ Often it is useful to intercept processing based on either request, session or application state. This can be achieved with action interceptors. There are currently two types of interceptors: before and after. {note} -If your interceptor is likely to apply to more than one controller, you are almost certainly better off writing a [Filter|guide:filters]. Filters can be applied to multiple controllers or URIs without the need to change the logic of each controller +If your interceptor is likely to apply to more than one controller, you are almost certainly better off writing a standalone [Interceptor|guide:interceptors]. Standaline Interceptors can be applied to multiple controllers or URIs without the need to change the logic of each controller {note} h4. Before Interception diff --git a/src/en/guide/theWebLayer/gsp/viewsAndTemplates.gdoc b/src/en/guide/theWebLayer/gsp/viewsAndTemplates.gdoc index 1500a186aac..01c84f3d437 100644 --- a/src/en/guide/theWebLayer/gsp/viewsAndTemplates.gdoc +++ b/src/en/guide/theWebLayer/gsp/viewsAndTemplates.gdoc @@ -55,7 +55,7 @@ This can be expressed with the @tmpl@ namespace as follows: h4. Templates in Controllers and Tag Libraries -You can also render templates from controllers using the [render|controllers] controller method. This is useful for [Ajax|guide:ajax] applications where you generate small HTML or data responses to partially update the current page instead of performing new request: +You can also render templates from controllers using the [render|controllers] controller method. This is useful for JavaScript heavy applications where you generate small HTML or data responses to partially update the current page instead of performing new request: {code:java} def bookData() { diff --git a/src/en/guide/theWebLayer/interceptors.gdoc b/src/en/guide/theWebLayer/interceptors.gdoc index 6c4a7545c83..3e53acc0732 100644 --- a/src/en/guide/theWebLayer/interceptors.gdoc +++ b/src/en/guide/theWebLayer/interceptors.gdoc @@ -1,6 +1,6 @@ Although Grails [controllers|guide:controllers] support fine grained interceptors, these are only really useful when applied to a few controllers and become difficult to manage with larger applications. -To solve this you can create standalone Interceptors using the [commandLine|create-interceptors] command: +To solve this you can create standalone Interceptors using the [create-interceptor|commandLine] command: {code} $ grails create-interceptor MyInterceptor diff --git a/src/en/ref/Command Line/list-plugins.gdoc b/src/en/ref/Command Line/list-plugins.gdoc index 9e6e5349783..bbfbb2c31b1 100644 --- a/src/en/ref/Command Line/list-plugins.gdoc +++ b/src/en/ref/Command Line/list-plugins.gdoc @@ -19,29 +19,19 @@ grails list-plugins -repository=myRepository grails list-plugins -installed {code} -Fired Events: - -* @StatusUpdate@ - When the plugin list is being refreshed -* @StatusError@ - When there was an error updating the plugin list - -Arguments: - -* @repository@ - The name of the repository to use, otherwise all known repositories will be scanned. See the section on [Plugin repositories|guide:repositories] in the user guide. -* @installed@ - List only the plugins that are installed into the current Grails application. - Lists the plugins that are installable. Note: This command can take a while to execute depending in your internet connectivity. Typical output looks like this: {code} -Plugins available in the grailsCentral repository are listed below: -------------------------------------------------------------- -acegi <0.5.3.2> -- Grails Spring Security 2.0 Plugin -activemq <0.3> -- Grails ActiveMQ Plugin -activiti <5.6> -- Grails Activiti Plugin -ajax-uploader <0.3> -- Ajax Uploader Plugin -ajaxflow <0.2.1> -- This plugin enables Ajaxified Webflows -akismet <0.2> -- Akismet Anti-Spam Plugin -alfresco <0.4> -- Plugin de integracion con Alfresco. -... +| Available Plugins +* asset-pipeline +* cache +* cache-ehcache +* fields +* geb +* hibernate +* mongodb +* quartz +* scaffolding {code} -The first column contains the plugin name, the second the version and the last the description. If you require more info about a plugin you can use the [plugin-info|commandLine] command. If you wish to install a plugin you can use the plugin name and/or version in combination with the [install-plugin|commandLine]. +The first column contains the plugin name, the second the version and the last the description. If you require more info about a plugin you can use the [plugin-info|commandLine] command. diff --git a/src/en/ref/Plug-ins/filters.gdoc b/src/en/ref/Plug-ins/filters.gdoc deleted file mode 100644 index d4a606ad16f..00000000000 --- a/src/en/ref/Plug-ins/filters.gdoc +++ /dev/null @@ -1,42 +0,0 @@ -h1. filters - -h2. Purpose - -The @filters@ plugin configures Grails' support for Filters. - -h2. Examples - -An example filter: - -{code:java} -class SecurityFilters { - def filters = { - loginCheck(controller: '*', action: '*') { - before = { - if (!session.user && !actionName.equals('login')) { - redirect(action: 'login') - return false - } - } - } - } -} -{code} - -Filter rule attributes: -* @controller@ - controller matching pattern, by default \* is replaced with .\* and a regex is compiled -* @action@ - action matching pattern, by default \* is replaced with .\* and a regex is compiled -* @regex@ (@true@/@false@) - use regex syntax (don't replace '\*' with '.\*') -* @find@ (@true@/@false@) - rule matches with partial match (see @java.util.regex.Matcher.find()@) -* @invert@ (@true@/@false@) - invert the rule (NOT rule) - -h2. Description - -Refer to the section on [Filters|guide:filters] in the Grails user guide which details how filters work. - -Configured Spring Beans: - -* @filterInterceptor@ - An instance of [CompositeInterceptor|api:org.grails.plugins.web.filters.CompositeInterceptor] that composes all the filters together into a single Spring @Interceptor@. -Configured Spring Beans given a filter called @SecurityFilters@: -* @SecurityFiltersClass@ - The [GrailsFiltersClass|api:org.grails.plugins.web.filters.GrailsFiltersClass] instance which aids in analyzing the conventions within the filter. -* @SecurityFilters@ - A singleton reference to the filter itself to support auto-wiring into a Filter diff --git a/src/en/ref/Tags/formRemote.gdoc b/src/en/ref/Tags/formRemote.gdoc deleted file mode 100644 index d50cd099793..00000000000 --- a/src/en/ref/Tags/formRemote.gdoc +++ /dev/null @@ -1,89 +0,0 @@ -h1. formRemote - -{note} -The formRemote tag and other Ajax related tags have been deprecated and will be removed from a future version of Grails. Applications may provide their own Ajax tags and/or Javascript plugins may provide Ajax tags of their own. -{note} - -h2. Purpose - -Creates a form tag that uses a remote uri to execute an Ajax call, serializing the form elements and falling back to a normal form submit if JavaScript is not supported. - -h2. Examples - -Example controller for an application called "shop": - -{code:java} -class BookController { - def show() { - [book: Book.get(params.id)] - } - - def byAuthor() { - [books: Book.findByAuthor(params.author, params)] - } -} -{code} - -Example usages for this controller: - -{code:xml} - - Book Id: - - -
this div is updated with the result of the show call
-{code} - -{code:xml} - - Author: - - -
this div is updated with the result of the byAuthor call
-{code} - -You can override both the form method and action to use when JavaScript is unavailable by providing @method@ and @action@ attributes. This example will submit the form to @//book/show@ using a GET if JavaScript is unavailable: - -{code:xml} - - Book Id: - - -
-{code} - -h2. Description - -This tag creates a form that fires an AJAX request when it is submitted. The exact Javascript used to fire off the AJAX request depends on which Javascript library is used. This tag also requires the use of either the or tags. See the [AJAX section|guide:ajax] of the user guide to find out more. - -Attributes - -* @name@ (required) - The name of the form. This attribute will be assigned to @id@ attribute if not present, otherwise, the value of this attribute will be omitted -* @url@ (required) - The url to submit to as either a Map (containing values for the controller, action, id, and params) or a URL string -* @id@ (optional) - The id of the form rendered to the output. If @id@ is not set, the value of @name@ will be assigned -* @action@ (optional) - The action to execute as a fallback, defaults to the url if not specified -* @update@ (optional) - Either a Map containing the elements to update for 'success' or 'failure' states, or a string with the element id to update, in which case failure events would be ignored -* @before@ (optional) - The JavaScript function to call before the remote function call. A semi-colon is automatically added so you don't have to provide one yourself in this string. -* @after@ (optional) - The JavaScript function to call after the remote function call. A semi-colon is automatically added so you don't have to provide one yourself in this string. -* @asynchronous@ (optional) - Whether to do the call asynchronously (defaults to @true@) -* @method@ (optional) - The method to use the execute the call (defaults to POST) - -Events - -* @onSuccess@ (optional) - The JavaScript function to call if successful -* @onFailure@ (optional) - The JavaScript function to call if the call fails -* @onERROR_CODE@ (optional) - The JavaScript function to call to handle the specified error code (e.g. @on404="alert('not found!')"@) -* @onUninitialized@ (optional) - The JavaScript function to call if Ajax fails to initialise -* @onLoading@ (optional) - The JavaScript function to call when the remote function loads the response -* @onLoaded@ (optional) - The JavaScript function to call when the remote function completes loading the response -* @onComplete@ (optional) - The JavaScript function to call when the remote function completes, including any updates - -h2. Source - -{source:tag=JavascriptTagLib.formRemote} -{source} diff --git a/src/en/ref/Tags/remoteField.gdoc b/src/en/ref/Tags/remoteField.gdoc deleted file mode 100644 index 9cedd3859ff..00000000000 --- a/src/en/ref/Tags/remoteField.gdoc +++ /dev/null @@ -1,66 +0,0 @@ -h1. remoteField - -{note} -The remoteField tag and other Ajax related tags have been deprecated and will be removed from a future version of Grails. Applications may provide their own Ajax tags and/or Javascript plugins may provide Ajax tags of their own. -{note} - -h2. Purpose - -Creates a text field that sends its value to a remote link when it changes. By default the parameter name sent is called 'value', this can be changed by specifying a 'paramName' attribute. - -h2. Examples - -Example controller for an application called "shop": - -{code:java} -class BookController { - - def changeTitle() { - def b = Book.get(params.id) - b.title = params.value - b.save() - } -} -{code} - -Example usages for this controller: - -{code:xml} - - -
I'm updated with the new title!
-{code} - -h2. Description - -This tag creates an input field that fires an AJAX request when its value changes (typically when the user presses return inside the field). The exact Javascript used to fire off the AJAX request depends on which Javascript library is used. This tag also requires the use of either the or tags. See the [AJAX section|guide:ajax] of the user guide to find out more. - -Attributes - -* @name@ (required) - the name of the field -* @value@ (optional) - The initial value of the field -* @paramName@ (optional) - The name of the parameter to send to the server -* @action@ (optional) - the name of the action to use in the link; if not specified the default action will be linked -* @controller@ (optional) - the name of the controller to use in the link; if not specified the current controller will be linked -* @id@ (optional) - The id to use in the link -* @update@ (optional) - Either a Map containing the elements to update for 'success' or 'failure' states, or a string with the element id to update, in which case failure events would be ignored -* @before@ (optional) - The JavaScript function to call before the remote function call. A semi-colon is automatically added so you don't have to provide one yourself in this string. -* @after@ (optional) - The JavaScript function to call after the remote function call. A semi-colon is automatically added so you don't have to provide one yourself in this string. -* @asynchronous@ (optional) - Whether to do the call asynchronously (defaults to @true@) -* @method@ (optional) - The method to use the execute the call (defaults to POST) - -Events - -* @onSuccess@ (optional) - The JavaScript function to call if successful -* @onFailure@ (optional) - The JavaScript function to call if the call fails -* @onERROR_CODE@ (optional) - The JavaScript function to call to handle the specified error code (e.g. @on404="alert('not found!')"@) -* @onUninitialized@ (optional) - The JavaScript function to call if Ajax fails to initialise -* @onLoading@ (optional) - The JavaScript function to call when the remote function loads the response -* @onLoaded@ (optional) - The JavaScript function to call when the remote function completes loading the response -* @onComplete@ (optional) - The JavaScript function to call when the remote function completes, including any updates - -h2. Source - -{source:tag=JavascriptTagLib.remoteField} -{source} diff --git a/src/en/ref/Tags/remoteFunction.gdoc b/src/en/ref/Tags/remoteFunction.gdoc deleted file mode 100644 index 47a0a74e55e..00000000000 --- a/src/en/ref/Tags/remoteFunction.gdoc +++ /dev/null @@ -1,85 +0,0 @@ -h1. remoteFunction - -{note} -The formFunction tag and other Ajax related tags have been deprecated and will be removed from a future version of Grails. Applications may provide their own Ajax tags and/or Javascript plugins may provide Ajax tags of their own. -{note} - -h2. Purpose - -Creates a remote JavaScript function that can be assigned to a DOM event to call the remote method - -h2. Examples - -Example controller for an application called @shop@: - -{code:java} -class BookController { - - def list() { - [books: Book.list(params)] - } - - def show() { - [book: Book.get(params.id)] - } - - def bookByName() { - [book: Book.findByName(params.bookName)] - } -} -{code} - -Example usages for above controller: - -{code:xml} -$('mydiv').onclick = -{code} - -Example as a method call in GSP only: - -{code:xml} - -{code} - -Example changing the asynchronous option to false: - -{code:xml} - - - - -
this div will be updated with the form submit response
-{code} - -h2. Description - -This tag creates a submit button that fires an AJAX request when it is pressed. The exact Javascript used to fire off the AJAX request depends on which Javascript library is used. This tag also requires the use of either the or tags. See the [AJAX section|guide:ajax] of the user guide to find out more. - -Attributes - -* @url@ - The url to submit to, either a map containing keys for the action, controller and id or a string value -* @value@ (optional) - The title of the button -* @update@ (optional) - Either a Map containing the elements to update for 'success' or 'failure' states, or a string with the element id to update, in which case failure events would be ignored -* @before@ (optional) - The JavaScript function to call before the remote function call. A semi-colon is automatically added so you don't have to provide one yourself in this string. -* @after@ (optional) - The JavaScript function to call after the remote function call. A semi-colon is automatically added so you don't have to provide one yourself in this string. -* @asynchronous@ (optional) - Whether to do the call asynchronously (defaults to @true@) -* @method@ (optional) - The method to use the execute the call (defaults to POST) - -Events - -* @onSuccess@ (optional) - The JavaScript function to call if successful -* @onFailure@ (optional) - The JavaScript function to call if the call fails -* @onERROR_CODE@ (optional) - The JavaScript function to call to handle the specified error code (e.g. @on404="alert('not found!')"@) -* @onUninitialized@ (optional) - The JavaScript function to call if Ajax fails to initialise -* @onLoading@ (optional) - The JavaScript function to call when the remote function loads the response -* @onLoaded@ (optional) - The JavaScript function to call when the remote function completes loading the response -* @onComplete@ (optional) - The JavaScript function to call when the remote function completes, including any updates - -h2. Source - -{source:tag=JavascriptTagLib.submitToRemote} -{source} From e13f18dcdc05a20a410734470384ec28ef74fc9d Mon Sep 17 00:00:00 2001 From: graemerocher Date: Wed, 25 Feb 2015 16:39:17 +0100 Subject: [PATCH 087/230] remove section on binary plugins, as all plugins are now binary --- src/en/guide/plugins/binaryPlugins.gdoc | 46 ------------------------- src/en/guide/toc.yml | 1 - 2 files changed, 47 deletions(-) delete mode 100644 src/en/guide/plugins/binaryPlugins.gdoc diff --git a/src/en/guide/plugins/binaryPlugins.gdoc b/src/en/guide/plugins/binaryPlugins.gdoc deleted file mode 100644 index a8190c35bbc..00000000000 --- a/src/en/guide/plugins/binaryPlugins.gdoc +++ /dev/null @@ -1,46 +0,0 @@ -Regular Grails plugins are packaged as zip files containing the full source of the plugin. This has some advantages in terms of being an open distribution system (anyone can see the source), in addition to avoiding problems with the source compatibility level used for compilation. - -As of Grails 2.0 you can pre-compile Grails plugins into regular JAR files known as "binary plugins". This has several advantages (and some disadvantages as discussed in the advantages of source plugins above) including: - -* Binary plugins can be published as standard JAR files to a Maven repository -* Binary plugins can be declared like any other JAR dependency -* Commercial plugins are more viable since the source isn't published -* IDEs have a better understanding since binary plugins are regular JAR files containing classes - -h4. Packaging - -To package a plugin in binary form you can use the package-plugin command and the @--binary@ flag: - -{code} -grails package-plugin --binary -{code} - -Supported artefacts include: - -* Grails artifact classes such as controllers, domain classes and so on -* I18n Message bundles -* GSP Views, layouts and templates - -You can also specify the packaging in the plugin descriptor: - -{code} -def packaging = "binary" -{code} - -in which case the packaging will default to binary. - -h4. Using Binary Plugins - -The packaging process creates a JAR file in the @target@ directory of the plugin, for example @target/foo-plugin-0.1.jar@. There are two ways to incorporate a binary plugin into an application. - -One is simply placing the plugin JAR file in your application's @lib@ directory. The other is to publish the plugin JAR to a compatible Maven repository and declare it as a dependency in @grails-app/conf/BuildConfig.groovy@: - -{code} -dependencies { - compile "mycompany:myplugin:0.1" -} -{code} - -{note} -Since binary plugins are packaged as JAR files, they are declared as dependencies in the @dependencies@ block, _not_ in the @plugins@ block as you may be naturally inclined to do. The @plugins@ block is used for declaring traditional source plugins packaged as zip files -{note} diff --git a/src/en/guide/toc.yml b/src/en/guide/toc.yml index f9c91ea1f88..2102c7b8923 100644 --- a/src/en/guide/toc.yml +++ b/src/en/guide/toc.yml @@ -282,7 +282,6 @@ plugins: title: The Artefact API queryingArtefacts: Asking About Available Artefacts customArtefacts: Adding Your Own Artefact Types - binaryPlugins: Binary Plugins spring: title: Grails and Spring theUnderpinningsOfGrails: The Underpinnings of Grails From 72d592bcf04e05347763f11998c80572a4f3acee Mon Sep 17 00:00:00 2001 From: graemerocher Date: Wed, 25 Feb 2015 16:41:29 +0100 Subject: [PATCH 088/230] fix link to traits --- src/en/guide/introduction/whatsNew/coreFeatures.gdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/en/guide/introduction/whatsNew/coreFeatures.gdoc b/src/en/guide/introduction/whatsNew/coreFeatures.gdoc index 01b0d35c6b4..2f0f33c4341 100644 --- a/src/en/guide/introduction/whatsNew/coreFeatures.gdoc +++ b/src/en/guide/introduction/whatsNew/coreFeatures.gdoc @@ -20,4 +20,4 @@ Grails 3.0 supports the notion of application profiles via a new [profile reposi h4. Redesigned API based on Traits -The Grails API has been redesigned so that public API is correctly populated under the @grails.@ package whilst private / internal API that is subject to change can be found in the @org.grails.@ package. The core API has also been rewritten and based around the [Groovy Traits|http://groovy-lang.org/docs/latest/html/documentation/core-traits.html]. +The Grails API has been redesigned so that public API is correctly populated under the @grails.@ package whilst private / internal API that is subject to change can be found in the @org.grails.@ package. The core API has also been rewritten and based around the [Groovy Traits|http://groovy-lang.org/objectorientation.html#_traits]. From a59eb9bfca711b87312bba6b2767f20650b06d3c Mon Sep 17 00:00:00 2001 From: Kazuki YAMAMOTO Date: Thu, 26 Feb 2015 10:13:06 +0900 Subject: [PATCH 089/230] Fix gradle setting sample of plugin which use ApplicationCommand --- src/en/guide/upgrading/upgradingPlugins.gdoc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/en/guide/upgrading/upgradingPlugins.gdoc b/src/en/guide/upgrading/upgradingPlugins.gdoc index c2bdbddb44e..e677e64070a 100644 --- a/src/en/guide/upgrading/upgradingPlugins.gdoc +++ b/src/en/guide/upgrading/upgradingPlugins.gdoc @@ -161,10 +161,10 @@ buildscript { dependencies { classpath "org.grails.plugins:myplugin:0.1-SNAPSHOT" } - ... - dependencies { - runtime "org.grails.plugins:myplugin:0.1-SNAPSHOT" - } +} +... +dependencies { + runtime "org.grails.plugins:myplugin:0.1-SNAPSHOT" } {code} From 46a178b5d8f83020a6ca11a7be3a41f75f1698f9 Mon Sep 17 00:00:00 2001 From: graemerocher Date: Thu, 26 Feb 2015 09:41:50 +0100 Subject: [PATCH 090/230] Links to new features --- src/en/guide/introduction/whatsNew/coreFeatures.gdoc | 6 ++++++ .../whatsNew/developmentEnvironmentFeatures.gdoc | 4 +++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/en/guide/introduction/whatsNew/coreFeatures.gdoc b/src/en/guide/introduction/whatsNew/coreFeatures.gdoc index 2f0f33c4341..eac7da65a40 100644 --- a/src/en/guide/introduction/whatsNew/coreFeatures.gdoc +++ b/src/en/guide/introduction/whatsNew/coreFeatures.gdoc @@ -14,10 +14,16 @@ h4. Gradle Build System Grails 3.0 deprecates the older Gant-based build system in favour of a new [Gradle-based|http://gradle.org] build that integrates closely with the [Gradle plugin ecosystem|http://plugins.gradle.org]. +See the new section on the new [Gradle build|guide:gradleBuild] for more information. + h4. Application Profiles Grails 3.0 supports the notion of application profiles via a new [profile repository|https://github.com/grails/grails-profile-repository]. A profile encapsulates an application structure, set of commands, plugins and capabilities. For example the "web" profile allows construction on web applications deployable to a Servlet container. In the future more profiles will be developed targeting different environments. +See the new section on [Profiles|guide:profiles] for more information. + h4. Redesigned API based on Traits The Grails API has been redesigned so that public API is correctly populated under the @grails.@ package whilst private / internal API that is subject to change can be found in the @org.grails.@ package. The core API has also been rewritten and based around the [Groovy Traits|http://groovy-lang.org/objectorientation.html#_traits]. + +See the new documentation on Grails 3.0's [core traits|guide:traits] for more information. diff --git a/src/en/guide/introduction/whatsNew/developmentEnvironmentFeatures.gdoc b/src/en/guide/introduction/whatsNew/developmentEnvironmentFeatures.gdoc index 7ceae47a052..af25259e016 100644 --- a/src/en/guide/introduction/whatsNew/developmentEnvironmentFeatures.gdoc +++ b/src/en/guide/introduction/whatsNew/developmentEnvironmentFeatures.gdoc @@ -4,10 +4,12 @@ Replacing Gant, Grails 3.0 features a new interactive command line shell that in The new shell integrates closely with the concept of application profiles with each profile capable defining [profile specific commands|https://github.com/grails/grails-profile-repository/tree/master/profiles/web/commands]. As with previous versions of Grails, plugins can define new shell commands that can invoke Gradle or perform code generation and project automation tasks. +See the new guide on [Creating Custom Scripts|guide:creatingCustomScripts] for more information. + h4. Enhanced IDE Integration Since Grails 3.0 is built on Gradle, you can now import a Grails project using IntelliJ community edition or GGTS's Gradle tooling support without the need for Grails specific tooling. Grails 3.0 plugins are published as simple JAR files greatly reducing the need for additional IDE support specific to Grails. h4. Application Main Class -Each new Grails 3.0 project features an @Application@ class that has a traditional @static void main@ signature, meaning to run or debug a Grails 3.0 application from an IDE like IntelliJ or GGTS you can simply right-click on the @Application@ class and execute to start your Grails application. All Grails 3.0 tests can also just be run from the IDE directly without needing to resort to the command line (even integration / functional tests!). +Each new Grails 3.0 project features an @Application@ class that has a traditional @static void main@ signature, meaning to run or debug a Grails 3.0 application from an IDE like IntelliJ or GGTS you can simply right-click on the @Application@ class and execute to start your Grails application. All Grails 3.0 tests can also just be run from the IDE directly without needing to resort to the command line (even integration / functional tests!). From db0cb2c96fe4d47b2dc8335dde7e1520880b03c3 Mon Sep 17 00:00:00 2001 From: graemerocher Date: Thu, 26 Feb 2015 16:29:41 +0100 Subject: [PATCH 091/230] Release grails-doc 3.0.0.M2 --- build.gradle | 2 +- gradle.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 99102d6dca2..a4900aff14d 100644 --- a/build.gradle +++ b/build.gradle @@ -22,7 +22,7 @@ buildscript { } dependencies { - classpath "org.grails:grails-docs:3.0.0.BUILD-SNAPSHOT" + classpath "org.grails:grails-docs:3.0.0.M2" classpath 'org.codehaus.groovy:groovy-all:2.4.0' } } diff --git a/gradle.properties b/gradle.properties index 020faca0686..f16f6b58dcd 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1 @@ -grails.version=3.0.0.BUILD-SNAPSHOT +grails.version=3.0.0.M2 From 49819018b0c9568cf009258c952bfbf3de8405a8 Mon Sep 17 00:00:00 2001 From: graemerocher Date: Thu, 26 Feb 2015 17:13:02 +0100 Subject: [PATCH 092/230] fix deploy file name --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 8ac462544e5..e1d1fc14800 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,7 +17,7 @@ deploy: provider: releases api_key: secure: OXqyhH6/rK9rmiApnm+8smg/+rjdM3T28/4ZUzbdibYZNSagVAMniDgndZIwt198jDvAPxf9jadN1G3OD5BLkW0wUWvAfYAtxAwOe6dzgcsMavdTxoBJnjXBc4XqFXSDhWTO4cd4vQ5Wx6cyvbUY5xgyREpvEP7oRUgQ0RJo9q8= - file: build/distributions/$RELEASE_FILE + file: build/distributions/grails-docs-${TRAVIS_TAG:1}.zip skip_cleanup: true on: repo: grails/grails-doc From 4c44bd6863aa31cfcf23d2dd2b8f7c4968d8645f Mon Sep 17 00:00:00 2001 From: Tom Crossland Date: Fri, 27 Feb 2015 20:35:20 +0100 Subject: [PATCH 093/230] Update upgradingPlugins.gdoc I'm guessing java sources shouldn't be copied to src/main/groovy --- src/en/guide/upgrading/upgradingPlugins.gdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/en/guide/upgrading/upgradingPlugins.gdoc b/src/en/guide/upgrading/upgradingPlugins.gdoc index e677e64070a..8379314235a 100644 --- a/src/en/guide/upgrading/upgradingPlugins.gdoc +++ b/src/en/guide/upgrading/upgradingPlugins.gdoc @@ -17,7 +17,7 @@ The next step is to copy the sources from the original Grails 2 plugin to the Gr {code} # first the sources cp -rf ../quartz-2.x/src/groovy src/main/groovy -cp -rf ../quartz-2.x/src/java src/main/groovy +cp -rf ../quartz-2.x/src/java src/main/java cp -rf ../quartz-2.x/grails-app grails-app cp -rf ../quartz-2.x/QuartzGrailsPlugin.groovy src/main/groovy/grails/plugins/quartz From 56b0d05a598af7c5be8279fda553b0a1bf9312d3 Mon Sep 17 00:00:00 2001 From: Jeff Scott Brown Date: Mon, 2 Mar 2015 09:04:52 -0600 Subject: [PATCH 094/230] update TraitInjector example --- src/en/guide/plugins/addingMethodsAtCompileTime.gdoc | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/en/guide/plugins/addingMethodsAtCompileTime.gdoc b/src/en/guide/plugins/addingMethodsAtCompileTime.gdoc index 03ebac316bb..645e8c6450e 100644 --- a/src/en/guide/plugins/addingMethodsAtCompileTime.gdoc +++ b/src/en/guide/plugins/addingMethodsAtCompileTime.gdoc @@ -18,19 +18,11 @@ package myplugin @CompileStatic class ControllerTraitInjector implements TraitInjector { - static Pattern CONTROLLER_PATTERN = Pattern.compile(".+/" + - GrailsResourceUtils.GRAILS_APP_DIR + "/controllers/(.+)Controller\\.groovy"); - @Override Class getTrait() { DateTrait } - @Override - boolean shouldInject(URL url) { - return url != null && CONTROLLER_PATTERN.matcher(url.getFile()).find(); - } - @Override String[] getArtefactTypes() { ['Controller'] as String[] @@ -38,4 +30,4 @@ class ControllerTraitInjector implements TraitInjector { } {code} -The above @TraitInjector@ will add the @DateTrait@ to all controllers. The @shouldInject@ method is used to restrict which source files will have the trait compiled into it. And the @getArtefactTypes@ method defines the supported artefact types. +The above @TraitInjector@ will add the @DateTrait@ to all controllers. The @getArtefactTypes@ method defines the types of artefacts that the trait should be applied to. From fe43cec013faa4b978f8434469ee92581ae4d1c2 Mon Sep 17 00:00:00 2001 From: Jeff Scott Brown Date: Tue, 10 Mar 2015 15:09:51 -0500 Subject: [PATCH 095/230] update some validateable notes --- ...alidationNonDomainAndCommandObjectClasses.gdoc | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/src/en/guide/validation/validationNonDomainAndCommandObjectClasses.gdoc b/src/en/guide/validation/validationNonDomainAndCommandObjectClasses.gdoc index 42cb958d113..76fb3052d9d 100644 --- a/src/en/guide/validation/validationNonDomainAndCommandObjectClasses.gdoc +++ b/src/en/guide/validation/validationNonDomainAndCommandObjectClasses.gdoc @@ -1,8 +1,8 @@ [Domain classes|guide:domainClasses] and [command objects|guide:commandObjects] support validation by default. Other classes may be made validateable by defining the static @constraints@ property in the class (as described above) and then telling the framework about them. It is important that the application register the validateable classes with the framework. Simply defining the @constraints@ property is not sufficient. -h4. The Validateable Annotation +h4. The Validateable Trait -Classes which define the static @constraints@ property and are annotated with @Validateable can be made validateable by the framework. Consider this example: +Classes which define the static @constraints@ property and implement the [Validateable|api:grails.validation.Validateable] trait will be validateable. Consider this example: {code:java} // src/groovy/com/mycompany/myapp/User.groovy @@ -10,8 +10,7 @@ package com.mycompany.myapp import grails.validation.Validateable -@Validateable -class User { +class User implements Validateable { ... static constraints = { @@ -22,11 +21,3 @@ class User { } } {code} - -h4. Registering Validateable Classes - -If a class is not marked with @Validateable, it may still be made validateable by the framework. The steps required to do this are to define the static @constraints@ property in the class (as described above) and then telling the framework about the class by assigning a value to the @grails.validateable.classes@ property in @Config.groovy@: - -{code:java} -grails.validateable.classes = [com.mycompany.myapp.User, com.mycompany.dto.Account] -{code} From 1d2bb8920821084b0b6f364ff3b7db4e2ac485b4 Mon Sep 17 00:00:00 2001 From: Jeff Scott Brown Date: Tue, 10 Mar 2015 15:40:30 -0500 Subject: [PATCH 096/230] GRAILS-11986 - remove notes about GroovyPagesTestCase --- src/en/guide/testing/integrationTesting.gdoc | 52 -------------------- 1 file changed, 52 deletions(-) diff --git a/src/en/guide/testing/integrationTesting.gdoc b/src/en/guide/testing/integrationTesting.gdoc index 9042ad9beb1..6825598cb17 100644 --- a/src/en/guide/testing/integrationTesting.gdoc +++ b/src/en/guide/testing/integrationTesting.gdoc @@ -242,58 +242,6 @@ class FooTagLibTests extends GroovyTestCase { Notice that for the second example, @testBodyTag@, we pass a block that returns the body of the tag. This is convenient to representing the body as a String. -h4. Testing Tag Libraries with GroovyPagesTestCase - -In addition to doing simple testing of tag libraries like in the above examples, you can also use the @grails.test.GroovyPagesTestCase@ class to test tag libraries with integration tests. - -The @GroovyPagesTestCase@ class is a subclass of the standard @GroovyTestCase@ class and adds utility methods for testing the output of GSP rendering. - -{note} -@GroovyPagesTestCase@ can only be used in an integration test. -{note} - -For example, consider this date formatting tag library: - -{code} -import java.text.SimpleDateFormat - -class FormatTagLib { - def dateFormat = { attrs, body -> - out << new SimpleDateFormat(attrs.format) << attrs.date - } -} -{code} - -This can be easily tested as follows: - -{code} -class FormatTagLibTests extends GroovyPagesTestCase { - void testDateFormat() { - def template = - '' - - def testDate = ... // create the date - assertOutputEquals('01-01-2008', template, [myDate:testDate]) - } -} -{code} - -You can also obtain the result of a GSP using the @applyTemplate@ method of the @GroovyPagesTestCase@ class: - -{code} -class FormatTagLibTests extends GroovyPagesTestCase { - void testDateFormat() { - def template = - '' - - def testDate = ... // create the date - def result = applyTemplate(template, [myDate:testDate]) - - assertEquals '01-01-2008', result - } -} -{code} - h4. Testing Domain Classes Testing domain classes is typically a simple matter of using the [GORM API|guide:GORM], but there are a few things to be aware of. Firstly, when testing queries you often need to "flush" to ensure the correct state has been persisted to the database. For example take the following example: From 3174ae50f2639ef0637141e5f3102a8206eff4ee Mon Sep 17 00:00:00 2001 From: Jeff Scott Brown Date: Tue, 10 Mar 2015 16:21:28 -0500 Subject: [PATCH 097/230] more trait notes --- src/en/guide/toc.yml | 6 +-- src/en/guide/traits.gdoc | 4 +- src/en/guide/traits/list.gdoc | 12 ------ src/en/guide/traits/overview.gdoc | 4 -- src/en/guide/traits/traitsprovided.gdoc | 38 +++++++++++++++++++ .../{overview => traitsprovided}/example.gdoc | 0 6 files changed, 43 insertions(+), 21 deletions(-) delete mode 100644 src/en/guide/traits/list.gdoc delete mode 100644 src/en/guide/traits/overview.gdoc create mode 100644 src/en/guide/traits/traitsprovided.gdoc rename src/en/guide/traits/{overview => traitsprovided}/example.gdoc (100%) diff --git a/src/en/guide/toc.yml b/src/en/guide/toc.yml index 2102c7b8923..bc526ffa4bb 100644 --- a/src/en/guide/toc.yml +++ b/src/en/guide/toc.yml @@ -176,12 +176,10 @@ theWebLayer: contentNegotiation: Content Negotiation traits: title: Traits - overview: - title: Overview + traitsprovided: + title: Traits Provided example: title: WebAttributes Trait Example - list: - title: Traits Provided webServices: title: Web Services REST: diff --git a/src/en/guide/traits.gdoc b/src/en/guide/traits.gdoc index 817a2181ce0..2b748fe1a2f 100644 --- a/src/en/guide/traits.gdoc +++ b/src/en/guide/traits.gdoc @@ -1 +1,3 @@ -h2. Traits Provided By Grails +h3. Overview + +Grails provides a number of traits which provide access to properties and behavior that may be accessed from various Grails artefacts as well as arbitrary Groovy classes which are part of a Grails project. Many of these traits are automatically added to Grails artefact classes (like controllers and taglibs, for example) and are easy to add to other classes. diff --git a/src/en/guide/traits/list.gdoc b/src/en/guide/traits/list.gdoc deleted file mode 100644 index fd55755e495..00000000000 --- a/src/en/guide/traits/list.gdoc +++ /dev/null @@ -1,12 +0,0 @@ -Below is a list of traits provided by the framework. The javadocs provide more detail about methods and properties related to each trait. - -{table} - *Trait* | *Brief Description* - [grails.web.api.WebAttributes|api:grails.web.api.WebAttributes] | Common Web Attributes - [grails.web.api.ServletAttributes|api:grails.web.api.ServletAttributes] | Servlet API Attributes - [grails.web.databinding.DataBinder|api:grails.web.databinding.DataBinder] | Data Binding API - [grails.artefact.controller.support.RequestForwarder|api:grails.artefact.controller.support.RequestForwarder] | Request Forwarding API - [grails.artefact.controller.support.ResponseRedirector|api:grails.artefact.controller.support.ResponseRedirector] | Response Redirecting API - [grails.artefact.controller.support.ResponseRenderer|api:grails.artefact.controller.support.ResponseRenderer] | Response Rendering API - [grails.validation.Validateable|api:grails.validation.Validateable] | Validation API -{table} diff --git a/src/en/guide/traits/overview.gdoc b/src/en/guide/traits/overview.gdoc deleted file mode 100644 index cbc8863c212..00000000000 --- a/src/en/guide/traits/overview.gdoc +++ /dev/null @@ -1,4 +0,0 @@ -h3. Overview - -Grails provides a number of traits which provide access to properties and behavior that may be accessed from various Grails artefacts as well as arbitrary Groovy classes which are part of a Grails project. Many of these traits are automatically added to Grails artefact classes (like controllers and taglibs, for example) and are easy to add to other classes. - diff --git a/src/en/guide/traits/traitsprovided.gdoc b/src/en/guide/traits/traitsprovided.gdoc new file mode 100644 index 00000000000..9d856912427 --- /dev/null +++ b/src/en/guide/traits/traitsprovided.gdoc @@ -0,0 +1,38 @@ +h2. Traits Provided By Grails + +Grails artefacts are automatically augmented with certain traits at compile time. + +h4. Domain Class Traits + +* [grails.artefact.DomainClass|api:grails.artefact.DomainClass] +* [grails.web.databinding.WebDataBinding|api:grails.web.databinding.WebDataBinding] +* org.grails.datastore.gorm.GormEntity +* org.grails.datastore.gorm.GormValidateable + +h4. Controller Traits +* [grails.artefact.gsp.TagLibraryInvoker|api:grails.artefact.gsp.TagLibraryInvoker] +* [grails.artefact.AsyncController|api:grails.artefact.AsyncController] +* [grails.artefact.controller.RestResponder|api:grails.artefact.controller.RestResponder] +* [grails.artefact.Controller|api:grails.artefact.Controller] + +h4. Interceptor Trait +* [grails.artefact.Interceptor|api:grails.artefact.Interceptor] + +h4. Tag Library Trait +* [grails.artefact.TagLibrary|api:grails.artefact.TagLibrary] + +h4. Service Trait +* [grails.artefact.Service|api:grails.artefact.Service] + +Below is a list of other traits provided by the framework. The javadocs provide more detail about methods and properties related to each trait. + +{table} + *Trait* | *Brief Description* + [grails.web.api.WebAttributes|api:grails.web.api.WebAttributes] | Common Web Attributes + [grails.web.api.ServletAttributes|api:grails.web.api.ServletAttributes] | Servlet API Attributes + [grails.web.databinding.DataBinder|api:grails.web.databinding.DataBinder] | Data Binding API + [grails.artefact.controller.support.RequestForwarder|api:grails.artefact.controller.support.RequestForwarder] | Request Forwarding API + [grails.artefact.controller.support.ResponseRedirector|api:grails.artefact.controller.support.ResponseRedirector] | Response Redirecting API + [grails.artefact.controller.support.ResponseRenderer|api:grails.artefact.controller.support.ResponseRenderer] | Response Rendering API + [grails.validation.Validateable|api:grails.validation.Validateable] | Validation API +{table} diff --git a/src/en/guide/traits/overview/example.gdoc b/src/en/guide/traits/traitsprovided/example.gdoc similarity index 100% rename from src/en/guide/traits/overview/example.gdoc rename to src/en/guide/traits/traitsprovided/example.gdoc From f4fde5f295874e346d010b42cf1e0ff4ffd1a353 Mon Sep 17 00:00:00 2001 From: graemerocher Date: Wed, 11 Mar 2015 12:17:48 +0100 Subject: [PATCH 098/230] =?UTF-8?q?Document=20the=20=E2=80=98Application?= =?UTF-8?q?=E2=80=99=20class?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/en/guide/conf/applicationClass.gdoc | 3 ++ .../applicationLifeCycle.gdoc | 16 ++++++++++ .../conf/applicationClass/customizing.gdoc | 31 +++++++++++++++++++ .../conf/applicationClass/executing.gdoc | 12 +++++++ src/en/guide/toc.yml | 6 ++++ 5 files changed, 68 insertions(+) create mode 100644 src/en/guide/conf/applicationClass.gdoc create mode 100644 src/en/guide/conf/applicationClass/applicationLifeCycle.gdoc create mode 100644 src/en/guide/conf/applicationClass/customizing.gdoc create mode 100644 src/en/guide/conf/applicationClass/executing.gdoc diff --git a/src/en/guide/conf/applicationClass.gdoc b/src/en/guide/conf/applicationClass.gdoc new file mode 100644 index 00000000000..e6424f5ef0d --- /dev/null +++ b/src/en/guide/conf/applicationClass.gdoc @@ -0,0 +1,3 @@ +Every new Grails application features an @Application@ class witin the the @grails-app/init@ directory. + +The @Application@ class subclasses the [GrailsAutoConfiguration|api:grails.boot.config.GrailsAutoConfiguration] class and features a @static void main@ method, meaning it can be run as a regular application. diff --git a/src/en/guide/conf/applicationClass/applicationLifeCycle.gdoc b/src/en/guide/conf/applicationClass/applicationLifeCycle.gdoc new file mode 100644 index 00000000000..876d17f3e40 --- /dev/null +++ b/src/en/guide/conf/applicationClass/applicationLifeCycle.gdoc @@ -0,0 +1,16 @@ +The @Application@ class also implements the [GrailsApplicationLifeCycle|api:grails.core.GrailsApplicationLifeCycle] interface which all plugins implement. + +This means that the @Application@ class can be used to perform the same functions as a plugin. You can override the [regular plugins hooks|guide:hookingIntoRuntimeConfiguration] such as @doWithSpring@, @doWithApplicationContext@ and so on by overriding the appropriate method: + +{code} +class Application extends GrailsAutoConfiguration { + @Override + Closure doWithSpring() { + {-> + mySpringBean(MyType) + } + } + + ... +} +{code} diff --git a/src/en/guide/conf/applicationClass/customizing.gdoc b/src/en/guide/conf/applicationClass/customizing.gdoc new file mode 100644 index 00000000000..0e741ef6325 --- /dev/null +++ b/src/en/guide/conf/applicationClass/customizing.gdoc @@ -0,0 +1,31 @@ +There are several ways in which you can customize the @Application@ class. + +h4. Customizing Scanning + +By default Grails will scan all known source directories for controllers, domain class etc., however if there are packages in other JAR files you wish to scan you can do so by overriding the @packageNames()@ method of the @Application@ class: + +{code} +class Application extends GrailsAutoConfiguration { + @Override + Collection packageNames() { + super.packageNames() + ['my.additional.package'] + } + + ... +} +{code} + +h4. Registering Additional Beans + +The @Application@ class can also be used as a source for Spring bean definitions, simply define a method annotated with the [Bean|api:org.springframework.context.annotation.Bean] and the returned object will become a Spring bean. The name of the method is used as the bean name: + +{code} +class Application extends GrailsAutoConfiguration { + @Bean + MyType myBean() { + return new MyType() + } + + ... +} +{code} diff --git a/src/en/guide/conf/applicationClass/executing.gdoc b/src/en/guide/conf/applicationClass/executing.gdoc new file mode 100644 index 00000000000..b016bf96720 --- /dev/null +++ b/src/en/guide/conf/applicationClass/executing.gdoc @@ -0,0 +1,12 @@ +There are several ways to execute the @Application@ class, if you are using an IDE then you can simply right click on the class and run it directly from your IDE which will start your Grails application. + +This is also useful for debugging since you can debug directly from the IDE without having to connect a remote debugger when using the @run-app --debug-jvm@ command from the command line. + +You can also package your application into a runnable WAR file, for example: + +{code} +$ grails package +$ java -jar build/libs/myapp-0.1.war +{code} + +This is useful if you plan to deploy your application using a container-less approach. diff --git a/src/en/guide/toc.yml b/src/en/guide/toc.yml index bc526ffa4bb..900d6dd92f8 100644 --- a/src/en/guide/toc.yml +++ b/src/en/guide/toc.yml @@ -32,6 +32,12 @@ conf: builtInOptions: Built in options logging: Logging configGORM: GORM + applicationClass: + title: The Application Class + executing: Executing the Application Class + customizing: Customizing the Application Class + applicationLifeCycle: The Application LifeCycle + environments: Environments dataSource: title: The DataSource From 715ae44ff92381ef6df8a9971c0639fd5cc255bd Mon Sep 17 00:00:00 2001 From: graemerocher Date: Wed, 11 Mar 2015 13:00:11 +0100 Subject: [PATCH 099/230] Documentation on events --- src/en/guide/async/events.gdoc | 17 +++++++++++++++++ src/en/guide/async/events/consuming.gdoc | 11 +++++++++++ src/en/guide/async/events/notifying.gdoc | 8 ++++++++ src/en/guide/toc.yml | 4 ++++ 4 files changed, 40 insertions(+) create mode 100644 src/en/guide/async/events.gdoc create mode 100644 src/en/guide/async/events/consuming.gdoc create mode 100644 src/en/guide/async/events/notifying.gdoc diff --git a/src/en/guide/async/events.gdoc b/src/en/guide/async/events.gdoc new file mode 100644 index 00000000000..47b9f6b9aac --- /dev/null +++ b/src/en/guide/async/events.gdoc @@ -0,0 +1,17 @@ +Grails 3.0 introduces a new Events API based on [Reactor|https://github.com/reactor/reactor]. + +All services and controllers in Grails 3.0 implement the [Events|api:grails.events.Events] trait. + +The @Events@ trait allows the ability to consume and publish events that are handled by Reactor. + +The default Reactor configuration utilises a thread pool backed event bus. You can however configure Reactor within @application.yml@, for example: + +{code} +reactor + dispatchers: + default: myExecutor + myExecutor: + type: threadPoolExecutor + size: 5 + backlog: 2048 +{code} diff --git a/src/en/guide/async/events/consuming.gdoc b/src/en/guide/async/events/consuming.gdoc new file mode 100644 index 00000000000..6d759e0f87c --- /dev/null +++ b/src/en/guide/async/events/consuming.gdoc @@ -0,0 +1,11 @@ +There are several ways to consume an event. As mentioned previously services and controllers implement the [Events|api:grails.events.Events] trait. + +The @Events@ trait provides several methods to register event consumers. For example: + +{code} +on("myEvent") { + println "Event fired!" +} +{code} + +Note that if you wish a class (other than a controller or service) to be an event consumer you simply have to implement the @Events@ trait and ensure the class is registered as a Spring bean. diff --git a/src/en/guide/async/events/notifying.gdoc b/src/en/guide/async/events/notifying.gdoc new file mode 100644 index 00000000000..7dc5575802a --- /dev/null +++ b/src/en/guide/async/events/notifying.gdoc @@ -0,0 +1,8 @@ +The @Events@ trait also provides methods for notifying of events. For example: + +{code} +notify "myEvent", "myData" +sendAndReceive "myEvent", "myData", { + println "Got response!" +} +{code} diff --git a/src/en/guide/toc.yml b/src/en/guide/toc.yml index 900d6dd92f8..fd1eef8bb06 100644 --- a/src/en/guide/toc.yml +++ b/src/en/guide/toc.yml @@ -218,6 +218,10 @@ webServices: async: title: Asynchronous Programming promises: Promises + events: + title: Events + consuming: Consuming Events + notifying: Event Notification asyncGorm: Asynchronous GORM asyncRequests: Asynchronous Request Handling asyncServletApi: Servlet 3.0 Async From 19e353865db8012989314cfc1a5551b4bbfb80f0 Mon Sep 17 00:00:00 2001 From: Jeff Scott Brown Date: Wed, 11 Mar 2015 19:48:20 -0500 Subject: [PATCH 100/230] update javascript tag docs --- src/en/ref/Tags/javascript.gdoc | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/en/ref/Tags/javascript.gdoc b/src/en/ref/Tags/javascript.gdoc index 77d32b895a6..4edcb547c98 100644 --- a/src/en/ref/Tags/javascript.gdoc +++ b/src/en/ref/Tags/javascript.gdoc @@ -2,9 +2,7 @@ h1. javascript h2. Purpose -Includes JavaScript libraries and scripts as well as providing a shorthand for inline JavaScript. Specifying a library indicates to the Ajax tags which JavaScript provider to use. - -This tag is [Resources plugin|http://grails.org/plugin/resources] aware, and will defer to the plugin to generate links to JavaScript as appropriate. It does this by including a resource module with the same name as the library you specify. +Includes JavaScript libraries and scripts as well as providing a shorthand for inline JavaScript. h2. Examples @@ -12,24 +10,19 @@ h2. Examples // actually imports '/app/js/myscript.js' -// imports all the necessary js for the scriptaculous library - - alert('hello') {code} h2. Description -If you do not include a "library" or "src" attribute but instead provide a body, the result is an inline script. +If you do not include a "src" attribute but instead provide a body, the result is an inline script. If you use this tag to render inline JavaScript code, it is recommended that you use the Resources plugin's tag to produce inline script that is included at the end of the body, or in the head if necessary - rather than inline. For more control use the Resources plugin's "":http://grails-plugins.github.com/grails-resources/ref/Tags/script.html tag directly. Attributes * @contextPath@ (optional) - the context path to use (relative to the application context path). Defaults to "" or path to the plugin for a plugin view or template. -* @library@ (optional) - The name of the library to include. Typical values include "jquery", "prototype", "scriptaculous", "yahoo" or "dojo" but plugins can contribute new providers. If the Resources plugin is installed, no link to the library will be rendered immediately. Rather, it will include the resource module with the same name as the library and let Resources do the rest. This means you must have a resource module declared with the same name, as if you had used an @@ tag. * @src@ (optional) - The name of the JavaScript file to import. Will look in /appname/js directory -* @base@ (optional) - specifies the full base url to prepend to the library name * @plugin@ (optional) - The plugin to look for the JavaScript in h2. Source From 4abf747ad7d9f550e3d8668824fe26a23da5439f Mon Sep 17 00:00:00 2001 From: Kazuki YAMAMOTO Date: Thu, 12 Mar 2015 15:22:32 +0900 Subject: [PATCH 101/230] Fix Multiple Datasources example --- .../conf/dataSource/multipleDatasources.gdoc | 73 ++++++++++--------- 1 file changed, 38 insertions(+), 35 deletions(-) diff --git a/src/en/guide/conf/dataSource/multipleDatasources.gdoc b/src/en/guide/conf/dataSource/multipleDatasources.gdoc index b689073b0d3..6b457697dfa 100644 --- a/src/en/guide/conf/dataSource/multipleDatasources.gdoc +++ b/src/en/guide/conf/dataSource/multipleDatasources.gdoc @@ -31,49 +31,52 @@ environments: initialSize: 5 {code} -This configures a single @DataSource@ with the Spring bean named @dataSource@. To configure extra @DataSource@s, add a @dataSources@ block (at the top level, in an environment block, or both, just like the standard @DataSource@ definition) with a custom name, separated by an underscore. For example, this configuration adds a second @DataSource@, using MySQL in the development environment and Oracle in production: +This configures a single @DataSource@ with the Spring bean named @dataSource@. To configure extra @DataSource@s, add a @dataSources@ block (at the top level, in an environment block, or both, just like the standard @DataSource@ definition) with a custom name. For example, this configuration adds a second @DataSource@, using MySQL in the development environment and Oracle in production: {code} --- -dataSources: - dataSource: - pooled: true - jmxExport: true - driverClassName: org.h2.Driver - username: sa - password: - dataSource_lookup: - dialect: org.hibernate.dialect.MySQLInnoDBDialect - driverClassName: com.mysql.jdbc.Driver - username: lookup - password: secret - url: jdbc:mysql://localhost/lookup - dbCreate: update +dataSources: + dataSource: + pooled: true + jmxExport: true + driverClassName: org.h2.Driver + username: sa + password: + lookup: + dialect: org.hibernate.dialect.MySQLInnoDBDialect + driverClassName: com.mysql.jdbc.Driver + username: lookup + password: secret + url: jdbc:mysql://localhost/lookup + dbCreate: update environments: development: - dataSource: - dbCreate: create-drop - url: jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE + dataSources: + dataSource: + dbCreate: create-drop + url: jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE test: - dataSource: - dbCreate: update - url: jdbc:h2:mem:testDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE + dataSources: + dataSource: + dbCreate: update + url: jdbc:h2:mem:testDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE production: - dataSource: - dbCreate: update - url: jdbc:h2:prodDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE - properties: - jmxEnabled: true - initialSize: 5 - ... - dataSource_lookup: - dialect: org.hibernate.dialect.Oracle10gDialect - driverClassName: oracle.jdbc.driver.OracleDriver - username: lookup - password: secret - url: jdbc:oracle:thin:@localhost:1521:lookup - dbCreate: update + dataSources: + dataSource: + dbCreate: update + url: jdbc:h2:prodDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE + properties: + jmxEnabled: true + initialSize: 5 + ... + lookup: + dialect: org.hibernate.dialect.Oracle10gDialect + driverClassName: oracle.jdbc.driver.OracleDriver + username: lookup + password: secret + url: jdbc:oracle:thin:@localhost:1521:lookup + dbCreate: update {code} You can use the same or different databases as long as they're supported by Hibernate. From 4d3fce23b923a61d5c0f087afdc700f7e9529102 Mon Sep 17 00:00:00 2001 From: graemerocher Date: Thu, 12 Mar 2015 09:58:26 +0100 Subject: [PATCH 102/230] update section on integration testing --- src/en/guide/testing/integrationTesting.gdoc | 276 +++---------------- 1 file changed, 33 insertions(+), 243 deletions(-) diff --git a/src/en/guide/testing/integrationTesting.gdoc b/src/en/guide/testing/integrationTesting.gdoc index 6825598cb17..e8305193eab 100644 --- a/src/en/guide/testing/integrationTesting.gdoc +++ b/src/en/guide/testing/integrationTesting.gdoc @@ -1,273 +1,63 @@ -Integration tests differ from unit tests in that you have full access to the Grails environment within the test. Grails uses an in-memory H2 database for integration tests and clears out all the data from the database between tests. +Integration tests differ from unit tests in that you have full access to the Grails environment within the test. You can create an integration test using the [create-integration-test|commandLine] command: -One thing to bear in mind is that logging is enabled for your application classes, but it is different from logging in tests. So if you have something like this: - -{code:java} -class MyServiceTests extends GroovyTestCase { - void testSomething() { - log.info "Starting tests" - ... - } -} -{code} - -the "starting tests" message is logged using a different system than the one used by the application. The @log@ property in the example above is an instance of @java.util.logging.Logger@ (inherited from the base class, not injected by Grails), which doesn't have the same methods as the @log@ property injected into your application artifacts. For example, it doesn't have @debug()@ or @trace()@ methods, and the equivalent of @warn()@ is in fact @warning()@. - -h4. Transactions - -Integration tests run inside a database transaction by default, which is rolled back at the end of the each test. This means that data saved during a test is not persisted to the database. Add a @transactional@ property to your test class to check transactional behaviour: - -{code} -class MyServiceTests extends GroovyTestCase { - static transactional = false - - void testMyTransactionalServiceMethod() { - ... - } -} {code} - -Be sure to remove any persisted data from a non-transactional test, for example in the @tearDown@ method, so these tests don't interfere with standard transactional tests that expect a clean database. - -h4. Testing Controllers - -To test controllers you first have to understand the Spring Mock Library. - -Grails automatically configures each test with a [MockHttpServletRequest|api:org.springframework.mock.web.MockHttpServletRequest], [MockHttpServletResponse|api:org.springframework.mock.web.MockHttpServletResponse], and [MockHttpSession|api:org.springframework.mock.web.MockHttpSession] that you can use in your tests. For example consider the following controller: - -{code:java} -class FooController { - - def text() { - render "bar" - } - - def someRedirect() { - redirect(action:"bar") - } -}{code} - -The tests for this would be: - -{code:java} -class FooControllerTests extends GroovyTestCase { - - void testText() { - def fc = new FooController() - fc.text() - assertEquals "bar", fc.response.contentAsString - } - - void testSomeRedirect() { - def fc = new FooController() - fc.someRedirect() - assertEquals "/foo/bar", fc.response.redirectedUrl - } -} +$ grails create-integration-test Example {code} -In the above case @response@ is an instance of @MockHttpServletResponse@ which we can use to obtain the generated content with @contentAsString@ (when writing to the response) or the redirected URL. These mocked versions of the Servlet API are completely mutable (unlike the real versions) and hence you can set properties on the request such as the @contextPath@ and so on. - -Grails *does not* invoke [interceptors|guide:interceptors] or servlet filters when calling actions during integration testing. You should test interceptors and filters in isolation, using [functional testing|guide:functionalTesting] if necessary. - -h4. Testing Controllers with Services - -If your controller references a service (or other Spring beans), you have to explicitly initialise the service from your test. +The above command will create a new integration test at the location @src/integration-test/groovy//ExampleSpec.groovy@. -Given a controller using a service: +Grails uses the test environment for integration tests and loads the application prior to the first test run. All tests use the same application state. -{code:java} -class FilmStarsController { - def popularityService - - def update() { - // do something with popularityService - } -}{code} - -The test for this would be: - -{code:java} -class FilmStarsTests extends GroovyTestCase { - def popularityService - - void testInjectedServiceInController () { - def fsc = new FilmStarsController() - fsc.popularityService = popularityService - fsc.update() - } -}{code} - -h4. Testing Controller Command Objects - -With command objects you just supply parameters to the request and it will automatically do the command object work for you when you call your action with no parameters: - -Given a controller using a command object: - -{code:java} -class AuthenticationController { - def signup(SignupForm form) { - ... - } -}{code} +h4. Transactions -You can then test it like this: +Integration tests run inside a database transaction by default, which is rolled back at the end of the each test. This means that data saved during a test is not persisted to the database (which is shared across all tests). The default generated integration test template includes the [Rollback|api:grails.transaction.Rollback] annotation: -{code:java} -def controller = new AuthenticationController() -controller.params.login = "marcpalmer" -controller.params.password = "secret" -controller.params.passwordConfirm = "secret" -controller.signup() {code} +import grails.test.mixin.integration.Integration +import grails.transaction.* +import spock.lang.* -Grails auto-magically sees your call to @signup()@ as a call to the action and populates the command object from the mocked request parameters. During controller testing, the @params@ are mutable with a mocked request supplied by Grails. - -h4. Testing Controllers and the render Method +@Integration +@Rollback +class @artifact.name@Spec extends Specification { -The [render|controllers] method lets you render a custom view at any point within the body of an action. For instance, consider the example below: + ... -{code:java} -def save() { - def book = Book(params) - if (book.save()) { - // handle - } - else { - render(view:"create", model:[book:book]) + void "test something"() { + expect:"fix me" + true == false } } {code} -In the above example the result of the model of the action is not available as the return value, but instead is stored within the @modelAndView@ property of the controller. The @modelAndView@ property is an instance of Spring MVC's [ModelAndView|http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/web/servlet/ModelAndView.html] class and you can use it to the test the result of an action: - -{code:java} -def bookController = new BookController() -bookController.save() -def model = bookController.modelAndView.model.book -{code} - -h4. Simulating Request Data - -You can use the Spring [MockHttpServletRequest|api:org.springframework.mock.web.MockHttpServletRequest] to test an action that requires request data, for example a REST web service. For example consider this action which performs data binding from an incoming request: - -{code:java} -def create() { - [book: new Book(params.book)] -} -{code} - -To simulate the 'book' parameter as an XML request you could do something like the following: +The @Rollback@ annotation ensures that each test methods runs in a transaction that is rolled back. Generally this is desirable because you do not want your tests depending on order or application state. -{code:java} -void testCreateWithXML() { +If you do have a series of tests that will share state you can remove the @Rollback@ and the last test in the suite should feature the [DirtiesContext|api:org.springframework.test.annotation.DirtiesContext] annotation which will shutdown the environment and restart it fresh (note that this will have an impact on test run times). - def controller = new BookController() +h4. Autowiring - controller.request.contentType = 'text/xml' - controller.request.content = '''\\\\ - - - The Stand - ... - - '''.stripIndent().getBytes() // note we need the bytes +To obtain a reference to a bean you can use the [Autowired|api:org.springframework.beans.factory.annotation.Autowired] annotation. For example: - def model = controller.create() - assert model.book - assertEquals "The Stand", model.book.title -} {code} +... +import org.springframework.beans.factory.annotation.* -The same can be achieved with a JSON request: - -{code:java} -void testCreateWithJSON() { - - def controller = new BookController() - - controller.request.contentType = "application/json" - controller.request.content = - '{"id":1,"class":"Book","title":"The Stand"}'.getBytes() - - def model = controller.create() - assert model.book - assertEquals "The Stand", model.book.title -} -{code} - -{note} -With JSON don't forget the @class@ property to specify the name the target type to bind to. In XML this is implicit within the name of the @@ node, but this property is required as part of the JSON packet. -{note} - -For more information on the subject of REST web services see the section on [REST|guide:REST]. - -h4. Testing Tag Libraries - -Testing tag libraries is simple because when a tag is invoked as a method it returns its result as a string (technically a @StreamCharBuffer@ but this class implements all of the methods of @String@). So for example if you have a tag library like this: +@Integration +@Rollback +class @artifact.name@Spec extends Specification { -{code:java} -class FooTagLib { + @Autowired + ExampleService exampleService + ... - def bar = { attrs, body -> - out << "

Hello World!

" - } - - def bodyTag = { attrs, body -> - out << "<\${attrs.name}>" - out << body() - out << "" + void "Test example service"() { + expect: + exampleService.countExamples() == 0 } } {code} -The tests would look like: - -{code:java} -class FooTagLibTests extends GroovyTestCase { - - void testBarTag() { - assertEquals "

Hello World!

", - new FooTagLib().bar(null, null).toString() - } - - void testBodyTag() { - assertEquals "

Hello World!

", - new FooTagLib().bodyTag(name: "p") { - "Hello World!" - }.toString() - } -} -{code} - -Notice that for the second example, @testBodyTag@, we pass a block that returns the body of the tag. This is convenient to representing the body as a String. - -h4. Testing Domain Classes -Testing domain classes is typically a simple matter of using the [GORM API|guide:GORM], but there are a few things to be aware of. Firstly, when testing queries you often need to "flush" to ensure the correct state has been persisted to the database. For example take the following example: - -{code:java} -void testQuery() { - def books = [ - new Book(title: "The Stand"), - new Book(title: "The Shining")] - books*.save() - - assertEquals 2, Book.list().size() -} -{code} - -This test will fail because calling [save|domainClasses] does not actually persist the @Book@ instances when called. Calling @save@ only indicates to Hibernate that at some point in the future these instances should be persisted. To commit changes immediately you "flush" them: - -{code:java} -void testQuery() { - def books = [ - new Book(title: "The Stand"), - new Book(title: "The Shining")] - books*.save(flush: true) - - assertEquals 2, Book.list().size() -} -{code} +h4. Testing Controllers -In this case since we're passing the argument @flush@ with a value of @true@ the updates will be persisted immediately and hence will be available to the query later on. +To integration test controllers it is recommended you use [create-functional-test|commandLine] command to create a Geb functional test. See the following section on functional testing for more information. From 43ee74b97ccf160c6e29f18e18e138e2e67f0aa5 Mon Sep 17 00:00:00 2001 From: graemerocher Date: Thu, 12 Mar 2015 11:01:34 +0100 Subject: [PATCH 103/230] Prepare 3.0.0.RC1 release --- build.gradle | 2 +- gradle.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index a4900aff14d..1010a47f31a 100644 --- a/build.gradle +++ b/build.gradle @@ -22,7 +22,7 @@ buildscript { } dependencies { - classpath "org.grails:grails-docs:3.0.0.M2" + classpath "org.grails:grails-docs:3.0.0.RC1" classpath 'org.codehaus.groovy:groovy-all:2.4.0' } } diff --git a/gradle.properties b/gradle.properties index f16f6b58dcd..ad85dc0a74d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1 @@ -grails.version=3.0.0.M2 +grails.version=3.0.0.RC1 From caf5cde1679352b1235bff8c2084d11da9d199de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=B3nal?= Date: Sun, 15 Mar 2015 16:19:37 +0000 Subject: [PATCH 104/230] Corrected path to Java src in Grails 3 --- src/en/guide/upgrading.gdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/en/guide/upgrading.gdoc b/src/en/guide/upgrading.gdoc index 0d31c0ff9f5..6cec851d226 100644 --- a/src/en/guide/upgrading.gdoc +++ b/src/en/guide/upgrading.gdoc @@ -27,7 +27,7 @@ The location of certain files have changed or been replaced with other files in @grails-app/conf/BootStrap.groovy@ | @grails-app/init/BootStrap.groovy@ | Moved since grails-app/conf is not a source directory anymore @scripts@ | @src/main/scripts@ | Moved for consistency with Gradle @src/groovy@ | @src/main/groovy@ | Moved for consistency with Gradle -@src/java@ | @src/main/groovy@ | Moved for consistency with Gradle +@src/java@ | @src/main/java@ | Moved for consistency with Gradle @test/unit@ | @src/test/groovy@ | Moved for consistency with Gradle @test/integration@ | @src/integration-test/groovy@ | Moved for consistency with Gradle @web-app@ | @src/main/webapp@ | Moved for consistency with Gradle From e36971e3a18ee9c46325581fdbc2209395d7fa8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=B3nal?= Date: Sun, 15 Mar 2015 22:29:58 +0000 Subject: [PATCH 105/230] Fixed path where java source should be located in Grails 3 --- src/en/guide/upgrading/upgradingPlugins.gdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/en/guide/upgrading/upgradingPlugins.gdoc b/src/en/guide/upgrading/upgradingPlugins.gdoc index 8379314235a..e677e64070a 100644 --- a/src/en/guide/upgrading/upgradingPlugins.gdoc +++ b/src/en/guide/upgrading/upgradingPlugins.gdoc @@ -17,7 +17,7 @@ The next step is to copy the sources from the original Grails 2 plugin to the Gr {code} # first the sources cp -rf ../quartz-2.x/src/groovy src/main/groovy -cp -rf ../quartz-2.x/src/java src/main/java +cp -rf ../quartz-2.x/src/java src/main/groovy cp -rf ../quartz-2.x/grails-app grails-app cp -rf ../quartz-2.x/QuartzGrailsPlugin.groovy src/main/groovy/grails/plugins/quartz From b49b9800d718a79231e02fd6d94e8f5e7b685874 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=B3nal?= Date: Sun, 15 Mar 2015 22:33:13 +0000 Subject: [PATCH 106/230] reverted previous change --- src/en/guide/upgrading.gdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/en/guide/upgrading.gdoc b/src/en/guide/upgrading.gdoc index 6cec851d226..0d31c0ff9f5 100644 --- a/src/en/guide/upgrading.gdoc +++ b/src/en/guide/upgrading.gdoc @@ -27,7 +27,7 @@ The location of certain files have changed or been replaced with other files in @grails-app/conf/BootStrap.groovy@ | @grails-app/init/BootStrap.groovy@ | Moved since grails-app/conf is not a source directory anymore @scripts@ | @src/main/scripts@ | Moved for consistency with Gradle @src/groovy@ | @src/main/groovy@ | Moved for consistency with Gradle -@src/java@ | @src/main/java@ | Moved for consistency with Gradle +@src/java@ | @src/main/groovy@ | Moved for consistency with Gradle @test/unit@ | @src/test/groovy@ | Moved for consistency with Gradle @test/integration@ | @src/integration-test/groovy@ | Moved for consistency with Gradle @web-app@ | @src/main/webapp@ | Moved for consistency with Gradle From 7c3b764f20f6d54b1cb66f0ae2479399968cf812 Mon Sep 17 00:00:00 2001 From: graemerocher Date: Wed, 18 Mar 2015 09:23:48 +0100 Subject: [PATCH 107/230] Prepare 3.0.0.RC2 release --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index ad85dc0a74d..c74122e52a5 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1 @@ -grails.version=3.0.0.RC1 +grails.version=3.0.0.RC2 From 6def0314bbb684967e4081a82bb6d55a4d619772 Mon Sep 17 00:00:00 2001 From: graemerocher Date: Wed, 18 Mar 2015 09:35:29 +0100 Subject: [PATCH 108/230] Prepare 3.0.0.RC2 release --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 1010a47f31a..20b8a3ab17d 100644 --- a/build.gradle +++ b/build.gradle @@ -22,7 +22,7 @@ buildscript { } dependencies { - classpath "org.grails:grails-docs:3.0.0.RC1" + classpath "org.grails:grails-docs:3.0.0.RC2" classpath 'org.codehaus.groovy:groovy-all:2.4.0' } } From fd216e68af9f22da91737c1f129a5925ed112211 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=B3nal?= Date: Thu, 19 Mar 2015 17:52:52 +0000 Subject: [PATCH 109/230] fixed typo --- src/en/guide/introduction/whatsNew/coreFeatures.gdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/en/guide/introduction/whatsNew/coreFeatures.gdoc b/src/en/guide/introduction/whatsNew/coreFeatures.gdoc index eac7da65a40..8161ab960c0 100644 --- a/src/en/guide/introduction/whatsNew/coreFeatures.gdoc +++ b/src/en/guide/introduction/whatsNew/coreFeatures.gdoc @@ -18,7 +18,7 @@ See the new section on the new [Gradle build|guide:gradleBuild] for more informa h4. Application Profiles -Grails 3.0 supports the notion of application profiles via a new [profile repository|https://github.com/grails/grails-profile-repository]. A profile encapsulates an application structure, set of commands, plugins and capabilities. For example the "web" profile allows construction on web applications deployable to a Servlet container. In the future more profiles will be developed targeting different environments. +Grails 3.0 supports the notion of application profiles via a new [profile repository|https://github.com/grails/grails-profile-repository]. A profile encapsulates an application structure, set of commands, plugins and capabilities. For example the "web" profile allows construction of web applications deployable to a Servlet container. In the future more profiles will be developed targeting different environments. See the new section on [Profiles|guide:profiles] for more information. From 6b4be039f5a9f2d2d36593fcf9f34ccf798ef26d Mon Sep 17 00:00:00 2001 From: Lari Hotari Date: Wed, 25 Mar 2015 04:11:40 +0200 Subject: [PATCH 110/230] synch Travis build changes from master branch --- .travis.yml | 25 ++++++++++++ README.md | 4 ++ build.gradle | 22 ++++++---- gradle.properties | 1 + gradle/wrapper/gradle-wrapper.jar | Bin 51348 -> 52141 bytes gradle/wrapper/gradle-wrapper.properties | 4 +- quick-publish.sh | 2 +- travis-build.sh | 50 +++++++++++++++++++++++ 8 files changed, 97 insertions(+), 11 deletions(-) create mode 100644 .travis.yml create mode 100644 gradle.properties create mode 100755 travis-build.sh diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000000..e1d1fc14800 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,25 @@ +script: ./travis-build.sh +sudo: false +jdk: +- openjdk7 +env: + global: + - GRADLE_OPTS="-server -Xmx1024M -Xms768M -XX:PermSize=256m -XX:MaxPermSize=512m" + - GIT_NAME="Graeme Rocher" + - GIT_EMAIL="graeme.rocher@gmail.com" + - secure: SdGzn2ItEkM0UGzByv/0yXLO7g9iJYmrSIgQ3a1yZXvOerQOLuOwwTZIJ4LUBJpJcQRhiAff1HidN/6fAGAd4mwgoQcX1kKdrRHIl0oG7V7DC9YRytPko/gasQ6aPoR3GBBpLqx8hIjGYbVKIrPWgMSRRA7DSvbzI5XlOgAX1Dg= + - secure: R9aL92lh09LniCTbiZuuikiWHXL4ik/DDAKe7NLanqpI126vs5Y9zd56JifgN8Mp7sEbwlaM4RzFXpgkdl57FZqdDzC04ljeqy9Z4CmGthUCF2o2exV98HFWxrL6J18OH5zVSBtZJN0ANcgdJ3/+vMuk2wyS61qhl36uiUM66tM= +cache: + directories: + - $HOME/.gradle/wrapper + - $HOME/.gradle/caches +deploy: + provider: releases + api_key: + secure: OXqyhH6/rK9rmiApnm+8smg/+rjdM3T28/4ZUzbdibYZNSagVAMniDgndZIwt198jDvAPxf9jadN1G3OD5BLkW0wUWvAfYAtxAwOe6dzgcsMavdTxoBJnjXBc4XqFXSDhWTO4cd4vQ5Wx6cyvbUY5xgyREpvEP7oRUgQ0RJo9q8= + file: build/distributions/grails-docs-${TRAVIS_TAG:1}.zip + skip_cleanup: true + on: + repo: grails/grails-doc + tags: true + all_branches: true diff --git a/README.md b/README.md index 4bd1bcc4da0..dd54a9d637c 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,10 @@ Building the Guide To build the documentation, simply type: ./gradlew docs + +This will take some time as it generates groovydoc for the Grails sources. If you want to just generate the user guide to preview your change you can do: + + ./gradlew -Ddisable.groovydocs=true docs Be warned: this command can take a while to complete and you should probably increase your Gradle memory settings by giving the `GRADLE_OPTS` environment variable a value like diff --git a/build.gradle b/build.gradle index 1733adab2ca..44c2a419e40 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,6 @@ apply plugin: "base" -version = System.getProperty("grails.version") ?: "2.4.4.BUILD-SNAPSHOT" +version = project.getProperty("grails.version") archivesBaseName = "grails-docs" @@ -22,11 +22,15 @@ buildscript { } dependencies { - classpath "org.grails:grails-docs:2.4.4.BUILD-SNAPSHOT" - classpath 'org.codehaus.groovy:groovy-all:2.3.0' + classpath "org.grails:grails-docs:3.0.0.RC2" + classpath 'org.codehaus.groovy:groovy-all:2.4.3' } } +task buildscriptDependencies(type: DependencyReportTask) { + configurations = [buildscript.configurations.classpath] +} + // use jsoup in PdfBuilder for cleaning input html System.setProperty('grails.docs.clean.html','true') // creates single.html.before.xml and single.html.after.xml files for debugging pdf input when enabled @@ -47,15 +51,17 @@ task fetchGrailsSource << { mapper type: "regexp", from: "(grails-grails-core-\\S*?/)(.*)", to: "grails-src/\\2" } + ant.chmod(file:"${checkOutDir}/grails-src/gradlew", perm:700) + println "Grails source code has been downloaded to ${relativePath(grailsHome)}" } fetchGrailsSource.onlyIf { !explicitGrailsHome } -task apiDocs(type: GradleBuild, dependsOn: 'fetchGrailsSource') { - tasks = ["groovydoc"] - buildFile = "${project.grailsHome}/build.gradle" - startParameter.excludedTaskNames = ['compileGroovy', 'compileUaaGroovy', 'compileJsp21Groovy', 'compileAstGroovy', 'jar'] +task apiDocs(type: Exec, dependsOn: 'fetchGrailsSource') { + commandLine = ["./gradlew", "groovydoc", '--info', '--stacktrace'] + workingDir = "${checkOutDir}/grails-src" + environment "GRADLE_OPTS", "-Xmx2048m -Xms256m -XX:MaxPermSize=512m -XX:+CMSClassUnloadingEnabled -XX:+HeapDumpOnOutOfMemoryError" } apiDocs.onlyIf { !System.getProperty("disable.groovydocs") } @@ -78,7 +84,7 @@ task publishGuide(type: grails.doc.gradle.PublishGuide, dependsOn: ['apiDocs', ' // generated with a 'en' in the path, but the source is in 'en' // so that it's easy to track with git. sourceDir = new File(projectDir, "src/en") - propertiesFiles = [ new File(project.grailsHome, "build.properties") ] + propertiesFiles = [ new File(projectDir, "gradle.properties") ] macros = [ new grails.doc.macros.GspTagSourceMacro(searchDirs) ] } diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 00000000000..e70df9b0a6d --- /dev/null +++ b/gradle.properties @@ -0,0 +1 @@ +grails.version=2.4.5 diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 0087cd3b18659b5577cf6ad3ef61f8eb9416ebba..085a1cdc27db1185342f15a00441734e74fe3735 100644 GIT binary patch delta 20006 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 delta 19193 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 ove~tpA@RwG0)=N%#OK!lL%xx2pdXP%h?w ~/.git-credentials + +export GRADLE_OPTS="-Xmx2048m -Xms256m -XX:MaxPermSize=512m -XX:+CMSClassUnloadingEnabled -XX:+HeapDumpOnOutOfMemoryError" + +./gradlew assemble --info --stacktrace + +if [[ $TRAVIS_PULL_REQUEST == 'false' ]]; then + + # If there is a tag present then this becomes the latest + if [[ -n $TRAVIS_TAG ]]; then + git clone https://${GH_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git -b gh-pages gh-pages --single-branch > /dev/null + cd gh-pages + + version="$TRAVIS_TAG" + version=${version:1} + zipName="grails-docs-$version" + export RELEASE_FILE="${zipName}.zip" + + milestone=${version:5} + if [[ -n $milestone ]]; then + git rm -rf latest/ + mkdir -p latest + cp -r ../build/docs/. ./latest/ + git add latest/* + fi + + majorVersion=${version:0:4} + majorVersion="${majorVersion}x" + + mkdir -p "$version" + cp -r ../build/docs/. "./$version/" + git add "$version/*" + + mkdir -p "$majorVersion" + cp -r ../build/docs/. "./$majorVersion/" + git add "$majorVersion/*" + git commit -a -m "Updating docs for Travis build: https://travis-ci.org/$TRAVIS_REPO_SLUG/builds/$TRAVIS_BUILD_ID" + git push origin HEAD + cd .. + rm -rf gh-pages + + fi + +fi From dd3cb3622531480a5753793f0bd8ed4a671a7e86 Mon Sep 17 00:00:00 2001 From: Lari Hotari Date: Wed, 25 Mar 2015 04:18:37 +0200 Subject: [PATCH 111/230] Release 2.5.0 docs --- build.gradle | 2 +- gradle.properties | 2 +- resources/doc.properties | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/build.gradle b/build.gradle index 44c2a419e40..6d2c89db0b4 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ archivesBaseName = "grails-docs" ext.checkOutDir = "${buildDir.path}/checkout" ext.outputDir = "${buildDir.path}/docs" -ext.githubBranch = "2.4.x" +ext.githubBranch = "2.5.x" ext.explicitGrailsHome = System.getProperty("grails.home") ext.grailsHome = explicitGrailsHome ? file(explicitGrailsHome).absolutePath : "$checkOutDir/grails-src" diff --git a/gradle.properties b/gradle.properties index e70df9b0a6d..f2fd1056851 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1 @@ -grails.version=2.4.5 +grails.version=2.5.0 diff --git a/resources/doc.properties b/resources/doc.properties index dfea64f9d61..88cb286e82c 100644 --- a/resources/doc.properties +++ b/resources/doc.properties @@ -89,9 +89,9 @@ api.org.springframework=http://docs.spring.io/spring/docs/4.0.x/javadoc-api api.javax.servlet=http://download.oracle.com/javaee/1.4/api api.java.=http://docs.oracle.com/javase/6/docs/api api.groovy.=http://docs.groovy-lang.org/docs/latest/html/api -api.org.codehaus.groovy.grails=http://grails.org/doc/2.4.x/api -api.grails.=http://grails.org/doc/2.4.x/api -api.org.grails.=http://grails.org/doc/2.4.x/api +api.org.codehaus.groovy.grails=http://grails.org/doc/2.5.x/api +api.grails.=http://grails.org/doc/2.5.x/api +api.org.grails.=http://grails.org/doc/2.5.x/api # Regular expression to parse out source code source.tag.regex=/\s*?def\s+?[a-zA-Z]+?\s*?=\s*?\{\s*?attrs\s*?,{0,1}\s*?body{0,1}\s*?->.+?/ From f81c587cf73956c62408712faed643220e0eab4e Mon Sep 17 00:00:00 2001 From: Lari Hotari Date: Wed, 25 Mar 2015 04:23:41 +0200 Subject: [PATCH 112/230] attempt to fix build failure --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 44c2a419e40..bd17849d958 100644 --- a/build.gradle +++ b/build.gradle @@ -22,8 +22,8 @@ buildscript { } dependencies { - classpath "org.grails:grails-docs:3.0.0.RC2" - classpath 'org.codehaus.groovy:groovy-all:2.4.3' + classpath "org.grails:grails-docs:2.4.5" + classpath 'org.codehaus.groovy:groovy-all:2.3.11' } } From 2dcdd8edd58da7321b316e4ff06b5722f91f2350 Mon Sep 17 00:00:00 2001 From: Lari Hotari Date: Wed, 25 Mar 2015 06:12:59 +0200 Subject: [PATCH 113/230] Revert "attempt to fix build failure" This reverts commit f81c587cf73956c62408712faed643220e0eab4e. --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index bd17849d958..44c2a419e40 100644 --- a/build.gradle +++ b/build.gradle @@ -22,8 +22,8 @@ buildscript { } dependencies { - classpath "org.grails:grails-docs:2.4.5" - classpath 'org.codehaus.groovy:groovy-all:2.3.11' + classpath "org.grails:grails-docs:3.0.0.RC2" + classpath 'org.codehaus.groovy:groovy-all:2.4.3' } } From 79e2bec9f241c295705e232e1725538742b718e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Le=20Callonnec?= Date: Wed, 25 Mar 2015 13:41:42 +0000 Subject: [PATCH 114/230] Fix incorrect doc on `UrlConstraint` using `commons-validator`. `UrlConstraint` uses its own `UrlValidator` and `DomainValidator`, and does *not* use `commons-validator`. This matters in the case you are trying to get Grails to accept new TLDs, such as `.pizza` or `.wtf`: upgrading `commons-validator` to the latest version won't help, since it is not used to validate URLs, and the Grails `DomainValidator` maintains its own TLD list. --- src/en/ref/Constraints/url.gdoc | 2 +- src/es/ref/Constraints/url.gdoc | 2 +- src/fr/ref/Constraints/url.gdoc | 2 +- src/th/ref/Constraints/url.gdoc | 2 +- src/zh_CN/ref/Constraints/url.gdoc | 2 +- src/zh_TW/ref/Constraints/url.gdoc | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/en/ref/Constraints/url.gdoc b/src/en/ref/Constraints/url.gdoc index 59ffce86ce2..5f0f71956c7 100644 --- a/src/en/ref/Constraints/url.gdoc +++ b/src/en/ref/Constraints/url.gdoc @@ -12,6 +12,6 @@ homePage url: true h2. Description -Set to @true@ if a string value must be a URL. Internally uses the @org.apache.commons.validator.UrlValidator@ class. +Set to @true@ if a string value must be a URL. Error Code: @className.propertyName.url.invalid@ diff --git a/src/es/ref/Constraints/url.gdoc b/src/es/ref/Constraints/url.gdoc index 59ffce86ce2..5f0f71956c7 100644 --- a/src/es/ref/Constraints/url.gdoc +++ b/src/es/ref/Constraints/url.gdoc @@ -12,6 +12,6 @@ homePage url: true h2. Description -Set to @true@ if a string value must be a URL. Internally uses the @org.apache.commons.validator.UrlValidator@ class. +Set to @true@ if a string value must be a URL. Error Code: @className.propertyName.url.invalid@ diff --git a/src/fr/ref/Constraints/url.gdoc b/src/fr/ref/Constraints/url.gdoc index 59ffce86ce2..5f0f71956c7 100644 --- a/src/fr/ref/Constraints/url.gdoc +++ b/src/fr/ref/Constraints/url.gdoc @@ -12,6 +12,6 @@ homePage url: true h2. Description -Set to @true@ if a string value must be a URL. Internally uses the @org.apache.commons.validator.UrlValidator@ class. +Set to @true@ if a string value must be a URL. Error Code: @className.propertyName.url.invalid@ diff --git a/src/th/ref/Constraints/url.gdoc b/src/th/ref/Constraints/url.gdoc index 59ffce86ce2..5f0f71956c7 100644 --- a/src/th/ref/Constraints/url.gdoc +++ b/src/th/ref/Constraints/url.gdoc @@ -12,6 +12,6 @@ homePage url: true h2. Description -Set to @true@ if a string value must be a URL. Internally uses the @org.apache.commons.validator.UrlValidator@ class. +Set to @true@ if a string value must be a URL. Error Code: @className.propertyName.url.invalid@ diff --git a/src/zh_CN/ref/Constraints/url.gdoc b/src/zh_CN/ref/Constraints/url.gdoc index 59ffce86ce2..5f0f71956c7 100644 --- a/src/zh_CN/ref/Constraints/url.gdoc +++ b/src/zh_CN/ref/Constraints/url.gdoc @@ -12,6 +12,6 @@ homePage url: true h2. Description -Set to @true@ if a string value must be a URL. Internally uses the @org.apache.commons.validator.UrlValidator@ class. +Set to @true@ if a string value must be a URL. Error Code: @className.propertyName.url.invalid@ diff --git a/src/zh_TW/ref/Constraints/url.gdoc b/src/zh_TW/ref/Constraints/url.gdoc index 59ffce86ce2..5f0f71956c7 100644 --- a/src/zh_TW/ref/Constraints/url.gdoc +++ b/src/zh_TW/ref/Constraints/url.gdoc @@ -12,6 +12,6 @@ homePage url: true h2. Description -Set to @true@ if a string value must be a URL. Internally uses the @org.apache.commons.validator.UrlValidator@ class. +Set to @true@ if a string value must be a URL. Error Code: @className.propertyName.url.invalid@ From 1a0fd441f73846e4c30f99e0876f08d800837a41 Mon Sep 17 00:00:00 2001 From: B5A7 Date: Thu, 26 Mar 2015 12:31:06 +1100 Subject: [PATCH 115/230] responseFormats needs to be updated Otherwise you will receive Response code: 406 Response message: Not Acceptable --- .../guide/webServices/REST/versioningResources.gdoc | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/en/guide/webServices/REST/versioningResources.gdoc b/src/en/guide/webServices/REST/versioningResources.gdoc index 6dbbbc7bf9f..32ebba49fc3 100644 --- a/src/en/guide/webServices/REST/versioningResources.gdoc +++ b/src/en/guide/webServices/REST/versioningResources.gdoc @@ -72,6 +72,17 @@ beans = { } {code} +Then update the list of acceptable response formats in your controller: + +{code} +class BookController extends RestfulController { + static responseFormats = ['json', 'xml', 'book', 'bookv2'] + + // ... +} +{code} + + Then using the @Accept@ header you can specify which version you need using the Mime Type: {code} From 568b623a78fe6822bbce8e7f8fbeb2cc15952d1e Mon Sep 17 00:00:00 2001 From: graemerocher Date: Thu, 26 Mar 2015 11:18:50 +0100 Subject: [PATCH 116/230] Improve upgrade documentation --- .../guide/gettingStarted/aHelloWorldExample.gdoc | 16 ++++++++++++---- src/en/guide/upgrading/upgradingApps.gdoc | 8 +++++++- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/en/guide/gettingStarted/aHelloWorldExample.gdoc b/src/en/guide/gettingStarted/aHelloWorldExample.gdoc index e3c5db0800b..abb883a6603 100644 --- a/src/en/guide/gettingStarted/aHelloWorldExample.gdoc +++ b/src/en/guide/gettingStarted/aHelloWorldExample.gdoc @@ -17,7 +17,7 @@ Don't forget that in the interactive console, we have auto-completion on command The above command will create a new [controller|guide:controllers] in the @grails-app/controllers/helloworld@ directory called @HelloController.groovy@. Why the extra @helloworld@ directory? Because in Java land, it's strongly recommended that all classes are placed into packages, so Grails defaults to the application name if you don't provide one. The reference page for [create-controller|commandLine] provides more detail on this. -We now have a controller so let's add an action to generate the "Hello World!" page. The code looks like this: +We now have a controller so let's add an action to generate the "Hello World!" page. The code looks like this: {code:java} package helloworld @@ -37,10 +37,19 @@ Job done. To see your application in action, you just need to start up a server bc. grails> run-app -This will start an embedded server on port 8080 that hosts your application. You should now be able to access your application at the URL [http://localhost:8080/helloworld/|http://localhost:8080/helloworld/] - try it! +This will start an embedded server on port 8080 that hosts your application. You should now be able to access your application at the URL [http://localhost:8080/|http://localhost:8080/] - try it! + +Note that in previous versions of Grails the context path was by default the name of the application. If you wish to restore this behavior you can configure a context path in @grails-app/conf/application.yml@: + +{code} +server: + 'context-path': '/helloworld' +{code} + +With the above configuration in place the server will instead startup at the URL [http://localhost:8080/helloworld/|http://localhost:8080/helloworld/]. {note} -If you see the error "Server failed to start for port 8080: Address already in use", then it means another server is running on that port. You can easily work around this by running your server on a different port using @-Dserver.port=9090 run-app@. '9090' is just an example: you can pretty much choose anything within the range 1024 to 49151. +If you see the error "Server failed to start for port 8080: Address already in use", then it means another server is running on that port. You can easily work around this by running your server on a different port using @run-app -port=9090@. '9090' is just an example: you can pretty much choose anything within the range 1024 to 49151. {note} The result will look something like this: @@ -50,4 +59,3 @@ The result will look something like this: This is the Grails intro page which is rendered by the @grails-app/view/index.gsp@ file. It detects the presence of your controllers and provides links to them. You can click on the "HelloController" link to see our custom page containing the text "Hello World!". Voila! You have your first working Grails application. One final thing: a controller can contain many actions, each of which corresponds to a different page (ignoring AJAX at this point). Each page is accessible via a unique URL that is composed from the controller name and the action name: ///. This means you can access the Hello World page via [/helloworld/hello/index|http://localhost:8080/helloworld/hello/index], where 'hello' is the controller name (remove the 'Controller' suffix from the class name and lower-case the first letter) and 'index' is the action name. But you can also access the page via the same URL without the action name: this is because 'index' is the _default action_. See the end of the [controllers and actions|guide:understandingControllersAndActions] section of the user guide to find out more on default actions. - diff --git a/src/en/guide/upgrading/upgradingApps.gdoc b/src/en/guide/upgrading/upgradingApps.gdoc index c7ee1cb06b9..f82cdcae83e 100644 --- a/src/en/guide/upgrading/upgradingApps.gdoc +++ b/src/en/guide/upgrading/upgradingApps.gdoc @@ -47,7 +47,13 @@ If you have a modified @web.xml@ template then you will need to migrate this to New servlets and filters can be registered as Spring beans or with [ServletRegistrationBean|api:org.springframework.boot.context.embedded.ServletRegistrationBean] and [FilterRegistrationBean|api:org.springframework.boot.context.embedded.FilterRegistrationBean] respectively. -h4. Step 7 - Migrate Tests +h4. Migrate Static Assets not handled by Asset Pipeline + +If you have static assets in your @web-app@ directory of your Grails 2.x application such as HTML files, TLDs etc. these need to be moved. For public assets such as static HTML pages and so on these should go in @src/main/resources/public@. + +TLD descriptors and not public assets should go in @src/main/resources/WEB-INF@ . + +h4. Step 8 - Migrate Tests Once the package names are corrected unit tests will continue to run, however any tests that extend the deprecated and removed JUnit 3 hierarchy will need to be migrated to Spock or JUnit 4. From 68883277b556159372c481822f0325807b9320e6 Mon Sep 17 00:00:00 2001 From: graemerocher Date: Thu, 26 Mar 2015 13:43:07 +0100 Subject: [PATCH 117/230] Better document deployment options --- src/en/guide/deployment.gdoc | 90 +++++++------------ .../deployingAnApplication.gdoc | 8 +- 2 files changed, 39 insertions(+), 59 deletions(-) diff --git a/src/en/guide/deployment.gdoc b/src/en/guide/deployment.gdoc index c9213b0c2b9..b15fcac8889 100644 --- a/src/en/guide/deployment.gdoc +++ b/src/en/guide/deployment.gdoc @@ -4,89 +4,63 @@ h3. "grails run-app" You should be very familiar with this approach by now, since it is the most common method of running an application during the development phase. An embedded Tomcat server is launched that loads the web application from the development sources, thus allowing it to pick up an changes to application files. -This approach is not recommended at all for production deployment because the performance is poor. Checking for and loading changes places a sizable overhead on the server. Having said that, @grails prod run-app@ removes the per-request overhead and lets you fine tune how frequently the regular check takes place. +You can also deploy to production this way using: -Setting the system property "disable.auto.recompile" to @true@ disables this regular check completely, while the property "recompile.frequency" controls the frequency. This latter property should be set to the number of seconds you want between each check. The default is currently 3. - -h3. "grails run-war" +{code} +grails prod run-app +{code} -This is very similar to the previous option, but Tomcat runs against the packaged WAR file rather than the development sources. Hot-reloading is disabled, so you get good performance without the hassle of having to deploy the WAR file elsewhere. +h3. "Runnable WAR or JAR file" -h3. WAR file - -When it comes down to it, current java infrastructures almost mandate that web applications are deployed as WAR files, so this is by far the most common approach to Grails application deployment in production. Creating a WAR file is as simple as executing the [war|commandLine] command: +Another alternative in Grails 3.0 or above is to use the new support for runnable JAR or WAR files. To create runnable archives run @grails package@: {code} -grails war +$ grails package {code} -There are also many ways in which you can customise the WAR file that is created. For example, you can specify a path (either absolute or relative) to the command that instructs it where to place the file and what name to give it: +You can then run either the WAR file or the JAR using your Java installation: {code} -grails war /opt/java/tomcat-5.5.24/foobar.war +java -Dgrails.env=prod -jar build/libs/mywar-0.1.jar + +// or + +java -Dgrails.env=prod -jar build/libs/mywar-0.1.war {code} -Alternatively, you can add a line to @grails-app/conf/BuildConfig.groovy@ that changes the default location and filename: +h3. A TAR/ZIP distribution + +The [package|commandLine] will also produce a TAR and a ZIP file in the @build/distributions@ directory. If you extract these archives (typically the TAR on Unix systems and the ZIP on Windows) you can then run bash file which is the name of your application located in the @bin@ directory. + +For example: {code} -grails.project.war.file = "foobar-prod.war" +$ grails create-app helloworld +$ cd helloworld +$ grails package +$ tar -xvf build/distributions/helloworld-0.1.tar +$ export HELLOWORLD_OPTS=-Dgrails.env=prod +$ helloworld-0.1/bin/helloworld +Grails application running at http://localhost:8080 {code} -Any command line argument that you provide overrides this setting. - -It is also possible to control what libraries are included in the WAR file, for example to avoid conflicts with libraries in a shared directory. The default behavior is to include in the WAR file all libraries required by Grails, plus any libraries contained in plugin "lib" directories, plus any libraries contained in the application's "lib" directory. As an alternative to the default behavior you can explicitly specify the complete list of libraries to include in the WAR file by setting the property @grails.war.dependencies@ in BuildConfig.groovy to either lists of Ant include patterns or closures containing AntBuilder syntax. Closures are invoked from within an Ant "copy" step, so only elements like "fileset" can be included, whereas each item in a pattern list is included. Any closure or pattern assigned to the latter property will be included in addition to @grails.war.dependencies@. +h3. WAR file -Be careful with these properties: if any of the libraries Grails depends on are missing, the application will almost certainly fail. Here is an example that includes a small subset of the standard Grails dependencies: +A common approach to Grails application deployment in production is to deploy to an existing Servlet container via a WAR file. Creating a WAR file is as simple as executing the [war|commandLine] command: {code} -def deps = [ - "hibernate3.jar", - "groovy-all-*.jar", - "standard-\${servletVersion}.jar", - "jstl-\${servletVersion}.jar", - "oscache-*.jar", - "commons-logging-*.jar", - "sitemesh-*.jar", - "spring-*.jar", - "log4j-*.jar", - "ognl-*.jar", - "commons-*.jar", - "xstream-1.2.1.jar", - "xpp3_min-1.1.3.4.O.jar" ] - -grails.war.dependencies = { - fileset(dir: "libs") { - for (pattern in deps) { - include(name: pattern) - } - } -} +grails war {code} -This example only exists to demonstrate the syntax for the properties. If you attempt to use it as is in your own application, the application will probably not work. You can find a list of dependencies required by Grails in the "dependencies.txt" file in the root directory of the unpacked distribution. You can also find a list of the default dependencies included in WAR generation in the "War.groovy" script - see the @DEFAULT_DEPS@ and @DEFAULT_J5_DEPS@ variables. +This will produce a WAR file that can be deployed to a container in the @build/libs@ directory. -The remaining two configuration options available to you are @grails.war.copyToWebApp@ and @grails.war.resources@. The first of these lets you customise what files are included in the WAR file from the "web-app" directory. The second lets you do any extra processing you want before the WAR file is finally created. +Note that by default Grails will include an embeddable version of Tomcat inside the WAR file so that it is runnable (see the previous section), this can cause problems if you deploy to a different version of Tomcat. If you don't intend to use the embedded container then you should change the scope of the Tomcat dependencies to @provided@ prior to deploying to your production container in @build.gradle@: {code} -// This closure is passed the command line arguments used to start the -// war process. -grails.war.copyToWebApp = { args -> - fileset(dir:"web-app") { - include(name: "js/**") - include(name: "css/**") - include(name: "WEB-INF/**") - } -} - -// This closure is passed the location of the staging directory that -// is zipped up to make the WAR file, and the command line arguments. -// Here we override the standard web.xml with our own. -grails.war.resources = { stagingDir, args -> - copy(file: "grails-app/conf/custom-web.xml", - tofile: "\${stagingDir}/WEB-INF/web.xml") -} +provided "org.springframework.boot:spring-boot-starter-tomcat" {code} + h2. Application servers Ideally you should be able to simply drop a WAR file created by Grails into any application server and it should work straight away. However, things are rarely ever this simple. The [Grails website|http://grails.org/Deployment] contains a list of application servers that Grails has been tested with, along with any additional steps required to get a Grails WAR file working. diff --git a/src/en/guide/gettingStarted/deployingAnApplication.gdoc b/src/en/guide/gettingStarted/deployingAnApplication.gdoc index 6d91be0d3eb..176ff002f60 100644 --- a/src/en/guide/gettingStarted/deployingAnApplication.gdoc +++ b/src/en/guide/gettingStarted/deployingAnApplication.gdoc @@ -8,6 +8,12 @@ grails war This will produce a WAR file under the @build/libs@ directory which can then be deployed as per your container's instructions. +Note that by default Grails will include an embeddable version of Tomcat inside the WAR file, this can cause problems if you deploy to a different version of Tomcat. If you don't intend to use the embedded container then you should change the scope of the Tomcat dependencies to @provided@ prior to deploying to your production container in @build.gradle@: + +{code} +provided "org.springframework.boot:spring-boot-starter-tomcat" +{code} + Unlike most scripts which default to the @development@ environment unless overridden, the @war@ command runs in the @production@ environment by default. You can override this like any script by specifying the environment name, for example: {code} @@ -18,7 +24,7 @@ If you prefer not to operate a separate Servlet container then you can simply ru {code} grails war -java -Xmx768M -XX:MaxPermSize=256m -jar build/libs/mywar-0.1.war +java -Dgrails.env=prod -jar build/libs/mywar-0.1.war {code} From 02d52614dc52020b617e47ea76b3abb7eb0fd0eb Mon Sep 17 00:00:00 2001 From: graemerocher Date: Thu, 26 Mar 2015 14:01:27 +0100 Subject: [PATCH 118/230] Prepare 3.0.0.RC3 release --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index c74122e52a5..ecfddd086fa 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1 @@ -grails.version=3.0.0.RC2 +grails.version=3.0.0.RC3 From 7e424251ebd47cda26370d7f723ffab80618bba8 Mon Sep 17 00:00:00 2001 From: B5A7 Date: Fri, 27 Mar 2015 08:56:30 +1100 Subject: [PATCH 119/230] Qualify use of media-range Considered raising a Jira for this as I am not sure this is the best place for this note. The "Versioning REST resources" section might benefit from further expansion or, can we just reference another persons' work, e.g. http://barelyenough.org/blog/2008/05/versioning-rest-web-services/. I guess we do not want to full the grails manual with everything about web services. I was worried that the examples are not representative of actual practice. --- src/en/guide/webServices/REST/hypermedia/hal.gdoc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/en/guide/webServices/REST/hypermedia/hal.gdoc b/src/en/guide/webServices/REST/hypermedia/hal.gdoc index 5c4b07ce7c9..968920278c8 100644 --- a/src/en/guide/webServices/REST/hypermedia/hal.gdoc +++ b/src/en/guide/webServices/REST/hypermedia/hal.gdoc @@ -247,6 +247,10 @@ beans = { In the above example the first bean defines a HAL renderer for a single book instance that returns a Mime Type of @application/vnd.books.org.book+json@. The second bean defines the Mime Type used to render a collection of books (in this case @application/vnd.books.org.booklist+json@). +{note} +@application/vnd.books.org.booklist+json@ is an example of a media-range (http://www.w3.org/Protocols/rfc2616/rfc2616.html - Header Field Definitions). This example uses entity (book) and operation (list) to form the media-range values but in reality, it may not be necessary to create a separate Mime type for each operation. Further, it may not be necessary to create Mime types at the entity level. See the section on "Versioning REST resources" for further information about how to define your own Mime types. +{note} + With this in place issuing a request for the new Mime Type returns the necessary HAL: {code} From 9152bbcef9027b6a08387422411d1019e546ab19 Mon Sep 17 00:00:00 2001 From: graemerocher Date: Mon, 30 Mar 2015 13:26:41 +0200 Subject: [PATCH 120/230] Link to Spring / Groovy release notes --- src/en/guide/introduction/whatsNew/coreFeatures.gdoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/en/guide/introduction/whatsNew/coreFeatures.gdoc b/src/en/guide/introduction/whatsNew/coreFeatures.gdoc index 8161ab960c0..9f242637175 100644 --- a/src/en/guide/introduction/whatsNew/coreFeatures.gdoc +++ b/src/en/guide/introduction/whatsNew/coreFeatures.gdoc @@ -2,11 +2,11 @@ h4. Groovy 2.4 Grails 3.0 comes with Groovy 2.4 which includes many new features and enhancements. -For more information on Groovy 2.4, see the (TBD). +For more information on Groovy 2.4, see the [release notes|http://groovy-lang.org/releasenotes/groovy-2.4.html] for more information. h4. Spring 4.1 and Spring Boot 1.2 -Grails 3.0 comes with Spring 4.1 which includes many new features and enhancements. See the (TBD). +Grails 3.0 comes with Spring 4.1 which includes [many new features and enhancements|https://spring.io/blog/2014/09/04/spring-framework-4-1-ga-is-here]. In addition, Grails 3.0 is built on [Spring Boot 1.2|http://projects.spring.io/spring-boot/] which provides the ability to produce runnable JAR files that can embed Tomcat, Jetty or Undertow containers. From 378b8b58917d14f702be9944d29b56d3285263c7 Mon Sep 17 00:00:00 2001 From: Jeff Scott Brown Date: Mon, 30 Mar 2015 07:52:20 -0500 Subject: [PATCH 121/230] update download url --- src/en/guide/gettingStarted/downloadingAndInstalling.gdoc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/en/guide/gettingStarted/downloadingAndInstalling.gdoc b/src/en/guide/gettingStarted/downloadingAndInstalling.gdoc index 72fc663d573..b0e25bc6dd4 100644 --- a/src/en/guide/gettingStarted/downloadingAndInstalling.gdoc +++ b/src/en/guide/gettingStarted/downloadingAndInstalling.gdoc @@ -1,10 +1,10 @@ -The first step to getting up and running with Grails is to install the distribution. +The first step to getting up and running with Grails is to install the distribution. The best way to install Grails on *nix systems is with the [GVM tool|http://gvmtool.net] which greatly simplifies installing and managing multiple Grails versions. For manual installation follow these steps: -* "Download":http://grails.org/Download a binary distribution of Grails and extract the resulting zip file to a location of your choice +* "Download":https://github.com/grails/grails-core/releases a binary distribution of Grails and extract the resulting zip file to a location of your choice * Set the GRAILS_HOME environment variable to the location where you extracted the zip ** On Unix/Linux based systems this is typically a matter of adding something like the following @export GRAILS_HOME=/path/to/grails@ to your profile ** On Windows this is typically a matter of setting an environment variable under @My Computer/Advanced/Environment Variables@ @@ -16,4 +16,3 @@ If Grails is working correctly you should now be able to type @grails -version@ bc. Grails version: 3.0.0 - From e57633ff93520d5cf8951236ad9193f3c6187225 Mon Sep 17 00:00:00 2001 From: Graeme Rocher Date: Tue, 31 Mar 2015 10:44:43 +0200 Subject: [PATCH 122/230] Prepare 3.0 release --- build.gradle | 2 +- gradle.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 20b8a3ab17d..4323564b869 100644 --- a/build.gradle +++ b/build.gradle @@ -22,7 +22,7 @@ buildscript { } dependencies { - classpath "org.grails:grails-docs:3.0.0.RC2" + classpath "org.grails:grails-docs:3.0.0" classpath 'org.codehaus.groovy:groovy-all:2.4.0' } } diff --git a/gradle.properties b/gradle.properties index ecfddd086fa..3e6807160d0 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1 @@ -grails.version=3.0.0.RC3 +grails.version=3.0.0 From 5fe2e4eaa563f312e1bfead68adb801847ebda08 Mon Sep 17 00:00:00 2001 From: graemerocher Date: Tue, 31 Mar 2015 11:26:36 +0200 Subject: [PATCH 123/230] Publish latest docs --- travis-build.sh | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/travis-build.sh b/travis-build.sh index 45acd387aaa..cf9d5cc758c 100755 --- a/travis-build.sh +++ b/travis-build.sh @@ -12,39 +12,9 @@ export GRADLE_OPTS="-Xmx2048m -Xms256m -XX:MaxPermSize=512m -XX:+CMSClassUnloadi if [[ $TRAVIS_PULL_REQUEST == 'false' ]]; then - # If there is a tag present then this becomes the latest - if [[ -n $TRAVIS_TAG ]]; then - git clone https://${GH_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git -b gh-pages gh-pages --single-branch > /dev/null - cd gh-pages - - version="$TRAVIS_TAG" - version=${version:1} - zipName="grails-docs-$version" - export RELEASE_FILE="${zipName}.zip" - - milestone=${version:5} - if [[ -n $milestone ]]; then git rm -rf latest/ mkdir -p latest cp -r ../build/docs/. ./latest/ git add latest/* - fi - - majorVersion=${version:0:4} - majorVersion="${majorVersion}x" - - mkdir -p "$version" - cp -r ../build/docs/. "./$version/" - git add "$version/*" - - mkdir -p "$majorVersion" - cp -r ../build/docs/. "./$majorVersion/" - git add "$majorVersion/*" - git commit -a -m "Updating docs for Travis build: https://travis-ci.org/$TRAVIS_REPO_SLUG/builds/$TRAVIS_BUILD_ID" - git push origin HEAD - cd .. - rm -rf gh-pages - - fi fi From 20f29e133bfb344eceac503e76460834138d58da Mon Sep 17 00:00:00 2001 From: graemerocher Date: Tue, 31 Mar 2015 11:30:20 +0200 Subject: [PATCH 124/230] Revert changes --- travis-build.sh | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/travis-build.sh b/travis-build.sh index cf9d5cc758c..45acd387aaa 100755 --- a/travis-build.sh +++ b/travis-build.sh @@ -12,9 +12,39 @@ export GRADLE_OPTS="-Xmx2048m -Xms256m -XX:MaxPermSize=512m -XX:+CMSClassUnloadi if [[ $TRAVIS_PULL_REQUEST == 'false' ]]; then + # If there is a tag present then this becomes the latest + if [[ -n $TRAVIS_TAG ]]; then + git clone https://${GH_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git -b gh-pages gh-pages --single-branch > /dev/null + cd gh-pages + + version="$TRAVIS_TAG" + version=${version:1} + zipName="grails-docs-$version" + export RELEASE_FILE="${zipName}.zip" + + milestone=${version:5} + if [[ -n $milestone ]]; then git rm -rf latest/ mkdir -p latest cp -r ../build/docs/. ./latest/ git add latest/* + fi + + majorVersion=${version:0:4} + majorVersion="${majorVersion}x" + + mkdir -p "$version" + cp -r ../build/docs/. "./$version/" + git add "$version/*" + + mkdir -p "$majorVersion" + cp -r ../build/docs/. "./$majorVersion/" + git add "$majorVersion/*" + git commit -a -m "Updating docs for Travis build: https://travis-ci.org/$TRAVIS_REPO_SLUG/builds/$TRAVIS_BUILD_ID" + git push origin HEAD + cd .. + rm -rf gh-pages + + fi fi From 7fbe061cedc59ec1d0d627542f4c75a082839f34 Mon Sep 17 00:00:00 2001 From: graemerocher Date: Tue, 31 Mar 2015 11:37:42 +0200 Subject: [PATCH 125/230] Publish latest docs --- travis-build.sh | 43 ++++++------------------------------------- 1 file changed, 6 insertions(+), 37 deletions(-) diff --git a/travis-build.sh b/travis-build.sh index 45acd387aaa..384dfd208ea 100755 --- a/travis-build.sh +++ b/travis-build.sh @@ -9,42 +9,11 @@ echo "https://$GH_TOKEN:@github.com" > ~/.git-credentials export GRADLE_OPTS="-Xmx2048m -Xms256m -XX:MaxPermSize=512m -XX:+CMSClassUnloadingEnabled -XX:+HeapDumpOnOutOfMemoryError" ./gradlew assemble --info --stacktrace +git clone https://${GH_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git -b gh-pages gh-pages --single-branch > /dev/null +cd gh-pages -if [[ $TRAVIS_PULL_REQUEST == 'false' ]]; then +git rm -rf latest/ +mkdir -p latest +cp -r ../build/docs/. ./latest/ +git add latest/* - # If there is a tag present then this becomes the latest - if [[ -n $TRAVIS_TAG ]]; then - git clone https://${GH_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git -b gh-pages gh-pages --single-branch > /dev/null - cd gh-pages - - version="$TRAVIS_TAG" - version=${version:1} - zipName="grails-docs-$version" - export RELEASE_FILE="${zipName}.zip" - - milestone=${version:5} - if [[ -n $milestone ]]; then - git rm -rf latest/ - mkdir -p latest - cp -r ../build/docs/. ./latest/ - git add latest/* - fi - - majorVersion=${version:0:4} - majorVersion="${majorVersion}x" - - mkdir -p "$version" - cp -r ../build/docs/. "./$version/" - git add "$version/*" - - mkdir -p "$majorVersion" - cp -r ../build/docs/. "./$majorVersion/" - git add "$majorVersion/*" - git commit -a -m "Updating docs for Travis build: https://travis-ci.org/$TRAVIS_REPO_SLUG/builds/$TRAVIS_BUILD_ID" - git push origin HEAD - cd .. - rm -rf gh-pages - - fi - -fi From 28e404a50d84a2fa9618ee5261c39b441b1d2449 Mon Sep 17 00:00:00 2001 From: graemerocher Date: Tue, 31 Mar 2015 11:38:33 +0200 Subject: [PATCH 126/230] Publish latest docs --- travis-build.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/travis-build.sh b/travis-build.sh index 384dfd208ea..54f583abc7a 100755 --- a/travis-build.sh +++ b/travis-build.sh @@ -16,4 +16,6 @@ git rm -rf latest/ mkdir -p latest cp -r ../build/docs/. ./latest/ git add latest/* +git commit -a -m "Updating docs for Travis build: https://travis-ci.org/$TRAVIS_REPO_SLUG/builds/$TRAVIS_BUILD_ID" +git push origin HEAD From bafb56ff08ea309082487c589d5e2e7aa5d26dba Mon Sep 17 00:00:00 2001 From: graemerocher Date: Tue, 31 Mar 2015 11:55:53 +0200 Subject: [PATCH 127/230] Revert changes --- travis-build.sh | 45 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/travis-build.sh b/travis-build.sh index 54f583abc7a..45acd387aaa 100755 --- a/travis-build.sh +++ b/travis-build.sh @@ -9,13 +9,42 @@ echo "https://$GH_TOKEN:@github.com" > ~/.git-credentials export GRADLE_OPTS="-Xmx2048m -Xms256m -XX:MaxPermSize=512m -XX:+CMSClassUnloadingEnabled -XX:+HeapDumpOnOutOfMemoryError" ./gradlew assemble --info --stacktrace -git clone https://${GH_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git -b gh-pages gh-pages --single-branch > /dev/null -cd gh-pages -git rm -rf latest/ -mkdir -p latest -cp -r ../build/docs/. ./latest/ -git add latest/* -git commit -a -m "Updating docs for Travis build: https://travis-ci.org/$TRAVIS_REPO_SLUG/builds/$TRAVIS_BUILD_ID" -git push origin HEAD +if [[ $TRAVIS_PULL_REQUEST == 'false' ]]; then + # If there is a tag present then this becomes the latest + if [[ -n $TRAVIS_TAG ]]; then + git clone https://${GH_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git -b gh-pages gh-pages --single-branch > /dev/null + cd gh-pages + + version="$TRAVIS_TAG" + version=${version:1} + zipName="grails-docs-$version" + export RELEASE_FILE="${zipName}.zip" + + milestone=${version:5} + if [[ -n $milestone ]]; then + git rm -rf latest/ + mkdir -p latest + cp -r ../build/docs/. ./latest/ + git add latest/* + fi + + majorVersion=${version:0:4} + majorVersion="${majorVersion}x" + + mkdir -p "$version" + cp -r ../build/docs/. "./$version/" + git add "$version/*" + + mkdir -p "$majorVersion" + cp -r ../build/docs/. "./$majorVersion/" + git add "$majorVersion/*" + git commit -a -m "Updating docs for Travis build: https://travis-ci.org/$TRAVIS_REPO_SLUG/builds/$TRAVIS_BUILD_ID" + git push origin HEAD + cd .. + rm -rf gh-pages + + fi + +fi From d6709cb39b96a739fdf56ef4a0b6443cd51dde7c Mon Sep 17 00:00:00 2001 From: graemerocher Date: Thu, 2 Apr 2015 10:23:49 +0200 Subject: [PATCH 128/230] Release 3.0.1 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 3e6807160d0..217007dcbb4 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1 @@ -grails.version=3.0.0 +grails.version=3.0.1 From 97469fba8db2bc0664f4c434d6f7f9222969b40b Mon Sep 17 00:00:00 2001 From: graemerocher Date: Thu, 2 Apr 2015 10:24:12 +0200 Subject: [PATCH 129/230] Release 3.0.1 --- travis-build.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/travis-build.sh b/travis-build.sh index 45acd387aaa..0ea88f009f6 100755 --- a/travis-build.sh +++ b/travis-build.sh @@ -23,12 +23,12 @@ if [[ $TRAVIS_PULL_REQUEST == 'false' ]]; then export RELEASE_FILE="${zipName}.zip" milestone=${version:5} - if [[ -n $milestone ]]; then + # if [[ -n $milestone ]]; then git rm -rf latest/ mkdir -p latest cp -r ../build/docs/. ./latest/ git add latest/* - fi + # fi majorVersion=${version:0:4} majorVersion="${majorVersion}x" From ab8cfad5da90ff3a460336abc69f2f9a1ddceba4 Mon Sep 17 00:00:00 2001 From: houbie Date: Sat, 4 Apr 2015 00:27:34 +0200 Subject: [PATCH 130/230] fix docs for hibernate second-level cache --- .../GORM/advancedGORMFeatures/ormdsl/caching.gdoc | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/en/guide/GORM/advancedGORMFeatures/ormdsl/caching.gdoc b/src/en/guide/GORM/advancedGORMFeatures/ormdsl/caching.gdoc index 6fb7d15e1be..e642102b06c 100644 --- a/src/en/guide/GORM/advancedGORMFeatures/ormdsl/caching.gdoc +++ b/src/en/guide/GORM/advancedGORMFeatures/ormdsl/caching.gdoc @@ -1,13 +1,14 @@ h4. Setting up caching -"Hibernate":http://www.hibernate.org/ features a second-level cache with a customizable cache provider. This needs to be configured in the @grails-app/conf/DataSource.groovy@ file as follows: +"Hibernate":http://www.hibernate.org/ features a second-level cache with a customizable cache provider. This needs to be configured in the @grails-app/conf/application.yml@ file as follows: -{code:java} -hibernate { - cache.use_second_level_cache=true - cache.use_query_cache=true - cache.provider_class='org.hibernate.cache.EhCacheProvider' -} +{code} +hibernate: + cache: + use_second_level_cache: true + provider_class: net.sf.ehcache.hibernate.EhCacheProvider + region: + factory_class: org.hibernate.cache.ehcache.EhCacheRegionFactory {code} You can customize any of these settings, for example to use a distributed caching mechanism. From d9a55891c40e19b589c3f1030530341872941d09 Mon Sep 17 00:00:00 2001 From: Jeff Scott Brown Date: Sat, 4 Apr 2015 19:45:47 -0500 Subject: [PATCH 131/230] update scaffolding notes --- src/en/guide/scaffolding.gdoc | 88 ++--------------------------------- 1 file changed, 5 insertions(+), 83 deletions(-) diff --git a/src/en/guide/scaffolding.gdoc b/src/en/guide/scaffolding.gdoc index 65cbccefed5..4574414c55a 100644 --- a/src/en/guide/scaffolding.gdoc +++ b/src/en/guide/scaffolding.gdoc @@ -3,98 +3,20 @@ Scaffolding lets you generate some basic CRUD interfaces for a domain class, inc * The necessary [views|guide:gsp] * Controller actions for create/read/update/delete (CRUD) operations -As of Grails 2.3, the scaffolding feature has been moved to a plugin. By default this is configured for installation in new applications, but if you are upgrading from a previous version of Grails you will need to add the following configuration to your @BuildConfig.groovy@ file: +The way for an application to express a dependency on the scaffolding plugin is by including the following in @build.gradle@. {code} - plugins { - ... - compile "\:scaffolding:2.0.0" - ... - } -{code} - -Version 1.0.0 of the plugin provides the same scaffolding seen in Grails 2.2.x and below. Version 2.0.x of the scaffolding plugin includes different scaffolding templates that are aligned with the new REST APIs introduced in Grails 2.3 and above. - -h4. Dynamic Scaffolding - -The simplest way to get started with scaffolding is to enable it with the @scaffold@ property. Set the @scaffold@ property in the controller to @true@ for the @Book@ domain class: - -{code:java} -class BookController { - static scaffold = true -} -{code} - -This works because the @BookController@ follows the same naming convention as the @Book@ domain class. To scaffold a specific domain class we could reference the class directly in the scaffold property: - -{code:java} -class SomeController { - static scaffold = Author -} -{code} - -With this configured, when you start your application the actions and views will be auto-generated at runtime. The following actions are dynamically implemented by default by the runtime scaffolding mechanism: - -* index -* show -* edit -* delete -* create -* save -* update - -A CRUD interface will also be generated. To access this open @http://localhost:8080/app/book@ in a browser. + dependencies { -If you prefer to keep your domain model in Java and [mapped with Hibernate|guide:hibernate] you can still use scaffolding, simply import the domain class and set its name as the @scaffold@ argument. + // ... -You can add new actions to a scaffolded controller, for example: + runtime "org.grails.plugins:scaffolding" -{code:java} -class BookController { - - static scaffold = Book - - def changeAuthor() { - def b = Book.get(params.id) - b.author = Author.get(params["author.id"]) - b.save() + // ... - // redirect to a scaffolded action - redirect(action:show) } -} {code} -You can also override the scaffolded actions: - -{code:java} -class BookController { - - static scaffold = Book - - // overrides scaffolded action to return both authors and books - def index() { - [bookInstanceList: Book.list(), - bookInstanceTotal: Book.count(), - authorInstanceList: Author.list()] - } - - def show() { - def book = Book.get(params.id) - log.error(book) - [bookInstance : book] - } -} -{code} - -All of this is what is known as "dynamic scaffolding" where the CRUD interface is generated dynamically at runtime. - -{note} -By default, the size of text areas in scaffolded views is defined in the CSS, so adding 'rows' and 'cols' attributes will have no effect. - -Also, the standard scaffold views expect model variables of the form @InstanceList@ for collections and @Instance@ for single instances. It's tempting to use properties like 'books' and 'book', but those won't work. -{note} - h4. Customizing the Generated Views The views adapt to [Validation constraints|guide:constraints]. For example you can change the order that fields appear in the views simply by re-ordering the constraints in the builder: From 966d55ae98348a7201ffddc2ed8699d5c038aae7 Mon Sep 17 00:00:00 2001 From: Larry Battle Date: Wed, 8 Apr 2015 14:01:05 -0500 Subject: [PATCH 132/230] Fixed small typo --- src/en/guide/webServices/REST/hypermedia.gdoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/en/guide/webServices/REST/hypermedia.gdoc b/src/en/guide/webServices/REST/hypermedia.gdoc index f58ec758ec6..13d1390b3c9 100644 --- a/src/en/guide/webServices/REST/hypermedia.gdoc +++ b/src/en/guide/webServices/REST/hypermedia.gdoc @@ -1,3 +1,3 @@ -[HATEOS|http://en.wikipedia.org/wiki/HATEOAS], an abbreviation for Hypermedia as the Engine of Application State, is a common pattern applied to REST architectures that uses hypermedia and linking to define the REST API. +[HATEOAS|http://en.wikipedia.org/wiki/HATEOAS], an abbreviation for Hypermedia as the Engine of Application State, is a common pattern applied to REST architectures that uses hypermedia and linking to define the REST API. -Hypermedia (also called Mime or Media Types) are used to describe the state of a REST resource, and links tell clients how to transition to the next state. The format of the response is typically JSON or XML, although standard formats such as [Atom|http://tools.ietf.org/html/rfc4287] and/or [HAL|http://stateless.co/hal_specification.html] are frequently used. \ No newline at end of file +Hypermedia (also called Mime or Media Types) are used to describe the state of a REST resource, and links tell clients how to transition to the next state. The format of the response is typically JSON or XML, although standard formats such as [Atom|http://tools.ietf.org/html/rfc4287] and/or [HAL|http://stateless.co/hal_specification.html] are frequently used. From d9379abfbffb0e5b948b72e74f69c78e1bd2d881 Mon Sep 17 00:00:00 2001 From: Ken Geis Date: Mon, 13 Apr 2015 15:41:45 -0700 Subject: [PATCH 133/230] Update request.gdoc --- src/en/ref/Servlet API/request.gdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/en/ref/Servlet API/request.gdoc b/src/en/ref/Servlet API/request.gdoc index 98431696275..758ee478371 100644 --- a/src/en/ref/Servlet API/request.gdoc +++ b/src/en/ref/Servlet API/request.gdoc @@ -24,7 +24,7 @@ Grails enhances the @HttpServletRequest@ instance by adding the following new pr * @XML@ - An instance of @XmlSlurper@'s [GPathResult|http://groovy.codehaus.org/api/groovy/util/slurpersupport/GPathResult.html] class that allows parsing of an incoming XML request (useful for REST). * @JSON@ - An instance of Grails' [JSONObject|api:org.codehaus.groovy.grails.web.json.JSONObject] class that allows parsing of an incoming JSON request (useful for JSON based REST). -* @forwardURI@ - Useful for obtaining the current request URI since the @request@ objects @requestURI@ property returns the original URI, not the matched one. +* @forwardURI@ - Useful for obtaining the current request URI since the @request@ object's @requestURI@ property returns the original URI, not the matched one. * @isRedirected()@ - Returns @true@ if a redirect has been issued for this request (Grails 2+). * @get@ - Returns true if the current request is an HTTP @GET@ request. * @post@ - Returns true if the current request is an HTTP @POST@ request. From 46e2e2efda1ce35f1f3035af60c0812c9b37b8a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=20Garc=C3=ADa?= Date: Wed, 22 Apr 2015 17:29:58 +0100 Subject: [PATCH 134/230] Fixing problem with TimeZone link in formatDate tag formatDate tag has a wrong link to TimeZone class api doc. --- src/en/ref/Tags/formatDate.gdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/en/ref/Tags/formatDate.gdoc b/src/en/ref/Tags/formatDate.gdoc index ead44b2dd39..9795d618816 100644 --- a/src/en/ref/Tags/formatDate.gdoc +++ b/src/en/ref/Tags/formatDate.gdoc @@ -30,7 +30,7 @@ Attributes * @format@ (optional) - The formatting pattern to use for the date, see [SimpleDateFormat|api:java.text.SimpleDateFormat] * @formatName@ (optional) - Look up @format@ from the default MessageSource / ResourceBundle (i18n/*.properties file) with this key. If @format@ and @formatName@ are empty, @format@ is looked up with '@default.date.format@' key. Defaults to 'yyyy-MM-dd HH:mm:ss z' if the key not specified * @type@ (optional) - The type of format to use for the date / time. @format@ or @formatName@ aren't used when @type@ is specified. Possible values: 'date' - shows only date part, 'time' - shows only time part, 'both'/'datetime' - shows date and time -* @timeZone@ (optional) - Sets the time zone for formatting. See [TimeZone|api:java.util.SimpleDateFormat] class. +* @timeZone@ (optional) - Sets the time zone for formatting. See [TimeZone|api:java.util.TimeZone] class. * @locale@ (optional) - Force the locale for formatting. * @style@ (optional) - Use default date/time formatting of the country specified by the locale. Possible values: SHORT (default), MEDIUM, LONG, FULL . See [DateFormat|api:java.text.DateFormat] for explanation. * @dateStyle@ (optional) - Set separate @style@ for the date part. From 01f537c180e5882907a4274cd173a80ae0eff214 Mon Sep 17 00:00:00 2001 From: Jeff Scott Brown Date: Mon, 4 May 2015 09:13:19 -0500 Subject: [PATCH 135/230] More updates to scaffolding docs --- src/en/guide/scaffolding.gdoc | 54 +++++++++++++++++------------------ 1 file changed, 26 insertions(+), 28 deletions(-) diff --git a/src/en/guide/scaffolding.gdoc b/src/en/guide/scaffolding.gdoc index 4574414c55a..72ffb4d3b93 100644 --- a/src/en/guide/scaffolding.gdoc +++ b/src/en/guide/scaffolding.gdoc @@ -17,6 +17,32 @@ The way for an application to express a dependency on the scaffolding plugin is } {code} +h4. Static Scaffolding + +Grails lets you generate a controller and the views used to create the above interface from the command line. To generate a controller type: + +{code:java} +grails generate-controller Book +{code} + +or to generate the views: + +{code:java} +grails generate-views Book +{code} + +or to generate everything: + +{code:java} +grails generate-all Book +{code} + +If you have a domain class in a package or are generating from a [Hibernate mapped class|guide:hibernate] remember to include the fully qualified package name: + +{code:java} +grails generate-all com.bookstore.Book +{code} + h4. Customizing the Generated Views The views adapt to [Validation constraints|guide:constraints]. For example you can change the order that fields appear in the views simply by re-ordering the constraints in the builder: @@ -54,34 +80,6 @@ def constraints = { } {code} -h4. Static Scaffolding - -Grails also supports "static" scaffolding. - -The above scaffolding features are useful but in real world situations it's likely that you will want to customize the logic and views. Grails lets you generate a controller and the views used to create the above interface from the command line. To generate a controller type: - -{code:java} -grails generate-controller Book -{code} - -or to generate the views: - -{code:java} -grails generate-views Book -{code} - -or to generate everything: - -{code:java} -grails generate-all Book -{code} - -If you have a domain class in a package or are generating from a [Hibernate mapped class|guide:hibernate] remember to include the fully qualified package name: - -{code:java} -grails generate-all com.bookstore.Book -{code} - h4. Customizing the Scaffolding templates The templates used by Grails to generate the controller and views can be customized by installing the templates with the [install-templates|commandLine] command. From 4e8d60f4894114f3180f8feff41ebc7ecfc70707 Mon Sep 17 00:00:00 2001 From: Jeff Scott Brown Date: Tue, 5 May 2015 18:05:22 -0500 Subject: [PATCH 136/230] update default date formats --- src/en/guide/theWebLayer/controllers/dataBinding.gdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/en/guide/theWebLayer/controllers/dataBinding.gdoc b/src/en/guide/theWebLayer/controllers/dataBinding.gdoc index b2c08e5c3ca..cb3e2ce2136 100644 --- a/src/en/guide/theWebLayer/controllers/dataBinding.gdoc +++ b/src/en/guide/theWebLayer/controllers/dataBinding.gdoc @@ -574,7 +574,7 @@ grails.databinding.dateFormats = ['MMddyyyy', 'yyyy-MM-dd HH:mm:ss.S', "yyyy-MM- The formats specified in @grails.databinding.dateFormats@ will be attempted in the order in which they are included in the List. If a property is marked with \@BindingFormat, the \@BindingFormat will take precedence over the values specified in @grails.databinding.dateFormats@. -The default formats that are used are "yyyy-MM-dd HH:mm:ss.S" and "yyyy-MM-dd'T'hh:mm:ss'Z'". +The default formats that are used are "yyyy-MM-dd HH:mm:ss.S", "yyyy-MM-dd'T'hh:mm:ss'Z'" and "yyyy-MM-dd HH:mm:ss.S z". h4. Custom Formatted Converters From 4d0da7cae059d26d019697a4d7805d81a53c45e7 Mon Sep 17 00:00:00 2001 From: Erik Pragt Date: Mon, 25 May 2015 18:09:43 +0200 Subject: [PATCH 137/230] Added documentation about Flags for generate-all and generate-controller --- src/en/ref/Command Line/generate-all.gdoc | 5 +++++ src/en/ref/Command Line/generate-controller.gdoc | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/src/en/ref/Command Line/generate-all.gdoc b/src/en/ref/Command Line/generate-all.gdoc index c166ac6a2a2..3ee53c01844 100644 --- a/src/en/ref/Command Line/generate-all.gdoc +++ b/src/en/ref/Command Line/generate-all.gdoc @@ -31,3 +31,8 @@ Fired Events: Arguments: * @name@ - Either a domain class name (case-sensitive) or a wildcard (\*). If you specify the wildcard then controllers and views will be generated for _all_ domain classes. + +Flags: + +* @force@ - Whether to overwrite existing files + diff --git a/src/en/ref/Command Line/generate-controller.gdoc b/src/en/ref/Command Line/generate-controller.gdoc index c756bd2a1ba..789b5524671 100644 --- a/src/en/ref/Command Line/generate-controller.gdoc +++ b/src/en/ref/Command Line/generate-controller.gdoc @@ -31,3 +31,7 @@ Fired Events: Arguments: * @domain class name@ - Either a domain class name (case-sensitive) or a wildcard (\*). If you specify the wildcard controllers will be generated for _all_ domain classes. + +Flags: + +* @force@ - Whether to overwrite existing files From 367c80751ff92c091de345d36ce8cad91c612c9e Mon Sep 17 00:00:00 2001 From: Danny Date: Wed, 3 Jun 2015 11:24:51 -0400 Subject: [PATCH 138/230] Making indent length consistent Hello from GR8Conf EU --- src/en/guide/testing/functionalTesting.gdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/en/guide/testing/functionalTesting.gdoc b/src/en/guide/testing/functionalTesting.gdoc index 6a63607cef0..bc90bb95e82 100644 --- a/src/en/guide/testing/functionalTesting.gdoc +++ b/src/en/guide/testing/functionalTesting.gdoc @@ -23,7 +23,7 @@ class HomeSpec extends GebSpec { go '/' then:"The title is correct" - \$('title').text() == "Welcome to Grails" + \$('title').text() == "Welcome to Grails" } } From 8dc60f84ea7083004d366626a3ff31767bcf08c4 Mon Sep 17 00:00:00 2001 From: Dem Pilafian Date: Fri, 5 Jun 2015 21:30:23 -0700 Subject: [PATCH 139/230] References to "create-tag-lib" command updated to "create-taglib" for Grails 3.0 --- src/en/ref/Command Line/create-tag-lib.gdoc | 12 ++++++------ src/en/ref/Tag Libraries.gdoc | 4 ++-- src/es/guide/commandLine/antAndMaven.gdoc | 8 ++++---- src/es/ref/Command Line/create-tag-lib.gdoc | 8 ++++---- src/es/ref/Tag Libraries.gdoc | 4 ++-- src/fr/guide/commandLine/antAndMaven.gdoc | 2 +- src/fr/ref/Command Line/create-tag-lib.gdoc | 8 ++++---- src/fr/ref/Tag Libraries.gdoc | 4 ++-- src/pt_BR/ref/Tag Libraries.gdoc | 8 ++++---- src/pt_PT/guide/commandLine/antAndMaven.gdoc | 4 ++-- src/pt_PT/ref/Command Line/create-tag-lib.gdoc | 8 ++++---- src/pt_PT/ref/Tag Libraries.gdoc | 4 ++-- src/th/guide/commandLine/antAndMaven.gdoc | 2 +- src/th/ref/Command Line/create-tag-lib.gdoc | 8 ++++---- src/th/ref/Tag Libraries.gdoc | 4 ++-- src/zh_CN/guide/commandLine/antAndMaven.gdoc | 2 +- src/zh_CN/ref/Command Line/create-tag-lib.gdoc | 8 ++++---- src/zh_CN/ref/Tag Libraries.gdoc | 4 ++-- src/zh_TW/guide/commandLine/antAndMaven.gdoc | 2 +- src/zh_TW/ref/Command Line/create-tag-lib.gdoc | 8 ++++---- src/zh_TW/ref/Tag Libraries.gdoc | 4 ++-- 21 files changed, 58 insertions(+), 58 deletions(-) diff --git a/src/en/ref/Command Line/create-tag-lib.gdoc b/src/en/ref/Command Line/create-tag-lib.gdoc index ad068464d69..bb801dce0e0 100644 --- a/src/en/ref/Command Line/create-tag-lib.gdoc +++ b/src/en/ref/Command Line/create-tag-lib.gdoc @@ -1,15 +1,15 @@ -h1. create-tag-lib +h1. create-taglib h2. Purpose -The @create-tag-lib@ command creates a tag library and associated unit test for the given base name. +The @create-taglib@ command creates a tag library and associated unit test for the given base name. h2. Examples {code:java} -grails create-tag-lib -grails create-tag-lib book -grails create-tag-lib org.bookstore.Book +grails create-taglib +grails create-taglib book +grails create-taglib org.bookstore.Book {code} h2. Description @@ -26,7 +26,7 @@ Note that this command is just for convenience and you can also create tag libs Usage: {code:java} -grails create-tag-lib [name] +grails create-taglib [name] {code} Fired Events: diff --git a/src/en/ref/Tag Libraries.gdoc b/src/en/ref/Tag Libraries.gdoc index f02a7d180d4..5db726cc8cc 100644 --- a/src/en/ref/Tag Libraries.gdoc +++ b/src/en/ref/Tag Libraries.gdoc @@ -1,9 +1,9 @@ h1. Tag Library Usage -A tag library fulfills role of "view helper" in the Model View Controller (MVC) pattern and helps with GSP rendering. In Grails a tag library is a class with a name that ends in the convention "TagLib" and lives in the @grails-app/taglib@ directory. Use the [create-tag-lib|commandLine] command create a tag library: +A tag library fulfills role of "view helper" in the Model View Controller (MVC) pattern and helps with GSP rendering. In Grails a tag library is a class with a name that ends in the convention "TagLib" and lives in the @grails-app/taglib@ directory. Use the [create-taglib|commandLine] command create a tag library: {code:java} -grails create-tag-lib format +grails create-taglib format {code} or with your favourite IDE or text editor. diff --git a/src/es/guide/commandLine/antAndMaven.gdoc b/src/es/guide/commandLine/antAndMaven.gdoc index 7a76d006847..086e3131470 100644 --- a/src/es/guide/commandLine/antAndMaven.gdoc +++ b/src/es/guide/commandLine/antAndMaven.gdoc @@ -191,7 +191,7 @@ to {code} {hidden} -h4. Creación de un proyecto Grails con Maven +h4. Creación de un proyecto Grails con Maven Para crear un proyecto Grails "mavenizado" sólo tiene que ejecutar el siguiente comando: @@ -203,7 +203,7 @@ mvn archetype: generate-DarchetypeGroupId org.grails = \ \ \ {code} Elija la versión de Grails que desee, el identificador de grupo y la identificación de artefactos que desee para su aplicación, pero todo lo demás debe ser escrito como está. Esto creará un nuevo proyecto de Maven con un POM y un otro par de ficheros. Lo que no verá es nada que se parezca a una aplicación Grails. Por lo tanto, el siguiente paso es crear la estructura del proyecto que estamos acostumbrados. -Pero primero, para establecer objetivos JDK de Java 6, hagalo ahora. Abra el fichero my-app/pom.xml y modifiquelo: +Pero primero, para establecer objetivos JDK de Java 6, hagalo ahora. Abra el fichero my-app/pom.xml y modifiquelo: {code} @@ -303,7 +303,7 @@ You can also use some of the Grails commands that have been wrapped as Maven goa * @grails:create-pom@ - Creates a new Maven POM for an existing Grails project * @grails:create-script@ - Calls the [create-script|commandLine] command * @grails:create-service@ - Calls the [create-service|commandLine] command -* @grails:create-taglib@ - Calls the [create-tag-lib|commandLine] command +* @grails:create-taglib@ - Calls the [create-taglib|commandLine] command * @grails:create-unit-test@ - Calls the [create-unit-test|commandLine] command * @grails:exec@ - Executes an arbitrary Grails command line script * @grails:generate-all@ - Calls the [generate-all|commandLine] command @@ -329,7 +329,7 @@ También puede utilizar algunos de los comandos de Grails que se han creado como * @grails:create-pom@ - Crea un nuevo POM para un proyecto Grails existente. * @grails:create-script@ - Invoca el comando [create-script|commandLine] * @grails:create-service@ - Invoca el comando [create-service|commandLine] -* @grails:create-taglib@ - Invoca el comando [create-tag-lib|commandLine] +* @grails:create-taglib@ - Invoca el comando [create-taglib|commandLine] * @grails:create-unit-test@ - Invoca el comando [create-unit-test|commandLine] * @grails:exec@ - Invoca un script de grails. * @grails:generate-all@ - ] Invoca el comando [generate-all|commandLine] diff --git a/src/es/ref/Command Line/create-tag-lib.gdoc b/src/es/ref/Command Line/create-tag-lib.gdoc index e50e6aa952b..f6375293d29 100644 --- a/src/es/ref/Command Line/create-tag-lib.gdoc +++ b/src/es/ref/Command Line/create-tag-lib.gdoc @@ -1,13 +1,13 @@ -h1. create-tag-lib +h1. create-taglib h2. Purpose -The @create-tag-lib@ command creates a tag library and associated unit test for the given base name. +The @create-taglib@ command creates a tag library and associated unit test for the given base name. h2. Examples {code:java} -grails create-tag-lib org.bookstore.book +grails create-taglib org.bookstore.book {code} h2. Description @@ -22,7 +22,7 @@ Note that this command is just for convenience and you can also create controlle Usage: {code:java} -grails create-tag-lib [name] +grails create-taglib [name] {code} Fired Events: diff --git a/src/es/ref/Tag Libraries.gdoc b/src/es/ref/Tag Libraries.gdoc index f02a7d180d4..5db726cc8cc 100644 --- a/src/es/ref/Tag Libraries.gdoc +++ b/src/es/ref/Tag Libraries.gdoc @@ -1,9 +1,9 @@ h1. Tag Library Usage -A tag library fulfills role of "view helper" in the Model View Controller (MVC) pattern and helps with GSP rendering. In Grails a tag library is a class with a name that ends in the convention "TagLib" and lives in the @grails-app/taglib@ directory. Use the [create-tag-lib|commandLine] command create a tag library: +A tag library fulfills role of "view helper" in the Model View Controller (MVC) pattern and helps with GSP rendering. In Grails a tag library is a class with a name that ends in the convention "TagLib" and lives in the @grails-app/taglib@ directory. Use the [create-taglib|commandLine] command create a tag library: {code:java} -grails create-tag-lib format +grails create-taglib format {code} or with your favourite IDE or text editor. diff --git a/src/fr/guide/commandLine/antAndMaven.gdoc b/src/fr/guide/commandLine/antAndMaven.gdoc index 76067c100f5..5a45d4ba5ed 100644 --- a/src/fr/guide/commandLine/antAndMaven.gdoc +++ b/src/fr/guide/commandLine/antAndMaven.gdoc @@ -145,7 +145,7 @@ You can also use some of the Grails commands that have been wrapped as Maven goa * @grails:create-pom@ - Creates a new Maven POM for an existing Grails project * @grails:create-script@ - Calls the [create-script|commandLine] command * @grails:create-service@ - Calls the [create-service|commandLine] command -* @grails:create-taglib@ - Calls the [create-tag-lib|commandLine] command +* @grails:create-taglib@ - Calls the [create-taglib|commandLine] command * @grails:create-unit-test@ - Calls the [create-unit-test|commandLine] command * @grails:exec@ - Executes an arbitrary Grails command line script * @grails:generate-all@ - Calls the [generate-all|commandLine] command diff --git a/src/fr/ref/Command Line/create-tag-lib.gdoc b/src/fr/ref/Command Line/create-tag-lib.gdoc index e50e6aa952b..f6375293d29 100644 --- a/src/fr/ref/Command Line/create-tag-lib.gdoc +++ b/src/fr/ref/Command Line/create-tag-lib.gdoc @@ -1,13 +1,13 @@ -h1. create-tag-lib +h1. create-taglib h2. Purpose -The @create-tag-lib@ command creates a tag library and associated unit test for the given base name. +The @create-taglib@ command creates a tag library and associated unit test for the given base name. h2. Examples {code:java} -grails create-tag-lib org.bookstore.book +grails create-taglib org.bookstore.book {code} h2. Description @@ -22,7 +22,7 @@ Note that this command is just for convenience and you can also create controlle Usage: {code:java} -grails create-tag-lib [name] +grails create-taglib [name] {code} Fired Events: diff --git a/src/fr/ref/Tag Libraries.gdoc b/src/fr/ref/Tag Libraries.gdoc index f02a7d180d4..5db726cc8cc 100644 --- a/src/fr/ref/Tag Libraries.gdoc +++ b/src/fr/ref/Tag Libraries.gdoc @@ -1,9 +1,9 @@ h1. Tag Library Usage -A tag library fulfills role of "view helper" in the Model View Controller (MVC) pattern and helps with GSP rendering. In Grails a tag library is a class with a name that ends in the convention "TagLib" and lives in the @grails-app/taglib@ directory. Use the [create-tag-lib|commandLine] command create a tag library: +A tag library fulfills role of "view helper" in the Model View Controller (MVC) pattern and helps with GSP rendering. In Grails a tag library is a class with a name that ends in the convention "TagLib" and lives in the @grails-app/taglib@ directory. Use the [create-taglib|commandLine] command create a tag library: {code:java} -grails create-tag-lib format +grails create-taglib format {code} or with your favourite IDE or text editor. diff --git a/src/pt_BR/ref/Tag Libraries.gdoc b/src/pt_BR/ref/Tag Libraries.gdoc index b10220d34d8..f9abb559611 100644 --- a/src/pt_BR/ref/Tag Libraries.gdoc +++ b/src/pt_BR/ref/Tag Libraries.gdoc @@ -1,10 +1,10 @@ {hidden} h1. Tag Library Usage -A tag library fulfills role of "view helper" in the Model View Controller (MVC) pattern and helps with GSP rendering. In Grails a tag library is a class with a name that ends in the convention "TagLib" and lives in the @grails-app/taglib@ directory. Use the [create-tag-lib|commandLine] command create a tag library: +A tag library fulfills role of "view helper" in the Model View Controller (MVC) pattern and helps with GSP rendering. In Grails a tag library is a class with a name that ends in the convention "TagLib" and lives in the @grails-app/taglib@ directory. Use the [create-taglib|commandLine] command create a tag library: {code:java} -grails create-tag-lib format +grails create-taglib format {code} or with your favourite IDE or text editor. @@ -28,10 +28,10 @@ h1. Uso das TagLibs Uma taglib atende pela camada "view helper" no padrão Model View Controller e tem o propósito de ajudar na renderização das páginas GSPs. -Uma taglib obedeçe a convenção de ter seu nome terminado em TagLib e deve estar na pasta @grails-app/taglib@. Use o comando [create-tag-lib|commandLine] para criar uma taglib: +Uma taglib obedeçe a convenção de ter seu nome terminado em TagLib e deve estar na pasta @grails-app/taglib@. Use o comando [create-taglib|commandLine] para criar uma taglib: {code:java} -grails create-tag-lib format +grails create-taglib format {code} ou use seu editor de texto preferido ou IDE: diff --git a/src/pt_PT/guide/commandLine/antAndMaven.gdoc b/src/pt_PT/guide/commandLine/antAndMaven.gdoc index 5cf2c9efb76..778d7a00388 100644 --- a/src/pt_PT/guide/commandLine/antAndMaven.gdoc +++ b/src/pt_PT/guide/commandLine/antAndMaven.gdoc @@ -242,7 +242,7 @@ You can also use some of the Grails commands that have been wrapped as Maven goa * @grails:create-pom@ - Creates a new Maven POM for an existing Grails project * @grails:create-script@ - Calls the [create-script|commandLine] command * @grails:create-service@ - Calls the [create-service|commandLine] command -* @grails:create-taglib@ - Calls the [create-tag-lib|commandLine] command +* @grails:create-taglib@ - Calls the [create-taglib|commandLine] command * @grails:create-unit-test@ - Calls the [create-unit-test|commandLine] command * @grails:exec@ - Executes an arbitrary Grails command line script * @grails:generate-all@ - Calls the [generate-all|commandLine] command @@ -264,7 +264,7 @@ Também pode utiizar alguns dos comandos Grails que foram embrulhados como metas * @grails:create-pom@ - Cria um novo POM Maven para um projeto Grails existente * @grails:create-script@ - Chama o comando [create-script|commandLine] * @grails:create-service@ - Chama o comando [create-service|commandLine] -* @grails:create-taglib@ - Chama o comando [create-tag-lib|commandLine] +* @grails:create-taglib@ - Chama o comando [create-taglib|commandLine] * @grails:create-unit-test@ - Chama o comando [create-unit-test|commandLine] * @grails:exec@ - Executa um script de linha de comando Grails arbitrário * @grails:generate-all@ - Chama o comando [generate-all|commandLine] diff --git a/src/pt_PT/ref/Command Line/create-tag-lib.gdoc b/src/pt_PT/ref/Command Line/create-tag-lib.gdoc index e50e6aa952b..f6375293d29 100644 --- a/src/pt_PT/ref/Command Line/create-tag-lib.gdoc +++ b/src/pt_PT/ref/Command Line/create-tag-lib.gdoc @@ -1,13 +1,13 @@ -h1. create-tag-lib +h1. create-taglib h2. Purpose -The @create-tag-lib@ command creates a tag library and associated unit test for the given base name. +The @create-taglib@ command creates a tag library and associated unit test for the given base name. h2. Examples {code:java} -grails create-tag-lib org.bookstore.book +grails create-taglib org.bookstore.book {code} h2. Description @@ -22,7 +22,7 @@ Note that this command is just for convenience and you can also create controlle Usage: {code:java} -grails create-tag-lib [name] +grails create-taglib [name] {code} Fired Events: diff --git a/src/pt_PT/ref/Tag Libraries.gdoc b/src/pt_PT/ref/Tag Libraries.gdoc index f02a7d180d4..5db726cc8cc 100644 --- a/src/pt_PT/ref/Tag Libraries.gdoc +++ b/src/pt_PT/ref/Tag Libraries.gdoc @@ -1,9 +1,9 @@ h1. Tag Library Usage -A tag library fulfills role of "view helper" in the Model View Controller (MVC) pattern and helps with GSP rendering. In Grails a tag library is a class with a name that ends in the convention "TagLib" and lives in the @grails-app/taglib@ directory. Use the [create-tag-lib|commandLine] command create a tag library: +A tag library fulfills role of "view helper" in the Model View Controller (MVC) pattern and helps with GSP rendering. In Grails a tag library is a class with a name that ends in the convention "TagLib" and lives in the @grails-app/taglib@ directory. Use the [create-taglib|commandLine] command create a tag library: {code:java} -grails create-tag-lib format +grails create-taglib format {code} or with your favourite IDE or text editor. diff --git a/src/th/guide/commandLine/antAndMaven.gdoc b/src/th/guide/commandLine/antAndMaven.gdoc index 76067c100f5..5a45d4ba5ed 100644 --- a/src/th/guide/commandLine/antAndMaven.gdoc +++ b/src/th/guide/commandLine/antAndMaven.gdoc @@ -145,7 +145,7 @@ You can also use some of the Grails commands that have been wrapped as Maven goa * @grails:create-pom@ - Creates a new Maven POM for an existing Grails project * @grails:create-script@ - Calls the [create-script|commandLine] command * @grails:create-service@ - Calls the [create-service|commandLine] command -* @grails:create-taglib@ - Calls the [create-tag-lib|commandLine] command +* @grails:create-taglib@ - Calls the [create-taglib|commandLine] command * @grails:create-unit-test@ - Calls the [create-unit-test|commandLine] command * @grails:exec@ - Executes an arbitrary Grails command line script * @grails:generate-all@ - Calls the [generate-all|commandLine] command diff --git a/src/th/ref/Command Line/create-tag-lib.gdoc b/src/th/ref/Command Line/create-tag-lib.gdoc index e50e6aa952b..f6375293d29 100644 --- a/src/th/ref/Command Line/create-tag-lib.gdoc +++ b/src/th/ref/Command Line/create-tag-lib.gdoc @@ -1,13 +1,13 @@ -h1. create-tag-lib +h1. create-taglib h2. Purpose -The @create-tag-lib@ command creates a tag library and associated unit test for the given base name. +The @create-taglib@ command creates a tag library and associated unit test for the given base name. h2. Examples {code:java} -grails create-tag-lib org.bookstore.book +grails create-taglib org.bookstore.book {code} h2. Description @@ -22,7 +22,7 @@ Note that this command is just for convenience and you can also create controlle Usage: {code:java} -grails create-tag-lib [name] +grails create-taglib [name] {code} Fired Events: diff --git a/src/th/ref/Tag Libraries.gdoc b/src/th/ref/Tag Libraries.gdoc index f02a7d180d4..5db726cc8cc 100644 --- a/src/th/ref/Tag Libraries.gdoc +++ b/src/th/ref/Tag Libraries.gdoc @@ -1,9 +1,9 @@ h1. Tag Library Usage -A tag library fulfills role of "view helper" in the Model View Controller (MVC) pattern and helps with GSP rendering. In Grails a tag library is a class with a name that ends in the convention "TagLib" and lives in the @grails-app/taglib@ directory. Use the [create-tag-lib|commandLine] command create a tag library: +A tag library fulfills role of "view helper" in the Model View Controller (MVC) pattern and helps with GSP rendering. In Grails a tag library is a class with a name that ends in the convention "TagLib" and lives in the @grails-app/taglib@ directory. Use the [create-taglib|commandLine] command create a tag library: {code:java} -grails create-tag-lib format +grails create-taglib format {code} or with your favourite IDE or text editor. diff --git a/src/zh_CN/guide/commandLine/antAndMaven.gdoc b/src/zh_CN/guide/commandLine/antAndMaven.gdoc index 76067c100f5..5a45d4ba5ed 100644 --- a/src/zh_CN/guide/commandLine/antAndMaven.gdoc +++ b/src/zh_CN/guide/commandLine/antAndMaven.gdoc @@ -145,7 +145,7 @@ You can also use some of the Grails commands that have been wrapped as Maven goa * @grails:create-pom@ - Creates a new Maven POM for an existing Grails project * @grails:create-script@ - Calls the [create-script|commandLine] command * @grails:create-service@ - Calls the [create-service|commandLine] command -* @grails:create-taglib@ - Calls the [create-tag-lib|commandLine] command +* @grails:create-taglib@ - Calls the [create-taglib|commandLine] command * @grails:create-unit-test@ - Calls the [create-unit-test|commandLine] command * @grails:exec@ - Executes an arbitrary Grails command line script * @grails:generate-all@ - Calls the [generate-all|commandLine] command diff --git a/src/zh_CN/ref/Command Line/create-tag-lib.gdoc b/src/zh_CN/ref/Command Line/create-tag-lib.gdoc index e50e6aa952b..f6375293d29 100644 --- a/src/zh_CN/ref/Command Line/create-tag-lib.gdoc +++ b/src/zh_CN/ref/Command Line/create-tag-lib.gdoc @@ -1,13 +1,13 @@ -h1. create-tag-lib +h1. create-taglib h2. Purpose -The @create-tag-lib@ command creates a tag library and associated unit test for the given base name. +The @create-taglib@ command creates a tag library and associated unit test for the given base name. h2. Examples {code:java} -grails create-tag-lib org.bookstore.book +grails create-taglib org.bookstore.book {code} h2. Description @@ -22,7 +22,7 @@ Note that this command is just for convenience and you can also create controlle Usage: {code:java} -grails create-tag-lib [name] +grails create-taglib [name] {code} Fired Events: diff --git a/src/zh_CN/ref/Tag Libraries.gdoc b/src/zh_CN/ref/Tag Libraries.gdoc index f02a7d180d4..5db726cc8cc 100644 --- a/src/zh_CN/ref/Tag Libraries.gdoc +++ b/src/zh_CN/ref/Tag Libraries.gdoc @@ -1,9 +1,9 @@ h1. Tag Library Usage -A tag library fulfills role of "view helper" in the Model View Controller (MVC) pattern and helps with GSP rendering. In Grails a tag library is a class with a name that ends in the convention "TagLib" and lives in the @grails-app/taglib@ directory. Use the [create-tag-lib|commandLine] command create a tag library: +A tag library fulfills role of "view helper" in the Model View Controller (MVC) pattern and helps with GSP rendering. In Grails a tag library is a class with a name that ends in the convention "TagLib" and lives in the @grails-app/taglib@ directory. Use the [create-taglib|commandLine] command create a tag library: {code:java} -grails create-tag-lib format +grails create-taglib format {code} or with your favourite IDE or text editor. diff --git a/src/zh_TW/guide/commandLine/antAndMaven.gdoc b/src/zh_TW/guide/commandLine/antAndMaven.gdoc index 76067c100f5..5a45d4ba5ed 100644 --- a/src/zh_TW/guide/commandLine/antAndMaven.gdoc +++ b/src/zh_TW/guide/commandLine/antAndMaven.gdoc @@ -145,7 +145,7 @@ You can also use some of the Grails commands that have been wrapped as Maven goa * @grails:create-pom@ - Creates a new Maven POM for an existing Grails project * @grails:create-script@ - Calls the [create-script|commandLine] command * @grails:create-service@ - Calls the [create-service|commandLine] command -* @grails:create-taglib@ - Calls the [create-tag-lib|commandLine] command +* @grails:create-taglib@ - Calls the [create-taglib|commandLine] command * @grails:create-unit-test@ - Calls the [create-unit-test|commandLine] command * @grails:exec@ - Executes an arbitrary Grails command line script * @grails:generate-all@ - Calls the [generate-all|commandLine] command diff --git a/src/zh_TW/ref/Command Line/create-tag-lib.gdoc b/src/zh_TW/ref/Command Line/create-tag-lib.gdoc index e50e6aa952b..f6375293d29 100644 --- a/src/zh_TW/ref/Command Line/create-tag-lib.gdoc +++ b/src/zh_TW/ref/Command Line/create-tag-lib.gdoc @@ -1,13 +1,13 @@ -h1. create-tag-lib +h1. create-taglib h2. Purpose -The @create-tag-lib@ command creates a tag library and associated unit test for the given base name. +The @create-taglib@ command creates a tag library and associated unit test for the given base name. h2. Examples {code:java} -grails create-tag-lib org.bookstore.book +grails create-taglib org.bookstore.book {code} h2. Description @@ -22,7 +22,7 @@ Note that this command is just for convenience and you can also create controlle Usage: {code:java} -grails create-tag-lib [name] +grails create-taglib [name] {code} Fired Events: diff --git a/src/zh_TW/ref/Tag Libraries.gdoc b/src/zh_TW/ref/Tag Libraries.gdoc index f02a7d180d4..5db726cc8cc 100644 --- a/src/zh_TW/ref/Tag Libraries.gdoc +++ b/src/zh_TW/ref/Tag Libraries.gdoc @@ -1,9 +1,9 @@ h1. Tag Library Usage -A tag library fulfills role of "view helper" in the Model View Controller (MVC) pattern and helps with GSP rendering. In Grails a tag library is a class with a name that ends in the convention "TagLib" and lives in the @grails-app/taglib@ directory. Use the [create-tag-lib|commandLine] command create a tag library: +A tag library fulfills role of "view helper" in the Model View Controller (MVC) pattern and helps with GSP rendering. In Grails a tag library is a class with a name that ends in the convention "TagLib" and lives in the @grails-app/taglib@ directory. Use the [create-taglib|commandLine] command create a tag library: {code:java} -grails create-tag-lib format +grails create-taglib format {code} or with your favourite IDE or text editor. From 91c6a7baceee4c0125116fe02a6fc6e92fa381b3 Mon Sep 17 00:00:00 2001 From: Dem Pilafian Date: Fri, 5 Jun 2015 21:38:14 -0700 Subject: [PATCH 140/230] Page for create-taglib moved from create-tag-lib.html to create-taglib.html --- .../ref/Command Line/{create-tag-lib.gdoc => create-taglib.gdoc} | 0 .../ref/Command Line/{create-tag-lib.gdoc => create-taglib.gdoc} | 0 .../ref/Command Line/{create-tag-lib.gdoc => create-taglib.gdoc} | 0 .../ref/Command Line/{create-tag-lib.gdoc => create-taglib.gdoc} | 0 .../ref/Command Line/{create-tag-lib.gdoc => create-taglib.gdoc} | 0 .../ref/Command Line/{create-tag-lib.gdoc => create-taglib.gdoc} | 0 .../ref/Command Line/{create-tag-lib.gdoc => create-taglib.gdoc} | 0 7 files changed, 0 insertions(+), 0 deletions(-) rename src/en/ref/Command Line/{create-tag-lib.gdoc => create-taglib.gdoc} (100%) rename src/es/ref/Command Line/{create-tag-lib.gdoc => create-taglib.gdoc} (100%) rename src/fr/ref/Command Line/{create-tag-lib.gdoc => create-taglib.gdoc} (100%) rename src/pt_PT/ref/Command Line/{create-tag-lib.gdoc => create-taglib.gdoc} (100%) rename src/th/ref/Command Line/{create-tag-lib.gdoc => create-taglib.gdoc} (100%) rename src/zh_CN/ref/Command Line/{create-tag-lib.gdoc => create-taglib.gdoc} (100%) rename src/zh_TW/ref/Command Line/{create-tag-lib.gdoc => create-taglib.gdoc} (100%) diff --git a/src/en/ref/Command Line/create-tag-lib.gdoc b/src/en/ref/Command Line/create-taglib.gdoc similarity index 100% rename from src/en/ref/Command Line/create-tag-lib.gdoc rename to src/en/ref/Command Line/create-taglib.gdoc diff --git a/src/es/ref/Command Line/create-tag-lib.gdoc b/src/es/ref/Command Line/create-taglib.gdoc similarity index 100% rename from src/es/ref/Command Line/create-tag-lib.gdoc rename to src/es/ref/Command Line/create-taglib.gdoc diff --git a/src/fr/ref/Command Line/create-tag-lib.gdoc b/src/fr/ref/Command Line/create-taglib.gdoc similarity index 100% rename from src/fr/ref/Command Line/create-tag-lib.gdoc rename to src/fr/ref/Command Line/create-taglib.gdoc diff --git a/src/pt_PT/ref/Command Line/create-tag-lib.gdoc b/src/pt_PT/ref/Command Line/create-taglib.gdoc similarity index 100% rename from src/pt_PT/ref/Command Line/create-tag-lib.gdoc rename to src/pt_PT/ref/Command Line/create-taglib.gdoc diff --git a/src/th/ref/Command Line/create-tag-lib.gdoc b/src/th/ref/Command Line/create-taglib.gdoc similarity index 100% rename from src/th/ref/Command Line/create-tag-lib.gdoc rename to src/th/ref/Command Line/create-taglib.gdoc diff --git a/src/zh_CN/ref/Command Line/create-tag-lib.gdoc b/src/zh_CN/ref/Command Line/create-taglib.gdoc similarity index 100% rename from src/zh_CN/ref/Command Line/create-tag-lib.gdoc rename to src/zh_CN/ref/Command Line/create-taglib.gdoc diff --git a/src/zh_TW/ref/Command Line/create-tag-lib.gdoc b/src/zh_TW/ref/Command Line/create-taglib.gdoc similarity index 100% rename from src/zh_TW/ref/Command Line/create-tag-lib.gdoc rename to src/zh_TW/ref/Command Line/create-taglib.gdoc From d5a9f7accd7b3c45bc73abd0e72f78d0911493a6 Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Sun, 14 Jun 2015 16:14:31 +0530 Subject: [PATCH 141/230] Fix missing with --- src/en/guide/conf/dataSource.gdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/en/guide/conf/dataSource.gdoc b/src/en/guide/conf/dataSource.gdoc index b09caafa508..840e0ed2c2f 100644 --- a/src/en/guide/conf/dataSource.gdoc +++ b/src/en/guide/conf/dataSource.gdoc @@ -12,7 +12,7 @@ Drivers typically come in the form of a JAR archive. It's best to use the depend If you can't use dependency resolution then just put the JAR in your project's @lib@ directory. -Once you have the JAR resolved you need to get familiar Grails' DataSource descriptor file located at @grails-app/conf/DataSource.groovy@. This file contains the dataSource definition which includes the following settings: +Once you have the JAR resolved you need to get familiar with Grails' DataSource descriptor file located at @grails-app/conf/DataSource.groovy@. This file contains the dataSource definition which includes the following settings: * @driverClassName@ - The class name of the JDBC driver * @username@ - The username used to establish a JDBC connection From 89ada352017d9d1ed44ce790caece608074029ac Mon Sep 17 00:00:00 2001 From: graemerocher Date: Tue, 16 Jun 2015 14:11:05 +0200 Subject: [PATCH 142/230] Release 3.0.2 docs --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 217007dcbb4..f8b92d12d71 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1 @@ -grails.version=3.0.1 +grails.version=3.0.2 From 60cfe31e44094784f823e5e9d5b53588d13196cc Mon Sep 17 00:00:00 2001 From: graemerocher Date: Tue, 16 Jun 2015 14:26:02 +0200 Subject: [PATCH 143/230] Use 3.0.x branch --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 4323564b869..a1d3e6cd5c8 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ archivesBaseName = "grails-docs" ext.checkOutDir = "${buildDir.path}/checkout" ext.outputDir = "${buildDir.path}/docs" -ext.githubBranch = "master" +ext.githubBranch = "3.0.x" ext.explicitGrailsHome = System.getProperty("grails.home") ext.grailsHome = explicitGrailsHome ? file(explicitGrailsHome).absolutePath : "$checkOutDir/grails-src" From 1356f9a329c254e44500e962eb004aaa0a4eb868 Mon Sep 17 00:00:00 2001 From: KasonYang Date: Wed, 17 Jun 2015 16:27:38 +0800 Subject: [PATCH 144/230] import fixed:@Mock --- src/en/guide/testing/unitTesting/unitTestingDomains.gdoc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/en/guide/testing/unitTesting/unitTestingDomains.gdoc b/src/en/guide/testing/unitTesting/unitTestingDomains.gdoc index 01a9e2f8188..0b70110c011 100644 --- a/src/en/guide/testing/unitTesting/unitTestingDomains.gdoc +++ b/src/en/guide/testing/unitTesting/unitTestingDomains.gdoc @@ -30,6 +30,7 @@ h4. DomainClassUnitTestMixin Basics {code:java} import grails.test.mixin.TestFor +import grails.test.mixin.Mock import spock.lang.Specification @TestFor(BookController) @@ -62,6 +63,7 @@ Tests for this action can be written as follows: {code:java} import grails.test.mixin.TestFor +import grails.test.mixin.Mock import spock.lang.Specification @TestFor(BookController) @@ -95,6 +97,7 @@ class BookControllerSpec extends Specification { {code:java} import grails.test.mixin.TestFor +import grails.test.mixin.Mock import spock.lang.Specification @TestFor(BookController) From d95097fa99dc88db0c4af4d9bae774f18e849ca1 Mon Sep 17 00:00:00 2001 From: Frank J Kocina Date: Thu, 18 Jun 2015 15:09:34 -0500 Subject: [PATCH 145/230] Fix typo in deployment.gdoc --- src/en/guide/deployment.gdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/en/guide/deployment.gdoc b/src/en/guide/deployment.gdoc index b15fcac8889..38ac0b755ff 100644 --- a/src/en/guide/deployment.gdoc +++ b/src/en/guide/deployment.gdoc @@ -2,7 +2,7 @@ Grails applications can be deployed in a number of ways, each of which has its p h3. "grails run-app" -You should be very familiar with this approach by now, since it is the most common method of running an application during the development phase. An embedded Tomcat server is launched that loads the web application from the development sources, thus allowing it to pick up an changes to application files. +You should be very familiar with this approach by now, since it is the most common method of running an application during the development phase. An embedded Tomcat server is launched that loads the web application from the development sources, thus allowing it to pick up any changes to application files. You can also deploy to production this way using: From dc598a52b60dc007a4030fcd6eb56056a44796ca Mon Sep 17 00:00:00 2001 From: Anders Kristian Andersen Date: Sat, 20 Jun 2015 15:31:52 +0200 Subject: [PATCH 146/230] #264 updated doc to reflect grails-core change grails-9020 --- src/en/guide/gettingStarted/aHelloWorldExample.gdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/en/guide/gettingStarted/aHelloWorldExample.gdoc b/src/en/guide/gettingStarted/aHelloWorldExample.gdoc index abb883a6603..0f048aac2d2 100644 --- a/src/en/guide/gettingStarted/aHelloWorldExample.gdoc +++ b/src/en/guide/gettingStarted/aHelloWorldExample.gdoc @@ -43,7 +43,7 @@ Note that in previous versions of Grails the context path was by default the nam {code} server: - 'context-path': '/helloworld' + 'contextPath': '/helloworld' {code} With the above configuration in place the server will instead startup at the URL [http://localhost:8080/helloworld/|http://localhost:8080/helloworld/]. From 1446b014cd5e1a1dca44714e796a2ea780dbf39b Mon Sep 17 00:00:00 2001 From: Dhiraj Mahapatro Date: Tue, 23 Jun 2015 13:49:21 -0400 Subject: [PATCH 147/230] Add information about usage of @Rollback in integration tests and when to use Spring's @Rollback --- src/en/guide/testing/integrationTesting.gdoc | 79 ++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/src/en/guide/testing/integrationTesting.gdoc b/src/en/guide/testing/integrationTesting.gdoc index e8305193eab..f27d568b3a7 100644 --- a/src/en/guide/testing/integrationTesting.gdoc +++ b/src/en/guide/testing/integrationTesting.gdoc @@ -32,6 +32,85 @@ class @artifact.name@Spec extends Specification { The @Rollback@ annotation ensures that each test methods runs in a transaction that is rolled back. Generally this is desirable because you do not want your tests depending on order or application state. +h4. Using Spring's Rollback annotation +In Grails 3.0 tests rely on @grails.transaction.Rollback@ annotation to bind the session in integration tests. But with this approach the @setup()@ and @setupSpec()@ method in the test is run prior to the transaction starting hence +you would see @No Hibernate Session found@ error while running integration test if @setup()@ sets up data and persists them as shown in the below sample: + +{code} +import grails.test.mixin.integration.Integration +import grails.transaction.* +import spock.lang.* + +@Integration +@Rollback +class @artifact.name@Spec extends Specification { + + void setup() { + // Below line would throw a Hibernate session not found error + new Book(name: 'Grails in Action').save(flush: true) + } + + void "test something"() { + expect: + Book.count() == 1 + } +} +{code} + +To make sure the setup logic runs within the transaction you have to move it to be called from the method itself. Similar to usage of @setupData()@ method shown below: + +{code} +import grails.test.mixin.integration.Integration +import grails.transaction.* +import spock.lang.* + +@Integration +@Rollback +class @artifact.name@Spec extends Specification { + + void setupData() { + new Book(name: 'Grails in Action').save(flush: true) + } + + void "test something"() { + given: + setupData() + + expect: + Book.count() == 1 + } +} +{code} + +Another approach could be to use Spring's [@Rollback|http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/test/annotation/Rollback.html] instead. + +{code} +import grails.test.mixin.integration.Integration +import org.springframework.test.annotation.Rollback +import spock.lang.* + +@Integration +@Rollback +class @artifact.name@Spec extends Specification { + + void setup() { + new Book(name: 'Grails in Action').save(flush: true) + } + + void "test something"() { + expect: + Book.count() == 1 + } +} +{code} + +{note} +It isn't possible to make @grails.transaction.Rollback@ behave the same way as Spring's Rollback annotation because @grails.transaction.Rollback@ transforms the byte code of the class, eliminating the need for a proxy (which Spring's version requires). +This has the downside that you cannot implement it differently for different cases (as Spring does for testing). +{note} + +h4. DirtiesContext + If you do have a series of tests that will share state you can remove the @Rollback@ and the last test in the suite should feature the [DirtiesContext|api:org.springframework.test.annotation.DirtiesContext] annotation which will shutdown the environment and restart it fresh (note that this will have an impact on test run times). h4. Autowiring From 7cf869bcdf59ae326cf3aeb5d7827449cd2828ea Mon Sep 17 00:00:00 2001 From: Georgios F Date: Fri, 26 Jun 2015 09:36:57 +0100 Subject: [PATCH 148/230] Updated the path for hibernate.cfg.xml from grails-app/conf/hibernate to grails-app/conf as the old path does not take effect in Grails 3.0.1. For a more detailed description of the issue refer to: http://stackoverflow.com/questions/30830155/mapping-with-hibernate-annotations-in-grails-3-0-1 --- src/en/guide/conf/dataSource/multipleDatasources.gdoc | 6 +++--- src/en/guide/hibernate/mappingWithHibernateAnnotations.gdoc | 2 +- src/en/guide/hibernate/usingHibernateXMLMappingFiles.gdoc | 6 +++--- src/es/guide/hibernate/mappingWithHibernateAnnotations.gdoc | 2 +- src/es/guide/hibernate/usingHibernateXMLMappingFiles.gdoc | 6 +++--- src/es/ref/Command Line/create-hibernate-cfg-xml.gdoc | 2 +- src/fr/guide/hibernate/mappingWithHibernateAnnotations.gdoc | 2 +- src/fr/guide/hibernate/usingHibernateXMLMappingFiles.gdoc | 6 +++--- src/fr/ref/Command Line/create-hibernate-cfg-xml.gdoc | 2 +- .../guide/hibernate/mappingWithHibernateAnnotations.gdoc | 2 +- .../guide/hibernate/usingHibernateXMLMappingFiles.gdoc | 6 +++--- src/pt_PT/ref/Command Line/create-hibernate-cfg-xml.gdoc | 2 +- src/th/guide/hibernate/mappingWithHibernateAnnotations.gdoc | 2 +- src/th/guide/hibernate/usingHibernateXMLMappingFiles.gdoc | 6 +++--- src/th/ref/Command Line/create-hibernate-cfg-xml.gdoc | 2 +- .../guide/hibernate/mappingWithHibernateAnnotations.gdoc | 2 +- .../guide/hibernate/usingHibernateXMLMappingFiles.gdoc | 6 +++--- src/zh_CN/ref/Command Line/create-hibernate-cfg-xml.gdoc | 2 +- .../guide/hibernate/mappingWithHibernateAnnotations.gdoc | 2 +- .../guide/hibernate/usingHibernateXMLMappingFiles.gdoc | 6 +++--- src/zh_TW/ref/Command Line/create-hibernate-cfg-xml.gdoc | 2 +- 21 files changed, 37 insertions(+), 37 deletions(-) diff --git a/src/en/guide/conf/dataSource/multipleDatasources.gdoc b/src/en/guide/conf/dataSource/multipleDatasources.gdoc index 6b457697dfa..2bef936f5c5 100644 --- a/src/en/guide/conf/dataSource/multipleDatasources.gdoc +++ b/src/en/guide/conf/dataSource/multipleDatasources.gdoc @@ -162,9 +162,9 @@ As you can see, you add the @DataSource@ to the method call in both the static c h4. Hibernate Mapped Domain Classes -You can also partition annotated Java classes into separate datasources. Classes using the default datasource are registered in @grails-app/conf/hibernate/hibernate.cfg.xml@. To specify that an annotated class uses a non-default datasource, create a @hibernate.cfg.xml@ file for that datasource with the file name prefixed with the datasource name. +You can also partition annotated Java classes into separate datasources. Classes using the default datasource are registered in @grails-app/conf/hibernate.cfg.xml@. To specify that an annotated class uses a non-default datasource, create a @hibernate.cfg.xml@ file for that datasource with the file name prefixed with the datasource name. -For example if the @Book@ class is in the default datasource, you would register that in @grails-app/conf/hibernate/hibernate.cfg.xml@: +For example if the @Book@ class is in the default datasource, you would register that in @grails-app/conf/hibernate.cfg.xml@: {code:xml} @@ -178,7 +178,7 @@ For example if the @Book@ class is in the default datasource, you would register {code} -and if the @Library@ class is in the "ds2" datasource, you would register that in @grails-app/conf/hibernate/ds2_hibernate.cfg.xml@: +and if the @Library@ class is in the "ds2" datasource, you would register that in @grails-app/conf/ds2_hibernate.cfg.xml@: {code:xml} diff --git a/src/en/guide/hibernate/mappingWithHibernateAnnotations.gdoc b/src/en/guide/hibernate/mappingWithHibernateAnnotations.gdoc index 7dd5ed3fb5a..9424985d869 100644 --- a/src/en/guide/hibernate/mappingWithHibernateAnnotations.gdoc +++ b/src/en/guide/hibernate/mappingWithHibernateAnnotations.gdoc @@ -42,7 +42,7 @@ public class Book { } {code} -Then register the class with the Hibernate @sessionFactory@ by adding relevant entries to the @grails-app/conf/hibernate/hibernate.cfg.xml@ file as follows: +Then register the class with the Hibernate @sessionFactory@ by adding relevant entries to the @grails-app/conf/hibernate.cfg.xml@ file as follows: {code:xml} @@ -14,7 +14,7 @@ Mapping your domain classes with XML is pretty straightforward. Simply create a {code} -The individual mapping files, like 'org.example.Book.hbm.xml' in the above example, also go into the @grails-app/conf/hibernate@ directory. To find out how to map domain classes with XML, check out the [Hibernate manual|http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html/mapping.html]. +The individual mapping files, like 'org.example.Book.hbm.xml' in the above example, also go into the @grails-app/conf@ directory. To find out how to map domain classes with XML, check out the [Hibernate manual|http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html/mapping.html]. If the default location of the @hibernate.cfg.xml@ file doesn't suit you, you can change it by specifying an alternative location in @grails-app/conf/DataSource.groovy@: @@ -33,4 +33,4 @@ hibernate { } {code} -Grails also lets you write your domain model in Java or reuse an existing one that already has Hibernate mapping files. Simply place the mapping files into @grails-app/conf/hibernate@ and either put the Java files in @src/java@ or the classes in the project's @lib@ directory if the domain model is packaged as a JAR. You still need the @hibernate.cfg.xml@ though! +Grails also lets you write your domain model in Java or reuse an existing one that already has Hibernate mapping files. Simply place the mapping files into @grails-app/conf@ and either put the Java files in @src/java@ or the classes in the project's @lib@ directory if the domain model is packaged as a JAR. You still need the @hibernate.cfg.xml@ though! diff --git a/src/es/guide/hibernate/mappingWithHibernateAnnotations.gdoc b/src/es/guide/hibernate/mappingWithHibernateAnnotations.gdoc index 7dd5ed3fb5a..9424985d869 100644 --- a/src/es/guide/hibernate/mappingWithHibernateAnnotations.gdoc +++ b/src/es/guide/hibernate/mappingWithHibernateAnnotations.gdoc @@ -42,7 +42,7 @@ public class Book { } {code} -Then register the class with the Hibernate @sessionFactory@ by adding relevant entries to the @grails-app/conf/hibernate/hibernate.cfg.xml@ file as follows: +Then register the class with the Hibernate @sessionFactory@ by adding relevant entries to the @grails-app/conf/hibernate.cfg.xml@ file as follows: {code:xml} @@ -14,7 +14,7 @@ Mapping your domain classes with XML is pretty straightforward. Simply create a {code} -The individual mapping files, like 'org.example.Book.hbm.xml' in the above example, also go into the @grails-app/conf/hibernate@ directory. To find out how to map domain classes with XML, check out the [Hibernate manual|http://docs.jboss.org/hibernate/core/3.3/reference/en/html/mapping.html]. +The individual mapping files, like 'org.example.Book.hbm.xml' in the above example, also go into the @grails-app/conf@ directory. To find out how to map domain classes with XML, check out the [Hibernate manual|http://docs.jboss.org/hibernate/core/3.3/reference/en/html/mapping.html]. If the default location of the @hibernate.cfg.xml@ file doesn't suit you, you can change it by specifying an alternative location in @grails-app/conf/DataSource.groovy@: @@ -33,4 +33,4 @@ hibernate { } {code} -Grails also lets you write your domain model in Java or reuse an existing one that already has Hibernate mapping files. Simply place the mapping files into @grails-app/conf/hibernate@ and either put the Java files in @src/java@ or the classes in the project's @lib@ directory if the domain model is packaged as a JAR. You still need the @hibernate.cfg.xml@ though! +Grails also lets you write your domain model in Java or reuse an existing one that already has Hibernate mapping files. Simply place the mapping files into @grails-app/conf@ and either put the Java files in @src/java@ or the classes in the project's @lib@ directory if the domain model is packaged as a JAR. You still need the @hibernate.cfg.xml@ though! diff --git a/src/es/ref/Command Line/create-hibernate-cfg-xml.gdoc b/src/es/ref/Command Line/create-hibernate-cfg-xml.gdoc index 5d2d0e19bec..80daa256716 100644 --- a/src/es/ref/Command Line/create-hibernate-cfg-xml.gdoc +++ b/src/es/ref/Command Line/create-hibernate-cfg-xml.gdoc @@ -11,7 +11,7 @@ grails create-hibernate-cfg-xml h2. Description -Creates a @hibernate.cfg.xml@ file in the @grails-app/conf/hibernate@ directory. You can add @@ elements there to reference annotated Java domain classes, classes mapped by hbm.xml files, or hbm.xml files containing @@ elements defining custom DDL that's not supported by GORM. +Creates a @hibernate.cfg.xml@ file in the @grails-app/conf@ directory. You can add @@ elements there to reference annotated Java domain classes, classes mapped by hbm.xml files, or hbm.xml files containing @@ elements defining custom DDL that's not supported by GORM. Usage: {code:java} diff --git a/src/fr/guide/hibernate/mappingWithHibernateAnnotations.gdoc b/src/fr/guide/hibernate/mappingWithHibernateAnnotations.gdoc index 7dd5ed3fb5a..9424985d869 100644 --- a/src/fr/guide/hibernate/mappingWithHibernateAnnotations.gdoc +++ b/src/fr/guide/hibernate/mappingWithHibernateAnnotations.gdoc @@ -42,7 +42,7 @@ public class Book { } {code} -Then register the class with the Hibernate @sessionFactory@ by adding relevant entries to the @grails-app/conf/hibernate/hibernate.cfg.xml@ file as follows: +Then register the class with the Hibernate @sessionFactory@ by adding relevant entries to the @grails-app/conf/hibernate.cfg.xml@ file as follows: {code:xml} @@ -14,7 +14,7 @@ Mapping your domain classes with XML is pretty straightforward. Simply create a {code} -The individual mapping files, like 'org.example.Book.hbm.xml' in the above example, also go into the @grails-app/conf/hibernate@ directory. To find out how to map domain classes with XML, check out the [Hibernate manual|http://docs.jboss.org/hibernate/core/3.3/reference/en/html/mapping.html]. +The individual mapping files, like 'org.example.Book.hbm.xml' in the above example, also go into the @grails-app/conf@ directory. To find out how to map domain classes with XML, check out the [Hibernate manual|http://docs.jboss.org/hibernate/core/3.3/reference/en/html/mapping.html]. If the default location of the @hibernate.cfg.xml@ file doesn't suit you, you can change it by specifying an alternative location in @grails-app/conf/DataSource.groovy@: @@ -33,4 +33,4 @@ hibernate { } {code} -Grails also lets you write your domain model in Java or reuse an existing one that already has Hibernate mapping files. Simply place the mapping files into @grails-app/conf/hibernate@ and either put the Java files in @src/java@ or the classes in the project's @lib@ directory if the domain model is packaged as a JAR. You still need the @hibernate.cfg.xml@ though! +Grails also lets you write your domain model in Java or reuse an existing one that already has Hibernate mapping files. Simply place the mapping files into @grails-app/conf@ and either put the Java files in @src/java@ or the classes in the project's @lib@ directory if the domain model is packaged as a JAR. You still need the @hibernate.cfg.xml@ though! diff --git a/src/fr/ref/Command Line/create-hibernate-cfg-xml.gdoc b/src/fr/ref/Command Line/create-hibernate-cfg-xml.gdoc index 5d2d0e19bec..80daa256716 100644 --- a/src/fr/ref/Command Line/create-hibernate-cfg-xml.gdoc +++ b/src/fr/ref/Command Line/create-hibernate-cfg-xml.gdoc @@ -11,7 +11,7 @@ grails create-hibernate-cfg-xml h2. Description -Creates a @hibernate.cfg.xml@ file in the @grails-app/conf/hibernate@ directory. You can add @@ elements there to reference annotated Java domain classes, classes mapped by hbm.xml files, or hbm.xml files containing @@ elements defining custom DDL that's not supported by GORM. +Creates a @hibernate.cfg.xml@ file in the @grails-app/conf@ directory. You can add @@ elements there to reference annotated Java domain classes, classes mapped by hbm.xml files, or hbm.xml files containing @@ elements defining custom DDL that's not supported by GORM. Usage: {code:java} diff --git a/src/pt_PT/guide/hibernate/mappingWithHibernateAnnotations.gdoc b/src/pt_PT/guide/hibernate/mappingWithHibernateAnnotations.gdoc index 7dd5ed3fb5a..9424985d869 100644 --- a/src/pt_PT/guide/hibernate/mappingWithHibernateAnnotations.gdoc +++ b/src/pt_PT/guide/hibernate/mappingWithHibernateAnnotations.gdoc @@ -42,7 +42,7 @@ public class Book { } {code} -Then register the class with the Hibernate @sessionFactory@ by adding relevant entries to the @grails-app/conf/hibernate/hibernate.cfg.xml@ file as follows: +Then register the class with the Hibernate @sessionFactory@ by adding relevant entries to the @grails-app/conf/hibernate.cfg.xml@ file as follows: {code:xml} @@ -14,7 +14,7 @@ Mapping your domain classes with XML is pretty straightforward. Simply create a {code} -The individual mapping files, like 'org.example.Book.hbm.xml' in the above example, also go into the @grails-app/conf/hibernate@ directory. To find out how to map domain classes with XML, check out the [Hibernate manual|http://docs.jboss.org/hibernate/core/3.3/reference/en/html/mapping.html]. +The individual mapping files, like 'org.example.Book.hbm.xml' in the above example, also go into the @grails-app/conf@ directory. To find out how to map domain classes with XML, check out the [Hibernate manual|http://docs.jboss.org/hibernate/core/3.3/reference/en/html/mapping.html]. If the default location of the @hibernate.cfg.xml@ file doesn't suit you, you can change it by specifying an alternative location in @grails-app/conf/DataSource.groovy@: @@ -33,4 +33,4 @@ hibernate { } {code} -Grails also lets you write your domain model in Java or reuse an existing one that already has Hibernate mapping files. Simply place the mapping files into @grails-app/conf/hibernate@ and either put the Java files in @src/java@ or the classes in the project's @lib@ directory if the domain model is packaged as a JAR. You still need the @hibernate.cfg.xml@ though! +Grails also lets you write your domain model in Java or reuse an existing one that already has Hibernate mapping files. Simply place the mapping files into @grails-app/conf@ and either put the Java files in @src/java@ or the classes in the project's @lib@ directory if the domain model is packaged as a JAR. You still need the @hibernate.cfg.xml@ though! diff --git a/src/pt_PT/ref/Command Line/create-hibernate-cfg-xml.gdoc b/src/pt_PT/ref/Command Line/create-hibernate-cfg-xml.gdoc index 5d2d0e19bec..80daa256716 100644 --- a/src/pt_PT/ref/Command Line/create-hibernate-cfg-xml.gdoc +++ b/src/pt_PT/ref/Command Line/create-hibernate-cfg-xml.gdoc @@ -11,7 +11,7 @@ grails create-hibernate-cfg-xml h2. Description -Creates a @hibernate.cfg.xml@ file in the @grails-app/conf/hibernate@ directory. You can add @@ elements there to reference annotated Java domain classes, classes mapped by hbm.xml files, or hbm.xml files containing @@ elements defining custom DDL that's not supported by GORM. +Creates a @hibernate.cfg.xml@ file in the @grails-app/conf@ directory. You can add @@ elements there to reference annotated Java domain classes, classes mapped by hbm.xml files, or hbm.xml files containing @@ elements defining custom DDL that's not supported by GORM. Usage: {code:java} diff --git a/src/th/guide/hibernate/mappingWithHibernateAnnotations.gdoc b/src/th/guide/hibernate/mappingWithHibernateAnnotations.gdoc index 7dd5ed3fb5a..9424985d869 100644 --- a/src/th/guide/hibernate/mappingWithHibernateAnnotations.gdoc +++ b/src/th/guide/hibernate/mappingWithHibernateAnnotations.gdoc @@ -42,7 +42,7 @@ public class Book { } {code} -Then register the class with the Hibernate @sessionFactory@ by adding relevant entries to the @grails-app/conf/hibernate/hibernate.cfg.xml@ file as follows: +Then register the class with the Hibernate @sessionFactory@ by adding relevant entries to the @grails-app/conf/hibernate.cfg.xml@ file as follows: {code:xml} @@ -14,7 +14,7 @@ Mapping your domain classes with XML is pretty straightforward. Simply create a {code} -The individual mapping files, like 'org.example.Book.hbm.xml' in the above example, also go into the @grails-app/conf/hibernate@ directory. To find out how to map domain classes with XML, check out the [Hibernate manual|http://docs.jboss.org/hibernate/core/3.3/reference/en/html/mapping.html]. +The individual mapping files, like 'org.example.Book.hbm.xml' in the above example, also go into the @grails-app/conf@ directory. To find out how to map domain classes with XML, check out the [Hibernate manual|http://docs.jboss.org/hibernate/core/3.3/reference/en/html/mapping.html]. If the default location of the @hibernate.cfg.xml@ file doesn't suit you, you can change it by specifying an alternative location in @grails-app/conf/DataSource.groovy@: @@ -33,4 +33,4 @@ hibernate { } {code} -Grails also lets you write your domain model in Java or reuse an existing one that already has Hibernate mapping files. Simply place the mapping files into @grails-app/conf/hibernate@ and either put the Java files in @src/java@ or the classes in the project's @lib@ directory if the domain model is packaged as a JAR. You still need the @hibernate.cfg.xml@ though! +Grails also lets you write your domain model in Java or reuse an existing one that already has Hibernate mapping files. Simply place the mapping files into @grails-app/conf@ and either put the Java files in @src/java@ or the classes in the project's @lib@ directory if the domain model is packaged as a JAR. You still need the @hibernate.cfg.xml@ though! diff --git a/src/th/ref/Command Line/create-hibernate-cfg-xml.gdoc b/src/th/ref/Command Line/create-hibernate-cfg-xml.gdoc index 5d2d0e19bec..80daa256716 100644 --- a/src/th/ref/Command Line/create-hibernate-cfg-xml.gdoc +++ b/src/th/ref/Command Line/create-hibernate-cfg-xml.gdoc @@ -11,7 +11,7 @@ grails create-hibernate-cfg-xml h2. Description -Creates a @hibernate.cfg.xml@ file in the @grails-app/conf/hibernate@ directory. You can add @@ elements there to reference annotated Java domain classes, classes mapped by hbm.xml files, or hbm.xml files containing @@ elements defining custom DDL that's not supported by GORM. +Creates a @hibernate.cfg.xml@ file in the @grails-app/conf@ directory. You can add @@ elements there to reference annotated Java domain classes, classes mapped by hbm.xml files, or hbm.xml files containing @@ elements defining custom DDL that's not supported by GORM. Usage: {code:java} diff --git a/src/zh_CN/guide/hibernate/mappingWithHibernateAnnotations.gdoc b/src/zh_CN/guide/hibernate/mappingWithHibernateAnnotations.gdoc index 7dd5ed3fb5a..9424985d869 100644 --- a/src/zh_CN/guide/hibernate/mappingWithHibernateAnnotations.gdoc +++ b/src/zh_CN/guide/hibernate/mappingWithHibernateAnnotations.gdoc @@ -42,7 +42,7 @@ public class Book { } {code} -Then register the class with the Hibernate @sessionFactory@ by adding relevant entries to the @grails-app/conf/hibernate/hibernate.cfg.xml@ file as follows: +Then register the class with the Hibernate @sessionFactory@ by adding relevant entries to the @grails-app/conf/hibernate.cfg.xml@ file as follows: {code:xml} @@ -14,7 +14,7 @@ Mapping your domain classes with XML is pretty straightforward. Simply create a {code} -The individual mapping files, like 'org.example.Book.hbm.xml' in the above example, also go into the @grails-app/conf/hibernate@ directory. To find out how to map domain classes with XML, check out the [Hibernate manual|http://docs.jboss.org/hibernate/core/3.3/reference/en/html/mapping.html]. +The individual mapping files, like 'org.example.Book.hbm.xml' in the above example, also go into the @grails-app/conf@ directory. To find out how to map domain classes with XML, check out the [Hibernate manual|http://docs.jboss.org/hibernate/core/3.3/reference/en/html/mapping.html]. If the default location of the @hibernate.cfg.xml@ file doesn't suit you, you can change it by specifying an alternative location in @grails-app/conf/DataSource.groovy@: @@ -33,4 +33,4 @@ hibernate { } {code} -Grails also lets you write your domain model in Java or reuse an existing one that already has Hibernate mapping files. Simply place the mapping files into @grails-app/conf/hibernate@ and either put the Java files in @src/java@ or the classes in the project's @lib@ directory if the domain model is packaged as a JAR. You still need the @hibernate.cfg.xml@ though! +Grails also lets you write your domain model in Java or reuse an existing one that already has Hibernate mapping files. Simply place the mapping files into @grails-app/conf@ and either put the Java files in @src/java@ or the classes in the project's @lib@ directory if the domain model is packaged as a JAR. You still need the @hibernate.cfg.xml@ though! diff --git a/src/zh_CN/ref/Command Line/create-hibernate-cfg-xml.gdoc b/src/zh_CN/ref/Command Line/create-hibernate-cfg-xml.gdoc index 5d2d0e19bec..80daa256716 100644 --- a/src/zh_CN/ref/Command Line/create-hibernate-cfg-xml.gdoc +++ b/src/zh_CN/ref/Command Line/create-hibernate-cfg-xml.gdoc @@ -11,7 +11,7 @@ grails create-hibernate-cfg-xml h2. Description -Creates a @hibernate.cfg.xml@ file in the @grails-app/conf/hibernate@ directory. You can add @@ elements there to reference annotated Java domain classes, classes mapped by hbm.xml files, or hbm.xml files containing @@ elements defining custom DDL that's not supported by GORM. +Creates a @hibernate.cfg.xml@ file in the @grails-app/conf@ directory. You can add @@ elements there to reference annotated Java domain classes, classes mapped by hbm.xml files, or hbm.xml files containing @@ elements defining custom DDL that's not supported by GORM. Usage: {code:java} diff --git a/src/zh_TW/guide/hibernate/mappingWithHibernateAnnotations.gdoc b/src/zh_TW/guide/hibernate/mappingWithHibernateAnnotations.gdoc index 7dd5ed3fb5a..9424985d869 100644 --- a/src/zh_TW/guide/hibernate/mappingWithHibernateAnnotations.gdoc +++ b/src/zh_TW/guide/hibernate/mappingWithHibernateAnnotations.gdoc @@ -42,7 +42,7 @@ public class Book { } {code} -Then register the class with the Hibernate @sessionFactory@ by adding relevant entries to the @grails-app/conf/hibernate/hibernate.cfg.xml@ file as follows: +Then register the class with the Hibernate @sessionFactory@ by adding relevant entries to the @grails-app/conf/hibernate.cfg.xml@ file as follows: {code:xml} @@ -14,7 +14,7 @@ Mapping your domain classes with XML is pretty straightforward. Simply create a {code} -The individual mapping files, like 'org.example.Book.hbm.xml' in the above example, also go into the @grails-app/conf/hibernate@ directory. To find out how to map domain classes with XML, check out the [Hibernate manual|http://docs.jboss.org/hibernate/core/3.3/reference/en/html/mapping.html]. +The individual mapping files, like 'org.example.Book.hbm.xml' in the above example, also go into the @grails-app/conf@ directory. To find out how to map domain classes with XML, check out the [Hibernate manual|http://docs.jboss.org/hibernate/core/3.3/reference/en/html/mapping.html]. If the default location of the @hibernate.cfg.xml@ file doesn't suit you, you can change it by specifying an alternative location in @grails-app/conf/DataSource.groovy@: @@ -33,4 +33,4 @@ hibernate { } {code} -Grails also lets you write your domain model in Java or reuse an existing one that already has Hibernate mapping files. Simply place the mapping files into @grails-app/conf/hibernate@ and either put the Java files in @src/java@ or the classes in the project's @lib@ directory if the domain model is packaged as a JAR. You still need the @hibernate.cfg.xml@ though! +Grails also lets you write your domain model in Java or reuse an existing one that already has Hibernate mapping files. Simply place the mapping files into @grails-app/conf@ and either put the Java files in @src/java@ or the classes in the project's @lib@ directory if the domain model is packaged as a JAR. You still need the @hibernate.cfg.xml@ though! diff --git a/src/zh_TW/ref/Command Line/create-hibernate-cfg-xml.gdoc b/src/zh_TW/ref/Command Line/create-hibernate-cfg-xml.gdoc index 5d2d0e19bec..80daa256716 100644 --- a/src/zh_TW/ref/Command Line/create-hibernate-cfg-xml.gdoc +++ b/src/zh_TW/ref/Command Line/create-hibernate-cfg-xml.gdoc @@ -11,7 +11,7 @@ grails create-hibernate-cfg-xml h2. Description -Creates a @hibernate.cfg.xml@ file in the @grails-app/conf/hibernate@ directory. You can add @@ elements there to reference annotated Java domain classes, classes mapped by hbm.xml files, or hbm.xml files containing @@ elements defining custom DDL that's not supported by GORM. +Creates a @hibernate.cfg.xml@ file in the @grails-app/conf@ directory. You can add @@ elements there to reference annotated Java domain classes, classes mapped by hbm.xml files, or hbm.xml files containing @@ elements defining custom DDL that's not supported by GORM. Usage: {code:java} From 9d6791ac32468453fb1227869a3ad92e04d9c4f7 Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Sun, 28 Jun 2015 15:01:22 +0530 Subject: [PATCH 149/230] Changed can using to are using I checked the plugin and @CompileStatic is being used --- src/en/guide/theWebLayer/interceptors.gdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/en/guide/theWebLayer/interceptors.gdoc b/src/en/guide/theWebLayer/interceptors.gdoc index 3e53acc0732..a2313644108 100644 --- a/src/en/guide/theWebLayer/interceptors.gdoc +++ b/src/en/guide/theWebLayer/interceptors.gdoc @@ -26,4 +26,4 @@ h4. Interceptors vs Filters In versions of Grails prior to Grails 3.0, Grails supported the notion of filters. These are still supported for backwards compatibility but are considered deprecated. -The new interceptors concept in Grails 3.0 is superior in a number of ways, most significantly interceptors can using Groovy's @CompileStatic@ annotation to optimize performance (something which is often critical as interceptors can be executed for every request.) +The new interceptors concept in Grails 3.0 is superior in a number of ways, most significantly interceptors are using Groovy's @CompileStatic@ annotation to optimize performance (something which is often critical as interceptors can be executed for every request.) From cc7b64eca486a509dbc271b6c846105562d3a12d Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Sun, 28 Jun 2015 15:26:13 +0530 Subject: [PATCH 150/230] Defining Interceptors changes for clarity Fixed sentence as earlier one was having problem The code looked like it had been copy pasted from Interceptor. That was looking odd as per indentation. --- .../interceptors/definingInterceptors.gdoc | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/en/guide/theWebLayer/interceptors/definingInterceptors.gdoc b/src/en/guide/theWebLayer/interceptors/definingInterceptors.gdoc index 28fb9658528..07bb09bf09f 100644 --- a/src/en/guide/theWebLayer/interceptors/definingInterceptors.gdoc +++ b/src/en/guide/theWebLayer/interceptors/definingInterceptors.gdoc @@ -1,26 +1,26 @@ -By default interceptors will match the controller name they apply to be convention. For example if you have an interceptor called @BookInterceptor@ then all requests the actions of the @BookController@ will trigger the interceptor. +By default interceptors will match the controllers with the same name. For example if you have an interceptor called @BookInterceptor@ then all requests to the actions of the @BookController@ will trigger the interceptor. An @Interceptor@ implements the [Interceptor|api:grails.artefact.Interceptor] trait and provides 3 methods that can be used to intercept requests: {code} - /** - * Executed before a matched action - * - * @return Whether the action should continue and execute - */ - boolean before() { true } - - /** - * Executed after the action executes but prior to view rendering - * - * @return True if view rendering should continue, false otherwise - */ - boolean after() { true } - - /** - * Executed after view rendering completes - */ - void afterView() {} +/** + * Executed before a matched action + * + * @return Whether the action should continue and execute + */ +boolean before() { true } + +/** + * Executed after the action executes but prior to view rendering + * + * @return True if view rendering should continue, false otherwise + */ +boolean after() { true } + +/** + * Executed after view rendering completes + */ +void afterView() {} {code} As described above the @before@ method is executed prior to an action and can cancel the execution of the action by returning @false@. From 5ee29b9a02bab90fd3679d22124ac9abb2ff4cef Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Sun, 28 Jun 2015 15:29:35 +0530 Subject: [PATCH 151/230] Minor change to sentence Sentence was too long. --- src/en/guide/theWebLayer/interceptors/definingInterceptors.gdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/en/guide/theWebLayer/interceptors/definingInterceptors.gdoc b/src/en/guide/theWebLayer/interceptors/definingInterceptors.gdoc index 07bb09bf09f..8a7bbe8534f 100644 --- a/src/en/guide/theWebLayer/interceptors/definingInterceptors.gdoc +++ b/src/en/guide/theWebLayer/interceptors/definingInterceptors.gdoc @@ -37,4 +37,4 @@ boolean after() { } {code} -The @afterView@ method is executed after view rendering completes and if an exception occurs, the exception is available using the @throwable@ property of the [Interceptor|api:grails.artefact.Interceptor] trait. +The @afterView@ method is executed after view rendering completes. If an exception occurs, the exception is available using the @throwable@ property of the [Interceptor|api:grails.artefact.Interceptor] trait. From a20c9f0c1c9721ab06a2cec719cebece9641e06c Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Sun, 28 Jun 2015 15:56:20 +0530 Subject: [PATCH 152/230] Made uri details more precise "cannot be used in combination with other arguments" was not clear about what would happen if it is used together. Added the details for that. --- src/en/guide/theWebLayer/interceptors/interceptorMatching.gdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/en/guide/theWebLayer/interceptors/interceptorMatching.gdoc b/src/en/guide/theWebLayer/interceptors/interceptorMatching.gdoc index 40460720353..f464b6920f5 100644 --- a/src/en/guide/theWebLayer/interceptors/interceptorMatching.gdoc +++ b/src/en/guide/theWebLayer/interceptors/interceptorMatching.gdoc @@ -39,4 +39,4 @@ All named arguments accept either a String or a Regex expression. The possible n * @controller@ - The name of the controller * @action@ - The name of the action * @method@ - The HTTP method -* @uri@ - The URI of the request (cannot be used in combination with other arguments) +* @uri@ - The URI of the request. If this argument is used then all other arguments will be ignored and only this will be used. From 88d5949103a036bbd59c4db1b9cdbb014412d371 Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Sun, 28 Jun 2015 16:14:12 +0530 Subject: [PATCH 153/230] Interceptor - Added details for multiple matchers Looked through the Interceptor traits source code and found that any number of matchers can be defined. Added the missing information to the documentation. --- .../guide/theWebLayer/interceptors/interceptorMatching.gdoc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/en/guide/theWebLayer/interceptors/interceptorMatching.gdoc b/src/en/guide/theWebLayer/interceptors/interceptorMatching.gdoc index 40460720353..16b24d93de2 100644 --- a/src/en/guide/theWebLayer/interceptors/interceptorMatching.gdoc +++ b/src/en/guide/theWebLayer/interceptors/interceptorMatching.gdoc @@ -19,7 +19,6 @@ class AuthInterceptor { You can also perform matching using named argument: - {code} class LoggingInterceptor { LoggingInterceptor() { @@ -33,6 +32,11 @@ class LoggingInterceptor { } {code} +You can any number of matchers defined in your interceptor. They will be executed in the order in which they have been defined. For example the above interceptor will match for all of the following: + +* when the @show@ action of @BookController@ is called +* when @AuthorController@ or @PublisherController@ is called + All named arguments accept either a String or a Regex expression. The possible named arguments are: * @namespace@ - The namespace of the controller From 52d5e8356746e9a951b3425a920332d5fb00405f Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Sun, 28 Jun 2015 17:37:54 +0530 Subject: [PATCH 154/230] Fix grammar mistake --- src/en/guide/theWebLayer/interceptors/interceptorMatching.gdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/en/guide/theWebLayer/interceptors/interceptorMatching.gdoc b/src/en/guide/theWebLayer/interceptors/interceptorMatching.gdoc index 16b24d93de2..81163e0bdf5 100644 --- a/src/en/guide/theWebLayer/interceptors/interceptorMatching.gdoc +++ b/src/en/guide/theWebLayer/interceptors/interceptorMatching.gdoc @@ -32,7 +32,7 @@ class LoggingInterceptor { } {code} -You can any number of matchers defined in your interceptor. They will be executed in the order in which they have been defined. For example the above interceptor will match for all of the following: +You can use any number of matchers defined in your interceptor. They will be executed in the order in which they have been defined. For example the above interceptor will match for all of the following: * when the @show@ action of @BookController@ is called * when @AuthorController@ or @PublisherController@ is called From eb86e66b2bcdbce4c7152c05b2f2045dc1d2ac45 Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Sun, 28 Jun 2015 17:59:10 +0530 Subject: [PATCH 155/230] Added other directory for consistency --- src/en/guide/upgrading.gdoc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/en/guide/upgrading.gdoc b/src/en/guide/upgrading.gdoc index 0d31c0ff9f5..ad4ea831905 100644 --- a/src/en/guide/upgrading.gdoc +++ b/src/en/guide/upgrading.gdoc @@ -30,10 +30,12 @@ The location of certain files have changed or been replaced with other files in @src/java@ | @src/main/groovy@ | Moved for consistency with Gradle @test/unit@ | @src/test/groovy@ | Moved for consistency with Gradle @test/integration@ | @src/integration-test/groovy@ | Moved for consistency with Gradle -@web-app@ | @src/main/webapp@ | Moved for consistency with Gradle +@web-app@ | @src/main/webapp@ or @src/main/resources/@ | Moved for consistency with Gradle @\*GrailsPlugin.groovy@ | @src/main/groovy@ | The plugin descriptor moved to a source directory {table} +@src/main/resources/public@ is recommended as @src/main/webapp@ only gets included in WAR packaging but not in JAR packaging. + For plugins the plugin descriptor (a Groovy file ending with "GrailsPlugin") which was previously located in the root of the plugin directory should be moved to the @src/main/groovy@ directory under an appropriate package. h4. New Files Not Present in Grails 2.x @@ -61,5 +63,5 @@ Some files that were previously created by Grails 2.x are no longer created. The @web-app/WEB-INF/applicationContext.xml@ | Removed, beans can be defined in @grails-app/conf/spring/resources.groovy@ @src/templates/war/web.xml@ | Grails 3.0 no longer requires web.xml. Customizations can be done via Spring @web-app/WEB-INF/sitemesh.xml@ | Removed, sitemesh filter no longer present. -@web-app/WEB-INF/tld@ | Removed, can be restored in src/main/webapp +@web-app/WEB-INF/tld@ | Removed, can be restored in @src/main/webapp@ or @src/main/resources/WEB-INF@ {table} From 9fae1e86dd25ee14f43c7a81f98f6a63e1c66b5a Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Sun, 28 Jun 2015 18:02:42 +0530 Subject: [PATCH 156/230] Minor changes. Added note for reference --- src/en/guide/upgrading/upgradingApps.gdoc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/en/guide/upgrading/upgradingApps.gdoc b/src/en/guide/upgrading/upgradingApps.gdoc index f82cdcae83e..e085d8c5892 100644 --- a/src/en/guide/upgrading/upgradingApps.gdoc +++ b/src/en/guide/upgrading/upgradingApps.gdoc @@ -47,11 +47,13 @@ If you have a modified @web.xml@ template then you will need to migrate this to New servlets and filters can be registered as Spring beans or with [ServletRegistrationBean|api:org.springframework.boot.context.embedded.ServletRegistrationBean] and [FilterRegistrationBean|api:org.springframework.boot.context.embedded.FilterRegistrationBean] respectively. -h4. Migrate Static Assets not handled by Asset Pipeline +h4. Step 7 - Migrate Static Assets not handled by Asset Pipeline If you have static assets in your @web-app@ directory of your Grails 2.x application such as HTML files, TLDs etc. these need to be moved. For public assets such as static HTML pages and so on these should go in @src/main/resources/public@. -TLD descriptors and not public assets should go in @src/main/resources/WEB-INF@ . +TLD descriptors and non public assets should go in @src/main/resources/WEB-INF@. + +As noted earlier, @src/main/webapp@ folder can also be used for this purpose but it is not recommended. h4. Step 8 - Migrate Tests From 78a171c0648afaca948c6bddd2e468cf7c863bb4 Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Sun, 28 Jun 2015 18:23:09 +0530 Subject: [PATCH 157/230] fieldValue tag return value - Added clarity --- src/en/ref/Tags/fieldValue.gdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/en/ref/Tags/fieldValue.gdoc b/src/en/ref/Tags/fieldValue.gdoc index 53a3472321a..691f12f43a0 100644 --- a/src/en/ref/Tags/fieldValue.gdoc +++ b/src/en/ref/Tags/fieldValue.gdoc @@ -2,7 +2,7 @@ h1. fieldValue h2. Purpose -Inspects a bean which has been the subject of [data binding|guide:dataBinding] and obtains the value of the field either from the originally submitted value in the bean's @errors@ object populated during data binding or from the value of a bean's property. Once the value is obtained it will be automatically HTML-encoded. +Inspects a bean which has been the subject of [data binding|guide:dataBinding] and obtains the value of the field. If the bean had @errors@ during data binding then the originally submitted value is returned from the bean's @errors@ object else the value from the bean's property is returned. The value returned will be HTML-encoded. h2. Examples From 39a8ec14e20aa7c6b4a40744638d4f46a5cfdc9a Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Sun, 28 Jun 2015 19:40:34 +0530 Subject: [PATCH 158/230] Fix grammar mistake --- src/en/guide/theWebLayer/interceptors.gdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/en/guide/theWebLayer/interceptors.gdoc b/src/en/guide/theWebLayer/interceptors.gdoc index a2313644108..aedbdc7d3ef 100644 --- a/src/en/guide/theWebLayer/interceptors.gdoc +++ b/src/en/guide/theWebLayer/interceptors.gdoc @@ -26,4 +26,4 @@ h4. Interceptors vs Filters In versions of Grails prior to Grails 3.0, Grails supported the notion of filters. These are still supported for backwards compatibility but are considered deprecated. -The new interceptors concept in Grails 3.0 is superior in a number of ways, most significantly interceptors are using Groovy's @CompileStatic@ annotation to optimize performance (something which is often critical as interceptors can be executed for every request.) +The new interceptors concept in Grails 3.0 is superior in a number of ways, most significantly interceptors can use Groovy's @CompileStatic@ annotation to optimize performance (something which is often critical as interceptors can be executed for every request.) From 23de719fa1aee0b2d9774bc53209582a518fe03f Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Sun, 28 Jun 2015 19:48:41 +0530 Subject: [PATCH 159/230] Removing DataSource.groovy from Documentation --- src/en/guide/conf/dataSource.gdoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/en/guide/conf/dataSource.gdoc b/src/en/guide/conf/dataSource.gdoc index 840e0ed2c2f..42ae985c278 100644 --- a/src/en/guide/conf/dataSource.gdoc +++ b/src/en/guide/conf/dataSource.gdoc @@ -12,7 +12,7 @@ Drivers typically come in the form of a JAR archive. It's best to use the depend If you can't use dependency resolution then just put the JAR in your project's @lib@ directory. -Once you have the JAR resolved you need to get familiar with Grails' DataSource descriptor file located at @grails-app/conf/DataSource.groovy@. This file contains the dataSource definition which includes the following settings: +Once you have the JAR resolved you need to get familiar with how Grails manages its database configuration. The configuration can be maintained in either @grails-app/conf/application.groovy@ or @grails-app/conf/application.yml@. These files contain the dataSource definition which includes the following settings: * @driverClassName@ - The class name of the JDBC driver * @username@ - The username used to establish a JDBC connection @@ -29,7 +29,7 @@ Once you have the JAR resolved you need to get familiar with Grails' DataSource * @properties@ - Extra properties to set on the DataSource bean. See the [Tomcat Pool|http://tomcat.apache.org/tomcat-7.0-doc/jdbc-pool.html#Common_Attributes] documentation. There is also a Javadoc format [documentation of the properties|https://tomcat.apache.org/tomcat-7.0-doc/api/org/apache/tomcat/jdbc/pool/PoolConfiguration.html]. * @jmxExport@ - If @false@, will disable registration of JMX MBeans for all DataSources. By default JMX MBeans are added for DataSources with @jmxEnabled = true@ in properties. -A typical configuration for MySQL may be something like: +A typical configuration for MySQL in @application.groovy@ may be something like: {code:java} dataSource { From a66ebfad33d4031491027e466c80ae371dd4cba7 Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Sun, 28 Jun 2015 19:51:59 +0530 Subject: [PATCH 160/230] Removal of DataSource.groovy --- src/en/guide/conf/dataSource/databaseConsole.gdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/en/guide/conf/dataSource/databaseConsole.gdoc b/src/en/guide/conf/dataSource/databaseConsole.gdoc index af068f0310b..fe6a0373f53 100644 --- a/src/en/guide/conf/dataSource/databaseConsole.gdoc +++ b/src/en/guide/conf/dataSource/databaseConsole.gdoc @@ -26,4 +26,4 @@ If you enable the console in production be sure to guard access to it using a tr h4. Configuration -By default the console is configured for an H2 database which will work with the default settings if you haven't configured an external database - you just need to change the JDBC URL to @jdbc:h2:mem:devDB@. If you've configured an external database (e.g. MySQL, Oracle, etc.) then you can use the Saved Settings dropdown to choose a settings template and fill in the url and username/password information from your DataSource.groovy. +By default the console is configured for an H2 database which will work with the default settings if you haven't configured an external database - you just need to change the JDBC URL to @jdbc:h2:mem:devDB@. If you've configured an external database (e.g. MySQL, Oracle, etc.) then you can use the Saved Settings dropdown to choose a settings template and fill in the url and username/password information from your @application.groovy@. From 307253692107b8fc7b34253df57ce8ff5ffdef81 Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Sun, 28 Jun 2015 19:53:23 +0530 Subject: [PATCH 161/230] Removal of DataSource.groovy --- src/en/guide/conf/dataSource/multipleDatasources.gdoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/en/guide/conf/dataSource/multipleDatasources.gdoc b/src/en/guide/conf/dataSource/multipleDatasources.gdoc index 2bef936f5c5..670b1be24dd 100644 --- a/src/en/guide/conf/dataSource/multipleDatasources.gdoc +++ b/src/en/guide/conf/dataSource/multipleDatasources.gdoc @@ -2,7 +2,7 @@ By default all domain classes share a single @DataSource@ and a single database, h4. Configuring Additional DataSources -The default @DataSource@ configuration in @grails-app/conf/DataSource.groovy@ looks something like this: +The default @DataSource@ configuration in @grails-app/conf/application.yml@ looks something like this: {code} --- @@ -239,4 +239,4 @@ When the Best Efforts 1PC pattern isn't suitable for handling transactions acros The [Spring transactions documentation|http://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/transaction.html#transaction-application-server-integration] contains information about integrating the JTA/XA transaction manager of different application servers. In this case, you can configure a bean with the name @transactionManager@ manually in @resources.groovy@ or @resources.xml@ file. -There is also [Atomikos plugin|http://grails.org/plugin/atomikos] available for XA support in Grails applications. \ No newline at end of file +There is also [Atomikos plugin|http://grails.org/plugin/atomikos] available for XA support in Grails applications. From 00ce7d46b1ceda24bd646e3d59926937ea6fe113 Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Sun, 28 Jun 2015 19:56:10 +0530 Subject: [PATCH 162/230] Removal of DataSource.groovy --- src/en/guide/GORM/advancedGORMFeatures/ormdsl/caching.gdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/en/guide/GORM/advancedGORMFeatures/ormdsl/caching.gdoc b/src/en/guide/GORM/advancedGORMFeatures/ormdsl/caching.gdoc index e642102b06c..5cf32cc0e6a 100644 --- a/src/en/guide/GORM/advancedGORMFeatures/ormdsl/caching.gdoc +++ b/src/en/guide/GORM/advancedGORMFeatures/ormdsl/caching.gdoc @@ -105,4 +105,4 @@ Below is a description of the different cache settings and their usages: * @read-only@ - If your application needs to read but never modify instances of a persistent class, a read-only cache may be used. * @read-write@ - If the application needs to update data, a read-write cache might be appropriate. * @nonstrict-read-write@ - If the application only occasionally needs to update data (i.e. if it is very unlikely that two transactions would try to update the same item simultaneously) and strict transaction isolation is not required, a @nonstrict-read-write@ cache might be appropriate. -* @transactional@ - The @transactional@ cache strategy provides support for fully transactional cache providers such as JBoss TreeCache. Such a cache may only be used in a JTA environment and you must specify @hibernate.transaction.manager_lookup_class@ in the @grails-app/conf/DataSource.groovy@ file's @hibernate@ config. +* @transactional@ - The @transactional@ cache strategy provides support for fully transactional cache providers such as JBoss TreeCache. Such a cache may only be used in a JTA environment and you must specify @hibernate.transaction.manager_lookup_class@ in the @grails-app/conf/application.groovy@ file's @hibernate@ config. From d08687ed05cbb5bd4bc729d21927f272a72ac975 Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Sun, 28 Jun 2015 19:57:42 +0530 Subject: [PATCH 163/230] Removal of DataSource.groovy --- .../GORM/advancedGORMFeatures/ormdsl/customNamingStrategy.gdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/en/guide/GORM/advancedGORMFeatures/ormdsl/customNamingStrategy.gdoc b/src/en/guide/GORM/advancedGORMFeatures/ormdsl/customNamingStrategy.gdoc index fb91beadd29..a7d3ec96bc7 100644 --- a/src/en/guide/GORM/advancedGORMFeatures/ormdsl/customNamingStrategy.gdoc +++ b/src/en/guide/GORM/advancedGORMFeatures/ormdsl/customNamingStrategy.gdoc @@ -1,6 +1,6 @@ By default Grails uses Hibernate's @ImprovedNamingStrategy@ to convert domain class Class and field names to SQL table and column names by converting from camel-cased Strings to ones that use underscores as word separators. You can customize these on a per-class basis in the @mapping@ closure but if there's a consistent pattern you can specify a different @NamingStrategy@ class to use. -Configure the class name to be used in @grails-app/conf/DataSource.groovy@ in the @hibernate@ section, e.g. +Configure the class name to be used in @grails-app/conf/application.groovy@ in the @hibernate@ section, e.g. {code:java} dataSource { From 3a84e4dc933abdf19eb225659ff13eadec32cdef Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Sun, 28 Jun 2015 20:00:12 +0530 Subject: [PATCH 164/230] Removal of DataSource.groovy --- src/en/guide/hibernate/usingHibernateXMLMappingFiles.gdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/en/guide/hibernate/usingHibernateXMLMappingFiles.gdoc b/src/en/guide/hibernate/usingHibernateXMLMappingFiles.gdoc index 51c70cc24bb..2db70c89261 100644 --- a/src/en/guide/hibernate/usingHibernateXMLMappingFiles.gdoc +++ b/src/en/guide/hibernate/usingHibernateXMLMappingFiles.gdoc @@ -16,7 +16,7 @@ Mapping your domain classes with XML is pretty straightforward. Simply create a The individual mapping files, like 'org.example.Book.hbm.xml' in the above example, also go into the @grails-app/conf@ directory. To find out how to map domain classes with XML, check out the [Hibernate manual|http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html/mapping.html]. -If the default location of the @hibernate.cfg.xml@ file doesn't suit you, you can change it by specifying an alternative location in @grails-app/conf/DataSource.groovy@: +If the default location of the @hibernate.cfg.xml@ file doesn't suit you, you can change it by specifying an alternative location in @grails-app/conf/application.groovy@: {code} hibernate { From 3126171b5cbd483b64678b7e9a04410583a3db0c Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Sun, 28 Jun 2015 20:21:18 +0530 Subject: [PATCH 165/230] Added attributes from the source into docs --- src/en/ref/Tags/pageProperty.gdoc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/en/ref/Tags/pageProperty.gdoc b/src/en/ref/Tags/pageProperty.gdoc index bb4a3b3b492..a30c0a44572 100644 --- a/src/en/ref/Tags/pageProperty.gdoc +++ b/src/en/ref/Tags/pageProperty.gdoc @@ -40,6 +40,14 @@ Results in: {code} +h2. Description + +Attributes + +* @name@ (required) - The property name +* @default@ (optional) - The default value to use if the property is null. (defaults to null) +* @writeEntireProperty@ (optional) - If true, writes the property in the form 'foo = "bar"', otherwise renders 'bar'. (defaults to false) + h2. Source {source:tag=RenderTagLib.pageProperty} From 655c62ebd37e9d587fdc98f66cdb3f5b08e7aed2 Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Sun, 28 Jun 2015 20:53:29 +0530 Subject: [PATCH 166/230] Added detailed example for pageProperty tag --- src/en/ref/Tags/pageProperty.gdoc | 63 +++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/src/en/ref/Tags/pageProperty.gdoc b/src/en/ref/Tags/pageProperty.gdoc index a30c0a44572..df4fcda89f5 100644 --- a/src/en/ref/Tags/pageProperty.gdoc +++ b/src/en/ref/Tags/pageProperty.gdoc @@ -40,6 +40,69 @@ Results in: {code} +Another example with more options used is below: + +We have a layout gsp file @container.gsp@ + +{code:xml} +
+
+ +
+ +
+ +
+
+{code} + +The layout is applied to a sub-part of the @gsp@ file using @applyLayout@ tag. + +{code:xml} + + + Title 1 + + + +
+ + + Title 2 + + Some other things + +
+ + +{code} + +This will result in the below page. + +{code:xml} + + + Title 1 + + + +
+
+
+ Title 2 +
+ +
+ Some other things +
+
+
+ + +{code} + +Notice how "Title 2" from the @content@ tag was picked via @page.title@ and the rest was picked up by @@. You can have any number of such @content@ tags with different tag values (e.g. @tag="grails"@) and then use them in your layouts via the @pageProperty@ tag. + h2. Description Attributes From 726afd233ca3777600258421ac6543337d90bc8e Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Mon, 29 Jun 2015 02:15:33 +0530 Subject: [PATCH 167/230] Fix for Config.groovy being replaced --- .../guide/theWebLayer/contentNegotiation.gdoc | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/en/guide/theWebLayer/contentNegotiation.gdoc b/src/en/guide/theWebLayer/contentNegotiation.gdoc index 38d8573ccd9..fa9a6798959 100644 --- a/src/en/guide/theWebLayer/contentNegotiation.gdoc +++ b/src/en/guide/theWebLayer/contentNegotiation.gdoc @@ -2,7 +2,36 @@ Grails has built in support for [Content negotiation|http://en.wikipedia.org/wik h4. Configuring Mime Types -Before you can start dealing with content negotiation you need to tell Grails what content types you wish to support. By default Grails comes configured with a number of different content types within @grails-app/conf/Config.groovy@ using the @grails.mime.types@ setting: +Before you can start dealing with content negotiation you need to tell Grails what content types you wish to support. By default Grails comes configured with a number of different content types within @grails-app/conf/application.yml@ using the @grails.mime.types@ setting: + +{code:java} +grails: + mime: + types: + all: '*/*' + atom: application/atom+xml + css: text/css + csv: text/csv + form: application/x-www-form-urlencoded + html: + - text/html + - application/xhtml+xml + js: text/javascript + json: + - application/json + - text/json + multipartForm: multipart/form-data + rss: application/rss+xml + text: text/plain + hal: + - application/hal+json + - application/hal+xml + xml: + - text/xml + - application/xml +{code} + +The setting can also be done in @grails-app/conf/application.groovy@ as shown below: {code:java} grails.mime.types = [ // the first one is the default format From 32b259f0d0bb4b7e50022afdb61dfa04cb35069e Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Mon, 29 Jun 2015 02:29:55 +0530 Subject: [PATCH 168/230] Merged duplicate documentation Content Negotiation with the format Request Parameter was present in two places. Merged their contents --- .../guide/theWebLayer/contentNegotiation.gdoc | 30 ++++++++----------- 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/src/en/guide/theWebLayer/contentNegotiation.gdoc b/src/en/guide/theWebLayer/contentNegotiation.gdoc index 38d8573ccd9..19737d94660 100644 --- a/src/en/guide/theWebLayer/contentNegotiation.gdoc +++ b/src/en/guide/theWebLayer/contentNegotiation.gdoc @@ -25,7 +25,7 @@ grails.mime.types = [ // the first one is the default format The above bit of configuration allows Grails to detect to format of a request containing either the 'text/xml' or 'application/xml' media types as simply 'xml'. You can add your own types by simply adding new entries into the map. The first one is the default format. -h4. Content Negotiation using the format parameter +h4. Content Negotiation using the format Request Parameter Let's say a controller action can return a resource in a variety of formats: HTML, XML, and JSON. What format will the client get? The easiest and most reliable way for the client to control this is through a @format@ URL parameter. @@ -35,7 +35,17 @@ So if you, as a browser or some other client, want a resource as XML, you can us http://my.domain.org/books?format=xml {code} -The result of this on the server side is a @format@ property on the @response@ object with the value @xml@ . You could code your controller action to return XML based on this property, but you can also make use of the controller-specific @withFormat()@ method: +The result of this on the server side is a @format@ property on the @response@ object with the value @xml@ . + +You can also define this parameter in the [URL Mappings|guide:urlmappings] definition: + +{code:java} +"/book/list"(controller:"book", action:"list") { + format = "xml" +} +{code} + +You could code your controller action to return XML based on this property, but you can also make use of the controller-specific @withFormat()@ method: {code:java} import grails.converters.JSON @@ -128,22 +138,6 @@ request.withFormat { } {code} -h4. Content Negotiation with the format Request Parameter - -If fiddling with request headers if not your favorite activity you can override the format used by specifying a @format@ request parameter: - -{code:java} -/book/list?format=xml -{code} - -You can also define this parameter in the [URL Mappings|guide:urlmappings] definition: - -{code:java} -"/book/list"(controller:"book", action:"list") { - format = "xml" -} -{code} - h4. Content Negotiation with URI Extensions Grails also supports content negotiation using URI extensions. For example given the following URI: From ed2fe7341b77afb874ce9b09c439797bf321ed62 Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Mon, 29 Jun 2015 02:39:46 +0530 Subject: [PATCH 169/230] Fix Url Mappings file location --- src/en/guide/theWebLayer/urlmappings.gdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/en/guide/theWebLayer/urlmappings.gdoc b/src/en/guide/theWebLayer/urlmappings.gdoc index 9139b666abb..a5b49192a60 100644 --- a/src/en/guide/theWebLayer/urlmappings.gdoc +++ b/src/en/guide/theWebLayer/urlmappings.gdoc @@ -1,4 +1,4 @@ -Throughout the documentation so far the convention used for URLs has been the default of @/controller/action/id@. However, this convention is not hard wired into Grails and is in fact controlled by a URL Mappings class located at @grails-app/conf/UrlMappings.groovy@. +Throughout the documentation so far the convention used for URLs has been the default of @/controller/action/id@. However, this convention is not hard wired into Grails and is in fact controlled by a URL Mappings class located at @grails-app/controllers/UrlMappings.groovy@. The @UrlMappings@ class contains a single property called @mappings@ that has been assigned a block of code: From 08e134d434b73bf52661076c27d62b39cd8496fb Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Mon, 29 Jun 2015 02:42:57 +0530 Subject: [PATCH 170/230] Updated UrlMappings.groovy location --- src/en/guide/theWebLayer/urlmappings/namespacedControllers.gdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/en/guide/theWebLayer/urlmappings/namespacedControllers.gdoc b/src/en/guide/theWebLayer/urlmappings/namespacedControllers.gdoc index 060d33c5dd9..bfd48506571 100644 --- a/src/en/guide/theWebLayer/urlmappings/namespacedControllers.gdoc +++ b/src/en/guide/theWebLayer/urlmappings/namespacedControllers.gdoc @@ -32,7 +32,7 @@ When defining url mappings which should be associated with a namespaced controller, the @namespace@ variable needs to be part of the URL mapping. {code} -// grails-app/conf/UrlMappings.groovy +// grails-app/controllers/UrlMappings.groovy class UrlMappings { static mappings = { From 852cad6e549aaceb9ff941519b03223d050e9610 Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Mon, 29 Jun 2015 03:00:38 +0530 Subject: [PATCH 171/230] Changed heading to remove two headings --- src/en/guide/toc.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/en/guide/toc.yml b/src/en/guide/toc.yml index fd1eef8bb06..0fc022e1546 100644 --- a/src/en/guide/toc.yml +++ b/src/en/guide/toc.yml @@ -183,7 +183,7 @@ theWebLayer: traits: title: Traits traitsprovided: - title: Traits Provided + title: Traits Provided by Grails example: title: WebAttributes Trait Example webServices: From b4c166cacf1b3062f97b555fdec5b25469653ca8 Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Mon, 29 Jun 2015 03:02:20 +0530 Subject: [PATCH 172/230] Removed heading as there were two headings --- src/en/guide/traits/traitsprovided.gdoc | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/en/guide/traits/traitsprovided.gdoc b/src/en/guide/traits/traitsprovided.gdoc index 9d856912427..d948ed94bb7 100644 --- a/src/en/guide/traits/traitsprovided.gdoc +++ b/src/en/guide/traits/traitsprovided.gdoc @@ -1,5 +1,3 @@ -h2. Traits Provided By Grails - Grails artefacts are automatically augmented with certain traits at compile time. h4. Domain Class Traits From dcb6a80f500723f91d8602f8e1f8639ac0f92be9 Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Mon, 29 Jun 2015 03:09:39 +0530 Subject: [PATCH 173/230] Added about the command url-mappings-report Recently came to know the command `url-mappings-report`. This can be really helpful --- src/en/guide/theWebLayer/urlmappings/restfulMappings.gdoc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/en/guide/theWebLayer/urlmappings/restfulMappings.gdoc b/src/en/guide/theWebLayer/urlmappings/restfulMappings.gdoc index bf254478fe5..f737164276c 100644 --- a/src/en/guide/theWebLayer/urlmappings/restfulMappings.gdoc +++ b/src/en/guide/theWebLayer/urlmappings/restfulMappings.gdoc @@ -18,6 +18,8 @@ You define a base URI and the name of the controller to map to using the @resour DELETE |/books/${id} | delete {table} +If you are not sure which mapping will be generated for your case just run the command @url-mappings-report@ in your grails console. It will give you a really neat report for all the url mappings. + If you wish to include or exclude any of the generated URL mappings you can do so with the @includes@ or @excludes@ parameter, which accepts the name of the Grails action to include or exclude: {code} From 1f61e8a0d7eaea1a08819daa0de0fca31597e410 Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Tue, 30 Jun 2015 00:05:27 +0530 Subject: [PATCH 174/230] Updated the sample output of plugin-info command --- src/en/ref/Command Line/plugin-info.gdoc | 27 +++++++++++------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/src/en/ref/Command Line/plugin-info.gdoc b/src/en/ref/Command Line/plugin-info.gdoc index 1a37e40351f..d80bdacb762 100644 --- a/src/en/ref/Command Line/plugin-info.gdoc +++ b/src/en/ref/Command Line/plugin-info.gdoc @@ -17,21 +17,18 @@ Usage: grails plugin-info [name] {code} -This command will display more detailed info about a given plugin such as the author, location of documentation and so on. An example of the output of the Shiro plugin can be seen below: +This command will display more detailed info about a given plugin such as the author, location of documentation and so on. An example of the output of the geb plugin can be seen below: {code} --------------------------------------------------------------------------- -Information about Grails plugin --------------------------------------------------------------------------- -Name: shiro | Latest release: 1.1.3 --------------------------------------------------------------------------- -Apache Shiro Integration for Grails --------------------------------------------------------------------------- -Author: Peter Ledbrook --------------------------------------------------------------------------- -Find more info here: http://grails.org/Shiro+Plugin --------------------------------------------------------------------------- -Enables Grails applications to take advantage of the Apache Shiro security layer. -Adopted from previous JSecurity plugin. --------------------------------------------------------------------------- +| Plugin Info: geb +| Latest Version: 1.0.1-SNAPSHOT +| All Versions: 1.0-SNAPSHOT,1.0.0.M1,1.0.0.M2,1.0.0.M3,1.0.0.M4,1.0.0,1.0.0.BUILD-SNAPSHOT,1.0.1-SNAPSHOT +| Title: Geb Plugin + +Plugin that adds Geb functional testing code generation features. + +* License: APACHE +* Documentation: http://grails.org/plugin/geb +* Issue Tracker: http://github.com/grails3-plugins/geb/issues +* Source: http://github.com/grails3-plugins/geb {code} From ea46cf0ce59bbf816b4ac5eb4c2fe1dd1a2980ae Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Wed, 1 Jul 2015 13:12:10 +0530 Subject: [PATCH 175/230] Updated documentation for generating docs --- src/en/guide/conf/docengine.gdoc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/en/guide/conf/docengine.gdoc b/src/en/guide/conf/docengine.gdoc index b612f19038c..665b3f147ce 100644 --- a/src/en/guide/conf/docengine.gdoc +++ b/src/en/guide/conf/docengine.gdoc @@ -67,10 +67,16 @@ One of the simplest ways to customise the look of the generated guide is to prov h4. Generating Documentation +Add the plugin in your @build.gradle@: + +{code} +apply plugin: "org.grails.grails-doc" +{code} + Once you have created some documentation (refer to the syntax guide in the next chapter) you can generate an HTML version of the documentation using the command: {code} -grails doc +gradle docs {code} This command will output an @docs/manual/index.html@ which can be opened in a browser to view your documentation. From e200712cb9b9af7f6f07444b5df3445b8888bb29 Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Wed, 1 Jul 2015 13:14:06 +0530 Subject: [PATCH 176/230] Updated reference documentation --- src/en/ref/Command Line/{doc.gdoc => docs.gdoc} | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) rename src/en/ref/Command Line/{doc.gdoc => docs.gdoc} (91%) diff --git a/src/en/ref/Command Line/doc.gdoc b/src/en/ref/Command Line/docs.gdoc similarity index 91% rename from src/en/ref/Command Line/doc.gdoc rename to src/en/ref/Command Line/docs.gdoc index 99f4207576d..954198ee078 100644 --- a/src/en/ref/Command Line/doc.gdoc +++ b/src/en/ref/Command Line/docs.gdoc @@ -1,4 +1,4 @@ -h1. doc +h1. docs h2. Purpose @@ -6,8 +6,16 @@ Generates a user guide and Javadoc + Groovydoc API documentation for the current h2. Examples -{code:java} -grails doc +Add the plugin in your @build.gradle@: + +{code} +apply plugin: "org.grails.grails-doc" +{code} + +Now run the command + +{code} +gradle docs {code} h2. Description From 1748cc86aed3b61a2213cc20dd24b7cdc4f356af Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Thu, 2 Jul 2015 11:35:45 +0530 Subject: [PATCH 177/230] Added stop-app documentation docs for stop-app added in https://github.com/grails/grails-core/issues/641 --- src/en/ref/Command Line/stop-app | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 src/en/ref/Command Line/stop-app diff --git a/src/en/ref/Command Line/stop-app b/src/en/ref/Command Line/stop-app new file mode 100644 index 00000000000..2f4515fa65b --- /dev/null +++ b/src/en/ref/Command Line/stop-app @@ -0,0 +1,19 @@ +h1. stop-app + +h2. Purpose + +Stops a running Grails application in an embedded servlet container + +h2. Examples + +{code:java} +grails stop-app +grails -Dserver.port=8090 stop-app +{code} + +h2. Description + +Supported system properties: + +* @server.port@ - Specifies the port which the Grails application is running on (defaults to 8080 for HTTP or 8443 for HTTPS) +* @server.address@ - Specifies the host the Grails application is bound to From a4acc8eceb691750430bb4bd4ce5a5532b2e4018 Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Thu, 2 Jul 2015 12:31:56 +0530 Subject: [PATCH 178/230] Updated example and added arguments --- src/en/ref/Command Line/stop-app | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/en/ref/Command Line/stop-app b/src/en/ref/Command Line/stop-app index 2f4515fa65b..6cd49384888 100644 --- a/src/en/ref/Command Line/stop-app +++ b/src/en/ref/Command Line/stop-app @@ -8,12 +8,17 @@ h2. Examples {code:java} grails stop-app -grails -Dserver.port=8090 stop-app +grails stop-app --port=9090 --host=mywebsite {code} h2. Description +Arguments: + +* @port@ - Specifies the port which the Grails application is running on (defaults to 8080 for HTTP or 8443 for HTTPS) +* @host@ - Specifies the host the Grails application is bound to + Supported system properties: -* @server.port@ - Specifies the port which the Grails application is running on (defaults to 8080 for HTTP or 8443 for HTTPS) -* @server.address@ - Specifies the host the Grails application is bound to +* @server.port@ - Same as @port@ argument. +* @server.address@ - Same as @host@ argument. From 9d99a0a2a99e3952a5cebc4b7a7b7bf70590535f Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Thu, 2 Jul 2015 19:51:56 +0530 Subject: [PATCH 179/230] Removing alias documentation as this command has been removed in grails 3 --- src/en/ref/Command Line/alias.gdoc | 106 ----------------------------- 1 file changed, 106 deletions(-) delete mode 100644 src/en/ref/Command Line/alias.gdoc diff --git a/src/en/ref/Command Line/alias.gdoc b/src/en/ref/Command Line/alias.gdoc deleted file mode 100644 index 43304b6dda6..00000000000 --- a/src/en/ref/Command Line/alias.gdoc +++ /dev/null @@ -1,106 +0,0 @@ -h1. alias - -h2. Purpose - -Configures Grails command aliases. - -h2. Examples - -{code:java} -grails alias ra run-app -grails alias rft test-app functional: -grails alias --list -grails alias rft -grails alias --delete=ra -{code} - -h2. Description - -Aliases can be defined to associate names with commands. The alias may be considerably shorter and/or more expressive than the corresponding command. For example, the command to run all of the integration tests in an application is usually something like this: - -{code:java} -grails test-app integration: -{code} - -An alias named run-integration-tests could be configured to do the same thing: - -{code:java} -grails alias run-integration-tests test-app integration: -{code} - -After defining that alias the integration tests may be run with this: - -{code:java} -grails run-integration-tests -{code} - -A shorter version of that alias might look something like this: - -{code:java} -grails alias rit test-app integration: -{code} - -After defining that alias the integration tests may be run with this: - -{code:java} -grails rit -{code} - -Usage: -{code:java} - grails alias [--delete=alias] [--list] [alias [command]] -{code} - -To configure a new alias or to update an existing alias: - -{code:java} -grails alias [alias command] -{code} - -@alias@ is the name of the alias and @command@ is the command to be associated with that alias. For example, the following creates an alias named @rit@ that will run all of the integration tests in an application: - -{code:java} -grails alias rit test-app integration: -{code} - -To display the value of an existing alias: - -{code:java} -grails alias [alias] -{code} - -Example: - -{code:java} -grails alias rit -rit = test-app integration: -{code} - -To list all configured aliases: - -{code:java} -grails alias --list -{code} - -To delete an alias: - -{code:java} -grails alias --delete= -{code} - -Example: - -{code:java} -grails alias --delete=rit -{code} - -h3. Limitations - -Alias definitions may include parameters such as the "unit:" argument in "grails alias rut test-app unit:" but may not include command line switches that begin with a "\-" or "\-\-" as those will be consumed by the alias command itself. For example the command "grails alias up upgrade \-\-non-interactive" creates an alias named "up" which will execute "upgrade" not "upgrade --non-interactive". The "\-\-non-interactive" switch in the original alias command is applied to the alias command itself, not the alias being defined. When aliases are invoked, additional switches may be applied like "grails up \-\-non-interactive". - -Alias definitions may not refer to other aliases. - - - - - From 4e929bbb3282342fe4d040408dd09c554d833a57 Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Fri, 3 Jul 2015 13:43:18 +0530 Subject: [PATCH 180/230] Removed incorrect information as per Grails 3.0.2 --- src/en/ref/Command Line/list-plugins.gdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/en/ref/Command Line/list-plugins.gdoc b/src/en/ref/Command Line/list-plugins.gdoc index bbfbb2c31b1..c0095a1e454 100644 --- a/src/en/ref/Command Line/list-plugins.gdoc +++ b/src/en/ref/Command Line/list-plugins.gdoc @@ -34,4 +34,4 @@ Lists the plugins that are installable. Note: This command can take a while to e * scaffolding {code} -The first column contains the plugin name, the second the version and the last the description. If you require more info about a plugin you can use the [plugin-info|commandLine] command. +If you require more info about a plugin you can use the [plugin-info|commandLine] command. From 0e52ba9bf082ce9913c759a70240d3778a2572ff Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Fri, 3 Jul 2015 19:43:48 +0530 Subject: [PATCH 181/230] Quotes mismatch in code --- src/en/guide/commandLine/gradleBuild/gradleDependencies.gdoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/en/guide/commandLine/gradleBuild/gradleDependencies.gdoc b/src/en/guide/commandLine/gradleBuild/gradleDependencies.gdoc index 7d0b66fcb4e..950dca4ce4f 100644 --- a/src/en/guide/commandLine/gradleBuild/gradleDependencies.gdoc +++ b/src/en/guide/commandLine/gradleBuild/gradleDependencies.gdoc @@ -18,8 +18,8 @@ dependencies { runtime 'org.grails.plugins:asset-pipeline' runtime 'org.grails.plugins:scaffolding' - testCompile "org.grails:grails-plugin-testing' - testCompile "org.grails.plugins:geb' + testCompile 'org.grails:grails-plugin-testing' + testCompile 'org.grails.plugins:geb' // Note: It is recommended to update to a more robust driver (Chrome, Firefox etc.) testRuntime 'org.seleniumhq.selenium:selenium-htmlunit-driver:2.44.0' From 1874e4ea0ed24b569f1cf69e0ad94f7eba6e65df Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Fri, 3 Jul 2015 21:09:07 +0530 Subject: [PATCH 182/230] Changed Config.groovy to application.groovy --- src/en/guide/conf/docengine.gdoc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/en/guide/conf/docengine.gdoc b/src/en/guide/conf/docengine.gdoc index 665b3f147ce..06378c64feb 100644 --- a/src/en/guide/conf/docengine.gdoc +++ b/src/en/guide/conf/docengine.gdoc @@ -45,7 +45,7 @@ Reference items appear in the Quick Reference section of the documentation. Each h4. Configuring Output Properties -There are various properties you can set within your @grails-app/conf/Config.groovy@ file that customize the output of the documentation such as: +There are various properties you can set within your @grails-app/conf/application.groovy@ file that customize the output of the documentation such as: * *grails.doc.title* - The title of the documentation * *grails.doc.subtitle* - The subtitle of the documentation @@ -115,7 +115,7 @@ You can also link to internal images like so: \!someFolder/my_diagram.png\! {code} -This will link to an image stored locally within your project. There is currently no default location for doc images, but you can specify one with the @grails.doc.images@ setting in Config.groovy like so: +This will link to an image stored locally within your project. There is currently no default location for doc images, but you can specify one with the @grails.doc.images@ setting in application.groovy like so: {code} grails.doc.images = new File("src/docs/images") @@ -159,7 +159,7 @@ Finally, to link to external APIs you can use the @api:@ prefix. For example: [String|api:java.lang.String] {code} -The documentation engine will automatically create the appropriate javadoc link in this case. To add additional APIs to the engine you can configure them in @grails-app/conf/Config.groovy@. For example: +The documentation engine will automatically create the appropriate javadoc link in this case. To add additional APIs to the engine you can configure them in @grails-app/conf/application.groovy@. For example: {code} grails.doc.api.org.hibernate= From 56543f30bb5aea654a8c6827383ef824dcbf3f61 Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Mon, 6 Jul 2015 15:43:44 +0530 Subject: [PATCH 183/230] Missing extension for stop-app command --- src/en/ref/Command Line/{stop-app => stop-app.gdoc} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/en/ref/Command Line/{stop-app => stop-app.gdoc} (100%) diff --git a/src/en/ref/Command Line/stop-app b/src/en/ref/Command Line/stop-app.gdoc similarity index 100% rename from src/en/ref/Command Line/stop-app rename to src/en/ref/Command Line/stop-app.gdoc From dc9b79fd57d0d330e11a2a3bffb75d0986f94877 Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Mon, 6 Jul 2015 17:25:44 +0530 Subject: [PATCH 184/230] Fix version explanation --- src/en/guide/plugins/creatingAndInstallingPlugins.gdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/en/guide/plugins/creatingAndInstallingPlugins.gdoc b/src/en/guide/plugins/creatingAndInstallingPlugins.gdoc index aa73f2637e1..21264a14769 100644 --- a/src/en/guide/plugins/creatingAndInstallingPlugins.gdoc +++ b/src/en/guide/plugins/creatingAndInstallingPlugins.gdoc @@ -41,7 +41,7 @@ All plugins must have this class under the @src/main/groovy@ directory, otherwis You can also provide additional information about your plugin using several special properties: * @title@ - short one-sentence description of your plugin -* @grailsVersion@ - The version of version range of Grails that the plugin supports. eg. "1.2 > *" (indicating 1.2 or higher) +* @grailsVersion@ - The version range of Grails that the plugin supports. eg. "1.2 > *" (indicating 1.2 or higher) * @author@ - plugin author's name * @authorEmail@ - plugin author's contact e-mail * @description@ - full multi-line description of plugin's features From a7bf0c5b1df100b8f9ed3679a81da07a40f8f219 Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Mon, 6 Jul 2015 21:38:35 +0530 Subject: [PATCH 185/230] Fixed locations of the plugin example files --- src/en/guide/plugins/artefactApi/customArtefacts.gdoc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/en/guide/plugins/artefactApi/customArtefacts.gdoc b/src/en/guide/plugins/artefactApi/customArtefacts.gdoc index 615d1226997..7808f1619c4 100644 --- a/src/en/guide/plugins/artefactApi/customArtefacts.gdoc +++ b/src/en/guide/plugins/artefactApi/customArtefacts.gdoc @@ -15,8 +15,8 @@ In addition to the handler itself, every new artefact needs a corresponding wrap The best way to understand how both the handler and wrapper classes work is to look at the Quartz plugin: -* [GrailsJobClass|http://github.com/nebolsin/grails-quartz/blob/master/src/java/grails/plugins/quartz/GrailsJobClass.java] -* [DefaultGrailsJobClass|http://github.com/nebolsin/grails-quartz/blob/master/src/java/grails/plugins/quartz/DefaultGrailsJobClass.java] -* [JobArtefactHandler|http://github.com/nebolsin/grails-quartz/blob/master/src/java/grails/plugins/quartz/JobArtefactHandler.java] +* [GrailsJobClass|https://github.com/grails3-plugins/quartz/blob/master/src/main/groovy/grails/plugins/quartz/GrailsJobClass.java] +* [DefaultGrailsJobClass|https://github.com/grails3-plugins/quartz/blob/master/src/main/groovy/grails/plugins/quartz/DefaultGrailsJobClass.java] +* [JobArtefactHandler|https://github.com/grails3-plugins/quartz/blob/master/src/main/groovy/grails/plugins/quartz/JobArtefactHandler.java] Another example is the [Shiro plugin|http://github.com/pledbrook/grails-shiro] which adds a realm artefact. From d2be022afc7e29c896c752a20412cfe7145e36dc Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Tue, 7 Jul 2015 01:04:21 +0530 Subject: [PATCH 186/230] Change all Config.groovy to application.groovy --- .../guide/spring/propertyPlaceholderConfiguration.gdoc | 2 +- .../theWebLayer/controllers/controllersAndScopes.gdoc | 2 +- src/en/guide/theWebLayer/controllers/dataBinding.gdoc | 10 +++++----- src/en/guide/theWebLayer/gsp/layouts.gdoc | 2 +- .../gsp/makingChangesToADeployedApplication.gdoc | 2 +- .../theWebLayer/urlmappings/customizingUrlFormat.gdoc | 4 ++-- src/en/guide/validation/sharingConstraints.gdoc | 2 +- src/en/guide/webServices/REST/hypermedia/hal.gdoc | 2 +- src/en/ref/Constraints.gdoc | 2 +- src/en/ref/Constraints/nullable.gdoc | 2 +- src/en/ref/Controllers/withFormat.gdoc | 2 +- src/en/ref/Database Mapping.gdoc | 2 +- src/en/ref/Domain Classes.gdoc | 2 +- src/en/ref/Domain Classes/save.gdoc | 2 +- 14 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/en/guide/spring/propertyPlaceholderConfiguration.gdoc b/src/en/guide/spring/propertyPlaceholderConfiguration.gdoc index 3fa29fa6f07..b3fe466713a 100644 --- a/src/en/guide/spring/propertyPlaceholderConfiguration.gdoc +++ b/src/en/guide/spring/propertyPlaceholderConfiguration.gdoc @@ -1,6 +1,6 @@ Grails supports the notion of property placeholder configuration through an extended version of Spring's [PropertyPlaceholderConfigurer|api:org.springframework.beans.factory.config.PropertyPlaceholderConfigurer]. -Settings defined in either "ConfigSlurper":http://groovy.codehaus.org/ConfigSlurper scripts or Java properties files can be used as placeholder values for Spring configuration in @grails-app/conf/spring/resources.xml@ and @grails-app/conf/spring/resources.groovy@. For example given the following entries in @grails-app/conf/Config.groovy@ (or an externalized config): +Settings defined in either "ConfigSlurper":http://groovy.codehaus.org/ConfigSlurper scripts or Java properties files can be used as placeholder values for Spring configuration in @grails-app/conf/spring/resources.xml@ and @grails-app/conf/spring/resources.groovy@. For example given the following entries in @grails-app/conf/application.groovy@ (or an externalized config): {code:java} database.driver="com.mysql.jdbc.Driver" diff --git a/src/en/guide/theWebLayer/controllers/controllersAndScopes.gdoc b/src/en/guide/theWebLayer/controllers/controllersAndScopes.gdoc index 0f7e5dc86f5..744d7ad565a 100644 --- a/src/en/guide/theWebLayer/controllers/controllersAndScopes.gdoc +++ b/src/en/guide/theWebLayer/controllers/controllersAndScopes.gdoc @@ -75,7 +75,7 @@ You can define the default strategy under in @Config.groovy@ with the @grails.co grails.controllers.defaultScope = "singleton" {code} -Newly created applications have the @grails.controllers.defaultScope@ property set in @grails-app/conf/Config.groovy@ with a value of "singleton". You may change this value to any +Newly created applications have the @grails.controllers.defaultScope@ property set in @grails-app/conf/application.groovy@ with a value of "singleton". You may change this value to any of the supported scopes listed above. If the property is not assigned a value at all, controllers will default to "prototype" scope. {note} diff --git a/src/en/guide/theWebLayer/controllers/dataBinding.gdoc b/src/en/guide/theWebLayer/controllers/dataBinding.gdoc index cb3e2ce2136..8da6474114a 100644 --- a/src/en/guide/theWebLayer/controllers/dataBinding.gdoc +++ b/src/en/guide/theWebLayer/controllers/dataBinding.gdoc @@ -221,7 +221,7 @@ This has the same effect as using the implicit constructor. When binding an empty String (a String with no characters in it, not even spaces), the data binder will convert the empty String to null. This simplifies the most common case where the intent is to treat an empty form field as having the value null since there isn't a way to actually submit a null as a request parameter. When this behavior is not desirable the application may assign the value directly. -The mass property binding mechanism will by default automatically trim all Strings at binding time. To disable this behavior set the @grails.databinding.trimStrings@ property to false in @grails-app/conf/Config.groovy@. +The mass property binding mechanism will by default automatically trim all Strings at binding time. To disable this behavior set the @grails.databinding.trimStrings@ property to false in @grails-app/conf/application.groovy@. {code:java} // the default value is true @@ -343,7 +343,7 @@ This would bind the selected image into the @Map@ property @images@ under a key When binding to Maps, Arrays and Collections the data binder will automatically grow the size of the collections as necessary. The default limit to how large the binder will grow a collection is 256. If the data binder encounters an entry that requires the collection be grown beyond that limit, the entry is ignored. The limit may be configured by assigning a value to the @grails.databinding.autoGrowCollectionLimit@ property in @Config.groovy@. {code:java} -// grails-app/conf/Config.groovy +// grails-app/conf/application.groovy // the default value is 256 grails.databinding.autoGrowCollectionLimit = 128 @@ -566,7 +566,7 @@ class Person { A global setting may be configured in @Config.groovy@ to define date formats which will be used application wide when binding to Date. {code:java} -// grails-app/conf/Config.groovy +// grails-app/conf/application.groovy grails.databinding.dateFormats = ['MMddyyyy', 'yyyy-MM-dd HH:mm:ss.S', "yyyy-MM-dd'T'hh:mm:ss'Z'"] @@ -830,10 +830,10 @@ public interface BindEventListener { } {code} -Support for @BindEventListener@ is disabled by default. To enable support assign a value of @true@ to the @grails.databinding.enableSpringEventAdapter@ property in @grails-app/conf/Config.groovy@. +Support for @BindEventListener@ is disabled by default. To enable support assign a value of @true@ to the @grails.databinding.enableSpringEventAdapter@ property in @grails-app/conf/application.groovy@. {code} -// grails-app/conf/Config.groovy +// grails-app/conf/application.groovy grails.databinding.enableSpringEventAdapter=true ... diff --git a/src/en/guide/theWebLayer/gsp/layouts.gdoc b/src/en/guide/theWebLayer/gsp/layouts.gdoc index 43f09ecc975..c80383be9ce 100644 --- a/src/en/guide/theWebLayer/gsp/layouts.gdoc +++ b/src/en/guide/theWebLayer/gsp/layouts.gdoc @@ -98,7 +98,7 @@ If you have both the above mentioned layouts in place the layout specific to the If a layout may not be located using any of those conventions, the convention of last resort is to look for the application default layout which is @grails-app/views/layouts/application.gsp@. The name of the application default layout may be changed by defining a property -in @grails-app/conf/Config.groovy@ as follows: +in @grails-app/conf/application.groovy@ as follows: {code:java} grails.sitemesh.default.layout = 'myLayoutName' diff --git a/src/en/guide/theWebLayer/gsp/makingChangesToADeployedApplication.gdoc b/src/en/guide/theWebLayer/gsp/makingChangesToADeployedApplication.gdoc index 5a00961f04b..ef8ce13fc8a 100644 --- a/src/en/guide/theWebLayer/gsp/makingChangesToADeployedApplication.gdoc +++ b/src/en/guide/theWebLayer/gsp/makingChangesToADeployedApplication.gdoc @@ -1,6 +1,6 @@ One of the main issues with deploying a Grails application (or typically any servlet-based one) is that any change to the views requires that you redeploy your whole application. If all you want to do is fix a typo on a page, or change an image link, it can seem like a lot of unnecessary work. For such simple requirements, Grails does have a solution: the @grails.gsp.view.dir@ configuration setting. -How does this work? The first step is to decide where the GSP files should go. Let's say we want to keep them unpacked in a @/var/www/grails/my-app@ directory. We add these two lines to @grails-app/conf/Config.groovy@ : +How does this work? The first step is to decide where the GSP files should go. Let's say we want to keep them unpacked in a @/var/www/grails/my-app@ directory. We add these two lines to @grails-app/conf/application.groovy@ : {code} grails.gsp.enable.reload = true grails.gsp.view.dir = "/var/www/grails/my-app/" diff --git a/src/en/guide/theWebLayer/urlmappings/customizingUrlFormat.gdoc b/src/en/guide/theWebLayer/urlmappings/customizingUrlFormat.gdoc index 55bca5fbd70..39ba4ca4ab8 100644 --- a/src/en/guide/theWebLayer/urlmappings/customizingUrlFormat.gdoc +++ b/src/en/guide/theWebLayer/urlmappings/customizingUrlFormat.gdoc @@ -1,7 +1,7 @@ -The default URL Mapping mechanism supports camel case names in the URLs. The default URL for accessing an action named @addNumbers@ in a controller named @MathHelperController@ would be something like @/mathHelper/addNumbers@. Grails allows for the customization of this pattern and provides an implementation which replaces the camel case convention with a hyphenated convention that would support URLs like @/math-helper/add-numbers@. To enable hyphenated URLs assign a value of "hyphenated" to the @grails.web.url.converter@ property in @grails-app/conf/Config.groovy@. +The default URL Mapping mechanism supports camel case names in the URLs. The default URL for accessing an action named @addNumbers@ in a controller named @MathHelperController@ would be something like @/mathHelper/addNumbers@. Grails allows for the customization of this pattern and provides an implementation which replaces the camel case convention with a hyphenated convention that would support URLs like @/math-helper/add-numbers@. To enable hyphenated URLs assign a value of "hyphenated" to the @grails.web.url.converter@ property in @grails-app/conf/application.groovy@. {code:java} -// grails-app/conf/Config.groovy +// grails-app/conf/application.groovy grails.web.url.converter = 'hyphenated' {code} diff --git a/src/en/guide/validation/sharingConstraints.gdoc b/src/en/guide/validation/sharingConstraints.gdoc index 14c16810bef..4e0ca72650f 100644 --- a/src/en/guide/validation/sharingConstraints.gdoc +++ b/src/en/guide/validation/sharingConstraints.gdoc @@ -2,7 +2,7 @@ A common pattern in Grails is to use [command objects|guide:commandObjects] for h3. Global Constraints -In addition to defining constraints in domain classes, command objects and [other validateable classes|guide:validationNonDomainAndCommandObjectClasses], you can also define them in @grails-app/conf/Config.groovy@: +In addition to defining constraints in domain classes, command objects and [other validateable classes|guide:validationNonDomainAndCommandObjectClasses], you can also define them in @grails-app/conf/application.groovy@: {code} grails.gorm.default.constraints = { diff --git a/src/en/guide/webServices/REST/hypermedia/hal.gdoc b/src/en/guide/webServices/REST/hypermedia/hal.gdoc index 968920278c8..748cdde15e8 100644 --- a/src/en/guide/webServices/REST/hypermedia/hal.gdoc +++ b/src/en/guide/webServices/REST/hypermedia/hal.gdoc @@ -218,7 +218,7 @@ Date: Thu, 17 Oct 2013 02:34:14 GMT h4. Using Custom Media / Mime Types -If you wish to use a custom Mime Type then you first need to declare the Mime Types in @grails-app/conf/Config.groovy@: +If you wish to use a custom Mime Type then you first need to declare the Mime Types in @grails-app/conf/application.groovy@: {code} grails.mime.types = [ diff --git a/src/en/ref/Constraints.gdoc b/src/en/ref/Constraints.gdoc index f9677ba7482..9a64cba359e 100644 --- a/src/en/ref/Constraints.gdoc +++ b/src/en/ref/Constraints.gdoc @@ -19,7 +19,7 @@ Refer to the user guide topic on [Constraints|guide:constraints] for more inform h2. Global Constraints -You can apply constraints globally inside @grails-app/conf/Config.groovy@ as follows: +You can apply constraints globally inside @grails-app/conf/application.groovy@ as follows: {code} grails.gorm.default.constraints = { diff --git a/src/en/ref/Constraints/nullable.gdoc b/src/en/ref/Constraints/nullable.gdoc index 58976fe6e20..74166a4164e 100644 --- a/src/en/ref/Constraints/nullable.gdoc +++ b/src/en/ref/Constraints/nullable.gdoc @@ -23,7 +23,7 @@ Web requests resulting from form submissions will have blank strings, not @null@ {note} {code:java} -// grails-app/conf/Config.groovy +// grails-app/conf/application.groovy // the default value for this property is true grails.databinding.convertEmptyStringsToNull = false diff --git a/src/en/ref/Controllers/withFormat.gdoc b/src/en/ref/Controllers/withFormat.gdoc index c3e032b95c4..3d8baacb842 100644 --- a/src/en/ref/Controllers/withFormat.gdoc +++ b/src/en/ref/Controllers/withFormat.gdoc @@ -35,7 +35,7 @@ withFormat { } {code} -Here we invoke three methods called @html@, @js@ and @xml@ that use mime type names configured in @grails-app/conf/Config.groovy@ (See [content negotiation|guide:contentNegotiation] for more information). The call to @html@ accepts a model (a Map) which is passed on to the view. Grails searches for a view called @grails-app/views/book/list.html.gsp@ and if that is not found fallback to @grails-app/views/book/list.gsp@. +Here we invoke three methods called @html@, @js@ and @xml@ that use mime type names configured in @grails-app/conf/application.groovy@ (See [content negotiation|guide:contentNegotiation] for more information). The call to @html@ accepts a model (a Map) which is passed on to the view. Grails searches for a view called @grails-app/views/book/list.html.gsp@ and if that is not found fallback to @grails-app/views/book/list.gsp@. Note that the order of the types is significant if the request format is "all" or if more than one content type has the same "q" rating in the accept header. In the former case, the first type handler in the block is executed ("html" in the short example above). The latter case is more confusing because it only holds if there is more than one content type with the highest "q" rating for which you have a type handler *and* you have more than one type handler matching that "q" rating. For example if the request has "text/html" and "application/xml" with a "q" rating of 1.0, then this code: diff --git a/src/en/ref/Database Mapping.gdoc b/src/en/ref/Database Mapping.gdoc index fbcf1d1ea38..be3b97dd456 100644 --- a/src/en/ref/Database Mapping.gdoc +++ b/src/en/ref/Database Mapping.gdoc @@ -27,7 +27,7 @@ Refer to the user guide section on [ORM Mapping|guide:ormdsl] for more informati h1. Global Database Mapping -You can configure mappings globally in @grails-app/conf/Config.groovy@ as follows: +You can configure mappings globally in @grails-app/conf/application.groovy@ as follows: {code} grails.gorm.default.mapping = { diff --git a/src/en/ref/Domain Classes.gdoc b/src/en/ref/Domain Classes.gdoc index c1c1dbb1478..c2fd009f6a3 100644 --- a/src/en/ref/Domain Classes.gdoc +++ b/src/en/ref/Domain Classes.gdoc @@ -23,7 +23,7 @@ The class name, by default, is mapped to the table name in lower case and separa One limitation of the default table naming scheme is that it is problematic to have 2 domain classes with the same name, even if they are defined to be in separate packages. For example, @com.bookstore.BookStore@ and @com.publishing.utility.BookStore@ would each map to a table named @book_store@. If the 2 classes are defined in the application this problem can be managed by giving the classes different names or by providing a specific table name for one or both of the classes that deviates from the default (see the [ORM DSL|guide:ormdsl] section of the user guide for more details). If one or both of the domain classes is provided by a plugin the application author may not have access to those options. To help manage a situation like that, GORM may be configured to prefix table names with plugin names by default. For example, if the @com.publishing.utility.BookStore@ domain class is provided by a plugin named @PublishingUtilities@, the default table name could be @publishing_utilities_book_store@. To enable that behavior the @grails.gorm.table.prefix.enabled@ config property must be set to true. Example: {code} -// grails-app/conf/Config.groovy +// grails-app/conf/application.groovy grails.gorm.table.prefix.enabled = true {code} diff --git a/src/en/ref/Domain Classes/save.gdoc b/src/en/ref/Domain Classes/save.gdoc index 5418a5137ac..a68186f2ea5 100644 --- a/src/en/ref/Domain Classes/save.gdoc +++ b/src/en/ref/Domain Classes/save.gdoc @@ -34,7 +34,7 @@ Parameters: * @validate@ (optional) - Set to @false@ if validation should be skipped * @flush@ (optional) - When set to @true@ flushes the persistence context, persisting the object immediately and updating the @version@ column for [optimistic locking|guide:locking] * @insert@ (optional) - When set to @true@ will force Hibernate to do a SQL INSERT; this is useful in certain situations (for example when using assigned ids) and Hibernate cannot detect whether to do an INSERT or an UPDATE -* @failOnError@ (optional) - When set to @true@ the @save@ method with throw a @grails.validation.ValidationException@ if [validation|guide:validation] fails. This behavior may also be triggered by setting the @grails.gorm.failOnError@ property in @grails-app/conf/Config.groovy@. If the Config property is set and the argument is passed to the method, the method argument will always take precedence. For more details about the config property and other GORM config options, see the [GORM Configuration Options|guide:configGORM] section of The User Guide. +* @failOnError@ (optional) - When set to @true@ the @save@ method with throw a @grails.validation.ValidationException@ if [validation|guide:validation] fails. This behavior may also be triggered by setting the @grails.gorm.failOnError@ property in @grails-app/conf/application.groovy@. If the Config property is set and the argument is passed to the method, the method argument will always take precedence. For more details about the config property and other GORM config options, see the [GORM Configuration Options|guide:configGORM] section of The User Guide. * @deepValidate@ (optional) - Determines whether associations of the domain instance should also be validated, i.e. whether validation cascades. This is @true@ by default - set to @false@ to disable cascading validation. {note} From d16fae6d304c98a060c1ae6159666574aa3769a7 Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Wed, 8 Jul 2015 00:01:40 +0530 Subject: [PATCH 187/230] Spelling mistakes in command line docs --- src/en/guide/commandLine.gdoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/en/guide/commandLine.gdoc b/src/en/guide/commandLine.gdoc index 72697e04e8e..e613841a50d 100644 --- a/src/en/guide/commandLine.gdoc +++ b/src/en/guide/commandLine.gdoc @@ -6,9 +6,9 @@ When you type: grails [command name] {code} -Grails searches the [profile repository|https://github.com/grails/grails-profile-repository] based on the profile of the current application. If the profile is for a web application then commmands a read from the web profile and the base profile which it inherits from. +Grails searches the [profile repository|https://github.com/grails/grails-profile-repository] based on the profile of the current application. If the profile is for a web application then commands are read from the web profile and the base profile which it inherits from. -Since command behavior is profile specific the web profile my provide different behavior for the @run-app@ command then say a profile for running batch applications. +Since command behavior is profile specific the web profile may provide different behavior for the @run-app@ command then say a profile for running batch applications. When you type the following command: From 07b141701d6a7c8fd0e005a20b879af553c3087c Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Wed, 8 Jul 2015 00:45:34 +0530 Subject: [PATCH 188/230] Added information regarding yml format. --- src/en/guide/conf/config/ymlOptions.gdoc | 13 +++++++++++++ src/en/guide/toc.yml | 1 + 2 files changed, 14 insertions(+) create mode 100644 src/en/guide/conf/config/ymlOptions.gdoc diff --git a/src/en/guide/conf/config/ymlOptions.gdoc b/src/en/guide/conf/config/ymlOptions.gdoc new file mode 100644 index 00000000000..3638021b6b5 --- /dev/null +++ b/src/en/guide/conf/config/ymlOptions.gdoc @@ -0,0 +1,13 @@ +@application.yml@ was introduced in Grails 3.0 for an alternative format for the configuration tasks. + +h3. Using system properties / command line arguments + +Suppose you are setting the @JDBC_CONNECTION_STRING@ system property and you want to access the same in the yml file then it can be done in the following manner: + +{code:java} +production: + dataSource: + url: '${JDBC_CONNECTION_STRING}' +{code} + +Similarly command line arguments can be accessed. diff --git a/src/en/guide/toc.yml b/src/en/guide/toc.yml index 0fc022e1546..243f3b7ede1 100644 --- a/src/en/guide/toc.yml +++ b/src/en/guide/toc.yml @@ -29,6 +29,7 @@ conf: title: Configuration config: title: Basic Configuration + ymlOptions: Options for the yml format Config builtInOptions: Built in options logging: Logging configGORM: GORM From 00b79e48ab569096453a1764b1b8ecf686adc9f4 Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Wed, 8 Jul 2015 01:00:42 +0530 Subject: [PATCH 189/230] The same line was present in the above paragrpah of profiles also --- src/en/guide/commandLine/creatingCustomScripts.gdoc | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/en/guide/commandLine/creatingCustomScripts.gdoc b/src/en/guide/commandLine/creatingCustomScripts.gdoc index d6d4db79168..ba53450b9f6 100644 --- a/src/en/guide/commandLine/creatingCustomScripts.gdoc +++ b/src/en/guide/commandLine/creatingCustomScripts.gdoc @@ -1,14 +1,10 @@ -You can create your own Command scripts by running the [create-script|commandLine] command from the root of your project. For example the following command: +You can create your own Command scripts by running the [create-script|commandLine] command from the root of your project. For example the following command will create a script called @src/main/scripts/hello-world.groovy@: {code} grails create-script hello-world {code} - - -Will create a script called @src/main/scripts/hello-world.groovy@. Each Command script is extends from the [GroovyScriptCommmand|api:org.grails.cli.profile.commands.script.GroovyScriptCommmand] class and hence has all of the methods of that class available to it. - {note} In general Grails scripts should be used for scripting the Gradle based build system and code generation. Scripts cannot load application classes and in fact should not since Gradle is required to construct the application classpath. {note} From c51298a6a699dfdcebc28116a850565b7e5f0991 Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Wed, 8 Jul 2015 01:48:14 +0530 Subject: [PATCH 190/230] Updated contributing docs for issues --- src/en/guide/contributing/issues.gdoc | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/en/guide/contributing/issues.gdoc b/src/en/guide/contributing/issues.gdoc index ddda87d2fe2..b121f0d284b 100644 --- a/src/en/guide/contributing/issues.gdoc +++ b/src/en/guide/contributing/issues.gdoc @@ -1,13 +1,11 @@ -Grails uses [JIRA|http://jira.grails.org] to track issues in the core framework, its documentation, its website, and many of the public plugins. If you've found a bug or wish to see a particular feature added, this is the place to start. You'll need to create a (free) JIRA account in order to either submit an issue or comment on an existing one. +Grails uses [Github|https://github.com/grails/grails-core/issues] to track issues in the core framework. Similarly for its [documentation|https://github.com/grails/grails-doc/issues] have a separate tracker. If you've found a bug or wish to see a particular feature added, this is the place to start. You'll need to create a (free) github account in order to either submit an issue or comment on an existing one in either of these. -When submitting issues, please provide as much information as possible and in the case of bugs, make sure you explain which versions of Grails and various plugins you are using. Also, an issue is much more likely to be dealt with if you attach a reproducible sample application (which can be packaged up using the @grails bug-report@ command). +When submitting issues, please provide as much information as possible and in the case of bugs, make sure you explain which versions of Grails and various plugins you are using. Also, an issue is much more likely to be dealt with if you upload a reproducible sample application on a github repository. h3. Reviewing issues -There are quite a few old issues in JIRA, some of which may no longer be valid. The core team can't track down these alone, so a very simple contribution that you can make is to verify one or two issues occasionally. +There are quite a few old issues in github, some of which may no longer be valid. The core team can't track down these alone, so a very simple contribution that you can make is to verify one or two issues occasionally. -Which issues need verification? A shared [JIRA filter|http://jira.grails.org/secure/IssueNavigator.jspa?reset=true&jqlQuery=project+%3D+GRAILS+AND+resolution+%3D+Unresolved+AND+%28cf%5B10310%5D+%3C%3D+%27-180d%27+OR+cf%5B10310%5D+is+EMPTY%29+AND+createdDate+%3C%3D+%27-180d%27] will display all issues that haven't been resolved and haven't been reviewed by someone else in the last 6 months. Just pick one or two of them and check whether they are still relevant. +Which issues need verification? Going to the [issue tracker|https://github.com/grails/grails-core/issues?q=is%3Aopen+is%3Aissue] will display all issues that haven't been resolved. -Once you've verified an issue, simply edit it and set the "Last Reviewed" field to today. If you think the issue can be closed, then also check the "Flagged" field and add a short comment explaining why. Once those changes are saved, the issue will disappear from the results of the above filter. If you've flagged it, the core team will review and close if it really is no longer relevant. - -One last thing: you can easily set the above filter as a favourite on [this JIRA screen|http://jira.grails.org/secure/ManageFilters.jspa#filterView=popular] so that it appears in the "Issues" drop down. Just click on the star next to a filter to make it a favourite. +Once you've verified an issue, simply add a short comment explaining what you found. Be sure to metion your environment details and grails version. From 9b8f2b4b84403f2014175b2d65b25b490e4ef5fb Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Wed, 8 Jul 2015 01:49:31 +0530 Subject: [PATCH 191/230] Update toc.yml --- src/en/guide/toc.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/en/guide/toc.yml b/src/en/guide/toc.yml index 0fc022e1546..20c2f008dd0 100644 --- a/src/en/guide/toc.yml +++ b/src/en/guide/toc.yml @@ -307,7 +307,7 @@ scaffolding: Scaffolding deployment: Deployment contributing: title: Contributing to Grails - issues: Report Issues in JIRA + issues: Report Issues in Github's issue tracker build: Build From Source and Run Tests patchesCore: Submit Patches to Grails Core patchesDoc: Submit Patches to Grails Documentation From 239a1f0406ad75f3a4b80890e978886e158fef76 Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Wed, 8 Jul 2015 19:27:48 +0530 Subject: [PATCH 192/230] Updated with change to build.gradle --- src/en/guide/conf/config/ymlOptions.gdoc | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/en/guide/conf/config/ymlOptions.gdoc b/src/en/guide/conf/config/ymlOptions.gdoc index 3638021b6b5..6e150916e94 100644 --- a/src/en/guide/conf/config/ymlOptions.gdoc +++ b/src/en/guide/conf/config/ymlOptions.gdoc @@ -2,7 +2,7 @@ h3. Using system properties / command line arguments -Suppose you are setting the @JDBC_CONNECTION_STRING@ system property and you want to access the same in the yml file then it can be done in the following manner: +Suppose you are using the @JDBC_CONNECTION_STRING@ command line argument and you want to access the same in the yml file then it can be done in the following manner: {code:java} production: @@ -10,4 +10,12 @@ production: url: '${JDBC_CONNECTION_STRING}' {code} -Similarly command line arguments can be accessed. +Similarly system arguments can be accessed. + +You will need to have this in @build.gradle@ to modify the @bootRun@ target if @grails run-app@ is used to start the application + +{code:java} +run { + systemProperties = System.properties +} +{code} From 7518656a765bb0153590e3cc63c02723f899d597 Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Wed, 8 Jul 2015 19:32:17 +0530 Subject: [PATCH 193/230] Removed info about public fork as that is not used --- src/en/guide/contributing/patchesDoc.gdoc | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/en/guide/contributing/patchesDoc.gdoc b/src/en/guide/contributing/patchesDoc.gdoc index c01e7f42836..a99387f7692 100644 --- a/src/en/guide/contributing/patchesDoc.gdoc +++ b/src/en/guide/contributing/patchesDoc.gdoc @@ -1,5 +1,3 @@ -Contributing to the documentation is simpler for the core framework because there is a public fork of the [http://github.com/grails/grails-doc|http://github.com/grails/grails-doc] project that anyone can request commit access to. So, if you want to submit patches to the documentation, simply request commit access to the following repository [http://github.com/pledbrook/grails-doc|http://github.com/pledbrook/grails-doc] by sending a GitHub message to 'pledbrook' and then commit your patches just as you would to any other GitHub repository. - h3. Building the Guide To build the documentation, simply type: From 0b9c1d02768c9fd2f68dfbdbfd1f572d32d5d021 Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Wed, 8 Jul 2015 19:38:20 +0530 Subject: [PATCH 194/230] Updated with test information --- src/en/guide/conf/config/ymlOptions.gdoc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/en/guide/conf/config/ymlOptions.gdoc b/src/en/guide/conf/config/ymlOptions.gdoc index 6e150916e94..7922376dd8b 100644 --- a/src/en/guide/conf/config/ymlOptions.gdoc +++ b/src/en/guide/conf/config/ymlOptions.gdoc @@ -19,3 +19,11 @@ run { systemProperties = System.properties } {code} + +For testing the following will be need to change the @test@ task + +{code:java} +test { + systemProperties = System.properties +} +{code} From b003d8c762d367664520dd55b1997979fce52d99 Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Wed, 8 Jul 2015 19:44:10 +0530 Subject: [PATCH 195/230] Changed log4j to logback --- src/en/ref/Plug-ins/logging.gdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/en/ref/Plug-ins/logging.gdoc b/src/en/ref/Plug-ins/logging.gdoc index dc0c77224f4..d23c777cd7c 100644 --- a/src/en/ref/Plug-ins/logging.gdoc +++ b/src/en/ref/Plug-ins/logging.gdoc @@ -2,7 +2,7 @@ h1. logging h2. Purpose -The @logging@ plugin configures Grails' support for [Logging|guide:logging] with [Log4j|http://logging.apache.org/log4j/1.2/index.html]. +The @logging@ plugin configures Grails' support for [Logging|guide:logging] with logback. h2. Examples From c4831d11620db7ec492a4eb22d06f9f38f2364e9 Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Wed, 8 Jul 2015 19:55:47 +0530 Subject: [PATCH 196/230] Removed docs from README.md as that creates duplication --- README.md | 98 +------------------------------------------------------ 1 file changed, 1 insertion(+), 97 deletions(-) diff --git a/README.md b/README.md index dd54a9d637c..05be5c63574 100644 --- a/README.md +++ b/README.md @@ -5,100 +5,4 @@ This is the project for generating the [Grails user & reference guide][Grails Do [Grails Documentation]: http://grails.org/doc/latest [Grails]: http://grails.org - -Building the Guide ------------------- - -To build the documentation, simply type: - - ./gradlew docs - -This will take some time as it generates groovydoc for the Grails sources. If you want to just generate the user guide to preview your change you can do: - - ./gradlew -Ddisable.groovydocs=true docs - -Be warned: this command can take a while to complete and you should probably increase your Gradle memory settings by giving the `GRADLE_OPTS` environment variable a value like - - export GRADLE_OPTS="-Xmx512m -XX:MaxPermSize=384m" - -Fortunately, you can reduce the overall build time with a couple of useful options. The first allows you to specify the location of the Grails source to use: - - ./gradlew -Dgrails.home=/home/user/projects/grails-core docs - -The Grails source is required because the guide links to its API documentation and the build needs to ensure it's generated. If you don't specify a `grails.home` property, then the build will fetch the Grails source - a download of 10s of megabytes. It must then compile the Grails source which can take a while too. - -Additionally you can create a local.properties file with this variable set: - - grails.home=/home/user/projects/grails-core - -or - - grails.home=../grails-core - -The other useful option allows you to disable the generation of the API documentation, since you only need to do it once: - - ./gradlew -Ddisable.groovydocs=true docs - -Again, this can save a significant amount of time and memory. - -The main English user guide is generated in the `build/docs` directory, with the `guide` sub-directory containing the user guide part and the `ref` folder containing the reference material. To view the user guide, simply open `build/docs/index.html`. - -If you want to enable building of translations, you can use: - - ./gradlew -Dall.langs=true docs - -Contributing Documentation --------------------------- - -The publishing system for the user guide is the same as [the one for Grails projects][1]. You write your chapters and sections in the gdoc wiki format which is then converted to HTML for the final guide. Each chapter is a top-level gdoc file in the `src//guide` directory. Sections and sub-sections then go into directories with the same name as the chapter gdoc but without the suffix. - -The structure of the user guide is defined in the `src//guide/toc.yml` file, which is a [YAML][2] file. This file also defines the (language-specific) section titles. If you add or remove a gdoc file, you must update the TOC as well! - -The `src//ref` directory contains the source for the reference sidebar. Each directory is the name of a category, which also appears in the docs. Hence the directories need different names for the different languages. Inside the directories go the gdoc files, whose names match the names of the methods, commands, properties or whatever that the files describe. - -Translations ------------- - -This project can host multiple translations of the user guide, with `src/en` being the main one. To add another one, simply create a new language directory under `src` and copy into it all the files under `src/en`. The build will take care of the rest. - -Once you have a copy of the original guide, you can use the `{hidden}` macro to wrap the English text that you have replaced, rather than remove it. This makes it easier to compare changes to the English guide against your translation. For example: - - {hidden} - When you create a Grails application with the [create-app|commandLine] command, - Grails doesn't automatically create an Ant @build.xml@ file but you can generate - one with the [integrate-with|commandLine] command: - {hidden} - - Quando crias uma aplicação Grails com o comando [create-app|commandLine], Grails - não cria automaticamente um ficheiro de construção Ant @build.xml@ mas podes gerar - um com o comando [integrate-with|commandLine]: - -Because the English text remains in your gdoc files, 'diff' will show differences on the English lines. You can then use the output of 'diff' to see which bits of your translation need updating. On top of that, the `{hidden}` macro ensures that the text inside it is not displayed in the browser, although you can display it by adding this URL as a bookmark: `javascript:toggleHidden();` (requires you to build the user guide with Grails 2.0 M2 or later). - -Even better, you can use the `left_to_do.groovy` script in the root of the project to see what still needs translating. You run it like so: - - ./left_to_do.groovy es - -This will then print out a recursive diff of the given translation against the reference English user guide. Anything in {hidden} blocks that hasn't changed since being translated will _not_ appear in the diff output. In other words, all you will see is content that hasn't been translated yet and content that has changed since it was translated. Note that {code} blocks are ignored, so you _don't_ need to include them inside {hidden} macros. - -To provide translations for the headers, such as the user guide title and subtitle, just add language specific entries in the `resources/doc.properties` file like so: - - es.title=El Grails Framework - es.subtitle=... - -For each language translation, properties beginning '.' will override the standard ones. In the above example, the user guide title will be El Grails Framework for the Spanish translation. Also, translators can be credited by adding a '.translators' property: - - fr.translators=Stéphane Maldini - -This should be a comma-separated list of names (or the native language equivalent) and it will be displayed as a "Translated by" header in the user guide itself. - -You can build specific translations very easily using the `publishGuide_*` and `publishPdf_*` tasks. For example, to build both the French HTML and PDF user guides, simply execute - - ./gradlew publishPdf_fr - -Each translation is generated in its own directory, so for example the French guide will end up in `build/docs/fr`. You can then view the translated guide by opening `build/docs//index.html`. - -All translations are created as part of the [Hudson CI build for the grails-doc][2] project, so you can easily see what the current state is without having to build the docs yourself. - -[1]: http://grails.org/doc/2.0.0.M1/guide/conf.html#docengine -[2]: http://hudson.grails.org/job/grails_docs_2.0.x/lastSuccessfulBuild/artifact/build/docs/ +[Building/Contibuting to Grails Documentation]: https://grails.github.io/grails-doc/latest/guide/contributing.html#patchesDoc From 6621da952ba992389123f5f476cf8dea2ed25c04 Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Wed, 8 Jul 2015 20:09:33 +0530 Subject: [PATCH 197/230] Corrected path As per the path in https://github.com/grails3-plugins/geb/blob/master/src/main/scripts/CreateFunctionalTest.groovy --- src/en/guide/testing/functionalTesting.gdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/en/guide/testing/functionalTesting.gdoc b/src/en/guide/testing/functionalTesting.gdoc index bc90bb95e82..6ffd15dac34 100644 --- a/src/en/guide/testing/functionalTesting.gdoc +++ b/src/en/guide/testing/functionalTesting.gdoc @@ -6,7 +6,7 @@ Grails by default ships with support for writing functional tests using the [Geb $ grails create-functional-test MyFunctional {code} -The above command will create a new Spock spec called @MyFunctionalSpec.groovy@ in the @src/test/groovy@ directory. The test is annotated with the [Integration|api:grails.test.mixin.integration.Integration] annotation to indicate it is a integration test and extends the @GebSpec@ super class: +The above command will create a new Spock spec called @MyFunctionalSpec.groovy@ in the @src/integration-test/groovy@ directory. The test is annotated with the [Integration|api:grails.test.mixin.integration.Integration] annotation to indicate it is a integration test and extends the @GebSpec@ super class: {code} @Integration From c9b25971292fdd42131658a85fef87e86cc6ead9 Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Wed, 8 Jul 2015 20:27:47 +0530 Subject: [PATCH 198/230] Fixed mistake of link not being available on front page --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 05be5c63574..5c70dd3b959 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,9 @@ Grails User/Reference Guide =========================== -This is the project for generating the [Grails user & reference guide][Grails Documentation] that explains how to build applications with the [Grails][Grails] framework. +This is the project for generating the [Grails user & reference guide][Grails Documentation] that explains how to build applications with the [Grails][Grails] framework. + +For contributing to grails docs look at [Building/Contibuting to Grails Documentation][Grails contribution Documentation] [Grails Documentation]: http://grails.org/doc/latest [Grails]: http://grails.org From 5a1a8b467c51bfbc9f92027d7419904413f3ab9a Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Wed, 8 Jul 2015 20:32:46 +0530 Subject: [PATCH 199/230] Spelling mistakes --- src/en/guide/plugins/creatingAndInstallingPlugins.gdoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/en/guide/plugins/creatingAndInstallingPlugins.gdoc b/src/en/guide/plugins/creatingAndInstallingPlugins.gdoc index 21264a14769..82c268cdcbe 100644 --- a/src/en/guide/plugins/creatingAndInstallingPlugins.gdoc +++ b/src/en/guide/plugins/creatingAndInstallingPlugins.gdoc @@ -8,13 +8,13 @@ grails create-plugin [PLUGIN NAME] This will create a plugin project for the name you specify. For example running @grails create-plugin example@ would create a new plugin project called @example@. -In Grails 3.0 you should consider whether the plugin you create requires a web environment or whether the plugin can be used with other profiles. If you plugin does not require a web environment then use the "plugin" profile instead of the "web-plugin" profile: +In Grails 3.0 you should consider whether the plugin you create requires a web environment or whether the plugin can be used with other profiles. If your plugin does not require a web environment then use the "plugin" profile instead of the "web-plugin" profile: {code:java} grails create-plugin [PLUGIN NAME] --profile=plugin {code} -Make sure the plugin name does not contain more than one capital in a row, or it won't work. Camel case is fine, though. +Make sure the plugin name does not contain more than one capital letter in a row, or it won't work. Camel case is fine, though. The structure of a Grails plugin is very nearly the same as a Grails application project's except that in the @src/main/groovy@ directory under the plugin package structure you will find a plugin descriptor class (a class that ends in "GrailsPlugin"). From 3b913e3dd188e7e342e558d12c1c45aa127cea47 Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Wed, 8 Jul 2015 20:38:48 +0530 Subject: [PATCH 200/230] Updated docs for plugin descriptor --- src/en/guide/plugins/creatingAndInstallingPlugins.gdoc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/en/guide/plugins/creatingAndInstallingPlugins.gdoc b/src/en/guide/plugins/creatingAndInstallingPlugins.gdoc index 21264a14769..18b3f5ef549 100644 --- a/src/en/guide/plugins/creatingAndInstallingPlugins.gdoc +++ b/src/en/guide/plugins/creatingAndInstallingPlugins.gdoc @@ -46,6 +46,9 @@ You can also provide additional information about your plugin using several spec * @authorEmail@ - plugin author's contact e-mail * @description@ - full multi-line description of plugin's features * @documentation@ - URL of the plugin's documentation +* @license@ - License of the plugin +* @issueManagement@ - Issue Tracker of the plugin +* @scm@ - Source code management location of the plugin Here is an example from the [Quartz Grails plugin|http://grails.org/plugin/quartz]: From 130e63d2e5b03c71b924581d1bd7dedf87e8c2bb Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Thu, 9 Jul 2015 11:00:49 +0530 Subject: [PATCH 201/230] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5c70dd3b959..9c36d479795 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Grails User/Reference Guide This is the project for generating the [Grails user & reference guide][Grails Documentation] that explains how to build applications with the [Grails][Grails] framework. -For contributing to grails docs look at [Building/Contibuting to Grails Documentation][Grails contribution Documentation] +For contributing to grails docs look at [Building/Contibuting to Grails Documentation][Building/Contibuting to Grails Documentation] [Grails Documentation]: http://grails.org/doc/latest [Grails]: http://grails.org From df3d7ec2cb3309a34348c13f809897baeff18fa8 Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Thu, 9 Jul 2015 11:03:02 +0530 Subject: [PATCH 202/230] Grammar mistake As per comments in https://github.com/grails/grails-doc/pull/313 --- src/en/guide/conf/config/ymlOptions.gdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/en/guide/conf/config/ymlOptions.gdoc b/src/en/guide/conf/config/ymlOptions.gdoc index 7922376dd8b..99616cb6bb4 100644 --- a/src/en/guide/conf/config/ymlOptions.gdoc +++ b/src/en/guide/conf/config/ymlOptions.gdoc @@ -20,7 +20,7 @@ run { } {code} -For testing the following will be need to change the @test@ task +For testing the following will need to change the @test@ task as follows {code:java} test { From 463ddfed4c7f5df1ab420d9db6d57ebeb59f4fef Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Thu, 9 Jul 2015 16:01:13 +0530 Subject: [PATCH 203/230] Added top level only injection note https://github.com/grails/grails-core/issues/9091 --- src/en/guide/services/dependencyInjectionServices.gdoc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/en/guide/services/dependencyInjectionServices.gdoc b/src/en/guide/services/dependencyInjectionServices.gdoc index 84f5e111dfa..24f181e2f4d 100644 --- a/src/en/guide/services/dependencyInjectionServices.gdoc +++ b/src/en/guide/services/dependencyInjectionServices.gdoc @@ -27,6 +27,10 @@ To be consistent with standard JavaBean conventions, if the first 2 letters of t See section 8.8 of the JavaBean specification for more information on de-capitalization rules. {note} +{note} +Only the top level object is subjected to injection as traversing all nested objects to perform injection would be a performance issue. +{note} + h4. Dependency Injection and Services You can inject services in other services with the same technique. If you had an @AuthorService@ that needed to use the @BookService@, declaring the @AuthorService@ as follows would allow that: @@ -54,4 +58,4 @@ class Book { h4. Service Bean Names -The default bean name which is associated with a service can be problematic if there are multiple services with the same name defined in different packages. For example consider the situation where an application defines a service class named @com.demo.ReportingService@ and the application uses a plugin named @ReportingUtilities@ and that plugin provides a service class named @com.reporting.util.ReportingService@. The default bean name for each of those would be @reportingService@ so they would conflict with each other. Grails manages this by changing the default bean name for services provided by plugins by prefixing the bean name with the plugin name. In the scenario described above the @reportingService@ bean would be an instance of the @com.demo.ReportingService@ class defined in the application and the @reportingUtilitiesReportingService@ bean would be an instance of the @com.reporting.util.ReportingService@ class provided by the @ReportingUtilities@ plugin. For all service beans provided by plugins, if there are no other services with the same name within the application or other plugins in the application then a bean alias will be created which does not include the plugin name and that alias points to the bean referred to by the name that does include the plugin name prefix. For example, if the @ReportingUtilities@ plugin provides a service named @com.reporting.util.AuthorService@ and there is no other @AuthorService@ in the application or in any of the plugins that the application is using then there will be a bean named @reportingUtilitiesAuthorService@ which is an instance of this @com.reporting.util.AuthorService@ class and there will be a bean alias defined in the context named @authorService@ which points to that same bean. \ No newline at end of file +The default bean name which is associated with a service can be problematic if there are multiple services with the same name defined in different packages. For example consider the situation where an application defines a service class named @com.demo.ReportingService@ and the application uses a plugin named @ReportingUtilities@ and that plugin provides a service class named @com.reporting.util.ReportingService@. The default bean name for each of those would be @reportingService@ so they would conflict with each other. Grails manages this by changing the default bean name for services provided by plugins by prefixing the bean name with the plugin name. In the scenario described above the @reportingService@ bean would be an instance of the @com.demo.ReportingService@ class defined in the application and the @reportingUtilitiesReportingService@ bean would be an instance of the @com.reporting.util.ReportingService@ class provided by the @ReportingUtilities@ plugin. For all service beans provided by plugins, if there are no other services with the same name within the application or other plugins in the application then a bean alias will be created which does not include the plugin name and that alias points to the bean referred to by the name that does include the plugin name prefix. For example, if the @ReportingUtilities@ plugin provides a service named @com.reporting.util.AuthorService@ and there is no other @AuthorService@ in the application or in any of the plugins that the application is using then there will be a bean named @reportingUtilitiesAuthorService@ which is an instance of this @com.reporting.util.AuthorService@ class and there will be a bean alias defined in the context named @authorService@ which points to that same bean. From a09d739e00ea826fbf2b09b6c21a04182f3d26fd Mon Sep 17 00:00:00 2001 From: Dovydas Venckus Date: Sun, 12 Jul 2015 22:48:57 +0300 Subject: [PATCH 204/230] Updated outdated testing phase/type chapter Refactored outdated parts to reflect how unit and integration phases are handled in grails3 Closes #305 --- src/en/guide/testing.gdoc | 44 ++++++++++----------------------------- 1 file changed, 11 insertions(+), 33 deletions(-) diff --git a/src/en/guide/testing.gdoc b/src/en/guide/testing.gdoc index f0a569e9aed..cb0ab18174e 100644 --- a/src/en/guide/testing.gdoc +++ b/src/en/guide/testing.gdoc @@ -96,54 +96,32 @@ This will run the @testLogin@ test in the @SimpleController@ tests. You can spec grails test-app some.org.* SimpleController.testLogin BookController {code} -h4. Targeting Test Types and/or Phases +h4. Targeting Test Phases -In addition to targeting certain tests, you can also target test _types_ and/or _phases_ by using the @phase:type@ syntax. +In addition to targeting certain tests, you can also target test _phases._ By default Grails has two testing phases @unit@ and @integration.@ {note} -Grails organises tests by phase and by type. A test phase relates to the state of the Grails application during the tests, and the type relates to the testing mechanism. - -Grails comes with support for 4 test phases (@unit@, @integration@, @functional@ and @other@) and JUnit test types for the @unit@ and @integration@ phases. These test types have the same name as the phase. - -Testing plugins may provide new test phases or new test types for existing phases. Refer to the plugin documentation. +Grails 2.x uses @phase:type@ syntax. In Grails 3.0 it was removed, because it made no sense in Gradle context. {note} -To execute the JUnit @integration@ tests you can run: - -{code} -grails test-app integration:integration -{code} - -Both @phase@ and @type@ are optional. Their absence acts as a wildcard. The following command will run all test types in the @unit@ phase: - -{code} -grails test-app unit: -{code} - -The Grails [Spock Plugin|http://grails.org/plugin/spock] is one plugin that adds new test types to Grails. It adds a @spock@ test type to the @unit@, @integration@ and @functional@ phases. To run all spock tests in all phases you would run the following: - -{code} -grails test-app :spock -{code} - -To run the all of the spock tests in the @functional@ phase you would run... +To execute @unit@ tests you can run: {code} -grails test-app functional:spock +grails test-app -unit {code} -More than one pattern can be specified... +To run @integration@ tests you would run... {code} -grails test-app unit:spock integration:spock +grails test-app -integration {code} -h4. Targeting Tests in Types and/or Phases +h4. Targeting Tests When Using Phases -Test and type/phase targetting can be applied at the same time: +Test and phase targeting can be applied at the same time: {code} -grails test-app integration: unit: some.org.**.* +grails test-app some.org.**.* -unit {code} -This would run all tests in the @integration@ and @unit@ phases that are in the package @some.org@ or a subpackage. +This would run all tests in the @unit@ phase that are in the package @some.org@ or a subpackage. From 4c4c1f7a61653ae73538254cb779cbc08f7202c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADs=20Miguel=20Dias=20Duarte?= Date: Mon, 13 Jul 2015 15:26:36 +0100 Subject: [PATCH 205/230] Update hql.gdoc Update Documentation for grails/grails-data-mapping Pull Request #544 --- src/en/guide/GORM/querying/hql.gdoc | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/en/guide/GORM/querying/hql.gdoc b/src/en/guide/GORM/querying/hql.gdoc index ef37b0f0db3..d1908010f74 100644 --- a/src/en/guide/GORM/querying/hql.gdoc +++ b/src/en/guide/GORM/querying/hql.gdoc @@ -49,9 +49,15 @@ from Book as b, \\\ where b.author = a and a.surname = ?", ['Smith']) {code} -{note} -Triple-quoted Groovy multiline Strings will NOT work with HQL queries. -{note} +or + +{code:java} +def results = Book.findAll(""" +from Book as b, + Author as a +where b.author = a and a.surname = ?", ['Smith'] +""") +{code} h4. Pagination and Sorting From aa36caa10275b2f6a157389405594d4f75bd3bb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADs=20Miguel=20Dias=20Duarte?= Date: Mon, 13 Jul 2015 19:57:47 +0100 Subject: [PATCH 206/230] Update hql.gdoc Added Note for version --- src/en/guide/GORM/querying/hql.gdoc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/en/guide/GORM/querying/hql.gdoc b/src/en/guide/GORM/querying/hql.gdoc index d1908010f74..3fc37014bf3 100644 --- a/src/en/guide/GORM/querying/hql.gdoc +++ b/src/en/guide/GORM/querying/hql.gdoc @@ -40,6 +40,10 @@ def books = Book.findAll("from Book as book where book.author = :author", h4. Multiline Queries +-{note} +-As of Grails 3.0.3, Triple-quoted Groovy multiline Strings now work properly with HQL queries. +-{note} + Use the line continuation character to separate the query across multiple lines: {code:java} From 8cb83d29d4a1456c13b7fa7b4b6693e1a892c7a5 Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Tue, 14 Jul 2015 09:14:06 +0530 Subject: [PATCH 207/230] Grammar, content Fixed grammar, content. --- src/en/guide/contributing/issues.gdoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/en/guide/contributing/issues.gdoc b/src/en/guide/contributing/issues.gdoc index b121f0d284b..40446c13cd8 100644 --- a/src/en/guide/contributing/issues.gdoc +++ b/src/en/guide/contributing/issues.gdoc @@ -1,6 +1,6 @@ -Grails uses [Github|https://github.com/grails/grails-core/issues] to track issues in the core framework. Similarly for its [documentation|https://github.com/grails/grails-doc/issues] have a separate tracker. If you've found a bug or wish to see a particular feature added, this is the place to start. You'll need to create a (free) github account in order to either submit an issue or comment on an existing one in either of these. +Grails uses Github to track issues in the [core framework|https://github.com/grails/grails-core/issues]. Similarly for its documentation there is a [separate tracker|https://github.com/grails/grails-doc/issues]. If you've found a bug or wish to see a particular feature added, these are the places to start. You'll need to create a (free) github account in order to either submit an issue or comment on an existing one in either of these. -When submitting issues, please provide as much information as possible and in the case of bugs, make sure you explain which versions of Grails and various plugins you are using. Also, an issue is much more likely to be dealt with if you upload a reproducible sample application on a github repository. +When submitting issues, please provide as much information as possible and in the case of bugs, make sure you explain which versions of Groovy, Grails and various plugins you are using. Other environment details - OS version, JDK, Gradle etc. should also be included. Also, an issue is much more likely to be dealt with if you upload a reproducible sample application on a github repository and provide a link in the issue. h3. Reviewing issues From aded355ee2cef0b06c6ae3451d3636cb0e0158bd Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Tue, 14 Jul 2015 09:20:52 +0530 Subject: [PATCH 208/230] Grammar mistake --- src/en/guide/contributing/build.gdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/en/guide/contributing/build.gdoc b/src/en/guide/contributing/build.gdoc index 45ba31f0934..a3c4bb2ef99 100644 --- a/src/en/guide/contributing/build.gdoc +++ b/src/en/guide/contributing/build.gdoc @@ -21,7 +21,7 @@ If you look at the project structure, you'll see that it doesn't look much like This will fetch all the standard dependencies required by Grails and then build a @GRAILS_HOME@ installation. Note that this target skips the extensive collection of Grails test classes, which can take some time to complete. -Once the above command has finished, simply set the @GRAILS_HOME@ environment variable to the checkout directory and add the "bin" directory to your path. When you next type run the @grails@ command, you'll be using the version you just built. +Once the above command has finished, simply set the @GRAILS_HOME@ environment variable to the checkout directory and add the "bin" directory to your path. When you next type @grails@ command to run, you'll be using the version you just built. h3. Running the test suite From 6addc8f28a12532a9fba0e6a2aa57dd83f265ddd Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Tue, 14 Jul 2015 09:22:16 +0530 Subject: [PATCH 209/230] contributing to any part --- src/en/guide/contributing/build.gdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/en/guide/contributing/build.gdoc b/src/en/guide/contributing/build.gdoc index 45ba31f0934..2a69a1b3abb 100644 --- a/src/en/guide/contributing/build.gdoc +++ b/src/en/guide/contributing/build.gdoc @@ -1,4 +1,4 @@ -If you're interested in contributing fixes and features to the core framework, you will have to learn how to get hold of the project's source, build it and test it with your own applications. Before you start, make sure you have: +If you're interested in contributing fixes and features to any part of grails, you will have to learn how to get hold of the project's source, build it and test it with your own applications. Before you start, make sure you have: * A JDK (1.6 or above) * A git client From 7b8525bddf07429d03f29f6760e342a4ab11f639 Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Tue, 14 Jul 2015 09:42:10 +0530 Subject: [PATCH 210/230] JIRA to github in contributing --- src/en/guide/contributing/patchesCore.gdoc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/en/guide/contributing/patchesCore.gdoc b/src/en/guide/contributing/patchesCore.gdoc index d417f2d656f..eee9e6d76b3 100644 --- a/src/en/guide/contributing/patchesCore.gdoc +++ b/src/en/guide/contributing/patchesCore.gdoc @@ -14,13 +14,13 @@ git checkout -b mine This will create a new local branch called "mine" based off the "master" branch. Of course, you can name the branch whatever you like - you don't have to use "mine". -h4. Create JIRAs for non-trivial changes +h4. Create Github issues for non-trivial changes -For any non-trivial changes, raise a JIRA issue if one doesn't already exist. That helps us keep track of what changes go into each new version of Grails. +For any non-trivial changes, raise an issue on github if one doesn't already exist. That helps us keep track of what changes go into each new version of Grails. -h4. Include JIRA issue ID in commit messages +h4. Include github issue ID in commit messages -This may not seem particularly important, but having a JIRA issue ID in a commit message means that we can find out at a later date why a change was made. Include the ID in any and all commits that relate to that issue. If a commit isn't related to an issue, then there's no need to include an issue ID. +This may not seem particularly important, but having a github issue ID in a commit message means that we can find out at a later date why a change was made. Include the ID in any and all commits that relate to that issue. If a commit isn't related to an issue, then there's no need to include an issue ID. h4. Make sure your fork is up to date @@ -55,4 +55,4 @@ You're now ready to send the pull request from the GitHub user interface. h4. Say what your pull request is for -A pull request can contain any number of commits and it may be related to any number of issues. In the pull request message, please specify the IDs of all issues that the request relates to. Also give a brief description of the work you have done, such as: "I refactored the data binder and added support for custom number editors (GRAILS-xxxx)". \ No newline at end of file +A pull request can contain any number of commits and it may be related to any number of issues. In the pull request message, please specify the IDs of all issues that the request relates to. Also give a brief description of the work you have done, such as: "I refactored the data binder and added support for custom number editors (GRAILS-xxxx)". From 74bea6aad0a335f32b8ea8b69326d95bb68749c1 Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Tue, 14 Jul 2015 14:35:13 +0530 Subject: [PATCH 211/230] Update information about JDK to min. JDK 7 --- src/en/guide/contributing/build.gdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/en/guide/contributing/build.gdoc b/src/en/guide/contributing/build.gdoc index 3c3795e5c3a..29d186a5bbd 100644 --- a/src/en/guide/contributing/build.gdoc +++ b/src/en/guide/contributing/build.gdoc @@ -1,6 +1,6 @@ If you're interested in contributing fixes and features to any part of grails, you will have to learn how to get hold of the project's source, build it and test it with your own applications. Before you start, make sure you have: -* A JDK (1.6 or above) +* A JDK (7 or above) * A git client Once you have all the pre-requisite packages installed, the next step is to download the Grails source code, which is hosted at [GitHub|http://github.com] in several repositories owned by the ["grails" GitHub user|http://github.com/grails]. This is a simple case of cloning the repository you're interested in. For example, to get the core framework run: From 242a717b6b51a80762d0ba18e5b7391582594fe4 Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Thu, 16 Jul 2015 21:25:20 +0530 Subject: [PATCH 212/230] Made a note about the limit This may catch people off guard so good to have it as a note. --- src/en/guide/theWebLayer/controllers/dataBinding.gdoc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/en/guide/theWebLayer/controllers/dataBinding.gdoc b/src/en/guide/theWebLayer/controllers/dataBinding.gdoc index 8da6474114a..2c89f123479 100644 --- a/src/en/guide/theWebLayer/controllers/dataBinding.gdoc +++ b/src/en/guide/theWebLayer/controllers/dataBinding.gdoc @@ -340,7 +340,11 @@ Binding to a @Map@ property works the same way except that the list index in the This would bind the selected image into the @Map@ property @images@ under a key of @"cover"@. -When binding to Maps, Arrays and Collections the data binder will automatically grow the size of the collections as necessary. The default limit to how large the binder will grow a collection is 256. If the data binder encounters an entry that requires the collection be grown beyond that limit, the entry is ignored. The limit may be configured by assigning a value to the @grails.databinding.autoGrowCollectionLimit@ property in @Config.groovy@. +When binding to Maps, Arrays and Collections the data binder will automatically grow the size of the collections as necessary. + +{note} +The default limit to how large the binder will grow a collection is 256. If the data binder encounters an entry that requires the collection be grown beyond that limit, the entry is ignored. The limit may be configured by assigning a value to the @grails.databinding.autoGrowCollectionLimit@ property in @Config.groovy@. +{note} {code:java} // grails-app/conf/application.groovy From 8a6c7b4342e7fa040184b8c578d95ed1e386bed1 Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Sat, 18 Jul 2015 22:28:21 +0530 Subject: [PATCH 213/230] Update that functionalities were removed Added that beforeInterceptor and afterInterceptor were removed. --- src/en/guide/upgrading.gdoc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/en/guide/upgrading.gdoc b/src/en/guide/upgrading.gdoc index ad4ea831905..cbe75322ab9 100644 --- a/src/en/guide/upgrading.gdoc +++ b/src/en/guide/upgrading.gdoc @@ -2,6 +2,8 @@ Grails 3.0 is a complete ground up rewrite of Grails and introduces new concepts When upgrading an application or plugin from Grails 3.0 there are many areas to consider including: +* Removal of dynamic scaffolding +* Removal of before and after interceptors * Project structure differences * File location differences * Configuration differences @@ -13,7 +15,11 @@ When upgrading an application or plugin from Grails 3.0 there are many areas to The best approach to take when upgrading a plugin or application (and if your application is using several plugins the plugins will need upgrading first) is to create a new Grails 3.0 application of the same name and copy the source files into the correct locations in the new application. -h3. Project Structure Changes +h3. Removal of before and after interceptors + +Before and after interceptors were removed. So all @beforeInterceptor@ and @afterInterceptor@ need to be replaced by Stand alone interceptors. + +h4. File Location Differences h4. File Location Differences From 7ba4dcf2e4b012018c07f820436136913b6fab16 Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Sat, 18 Jul 2015 22:31:20 +0530 Subject: [PATCH 214/230] Update toc.yml --- src/en/guide/toc.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/src/en/guide/toc.yml b/src/en/guide/toc.yml index e7a71b6beea..50decb39648 100644 --- a/src/en/guide/toc.yml +++ b/src/en/guide/toc.yml @@ -120,7 +120,6 @@ theWebLayer: controllersAndScopes: Controllers and Scopes modelsAndViews: Models and Views redirectsAndChaining: Redirects and Chaining - controllerInterceptors: Controller Interceptors dataBinding: Data Binding xmlAndJSON: XML and JSON Responses moreOnJSONBuilder: More on JSONBuilder From 84bed2fe24ebbd783b6b156d0afeea68f44b4894 Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Sat, 18 Jul 2015 22:34:28 +0530 Subject: [PATCH 215/230] Delete controllerInterceptors.gdoc --- .../controllers/controllerInterceptors.gdoc | 79 ------------------- 1 file changed, 79 deletions(-) delete mode 100644 src/en/guide/theWebLayer/controllers/controllerInterceptors.gdoc diff --git a/src/en/guide/theWebLayer/controllers/controllerInterceptors.gdoc b/src/en/guide/theWebLayer/controllers/controllerInterceptors.gdoc deleted file mode 100644 index 06ef752fa66..00000000000 --- a/src/en/guide/theWebLayer/controllers/controllerInterceptors.gdoc +++ /dev/null @@ -1,79 +0,0 @@ -Often it is useful to intercept processing based on either request, session or application state. This can be achieved with action interceptors. There are currently two types of interceptors: before and after. - -{note} -If your interceptor is likely to apply to more than one controller, you are almost certainly better off writing a standalone [Interceptor|guide:interceptors]. Standaline Interceptors can be applied to multiple controllers or URIs without the need to change the logic of each controller -{note} - -h4. Before Interception - -The @beforeInterceptor@ intercepts processing before the action is executed. If it returns @false@ then the intercepted action will not be executed. The interceptor can be defined for all actions in a controller as follows: - -{code:java} -def beforeInterceptor = { - println "Tracing action ${actionUri}" -} -{code} - -The above is declared inside the body of the controller definition. It will be executed before all actions and does not interfere with processing. A common use case is very simplistic authentication: - -{code:java} -def beforeInterceptor = [action: this.&auth, except: 'login'] - -// defined with private scope, so it's not considered an action -private auth() { - if (!session.user) { - redirect(action: 'login') - return false - } -} - -def login() { - // display login page -} -{code} - -The above code defines a method called @auth@. A private method is used so that it is not exposed as an action to the outside world. The @beforeInterceptor@ then defines an interceptor that is used on all actions _except_ the login action and it executes the @auth@ method. The @auth@ method is referenced using Groovy's method pointer syntax. Within the method it detects whether there is a user in the session, and if not it redirects to the @login@ action and returns @false@, causing the intercepted action to not be processed. - -h4. After Interception - -Use the @afterInterceptor@ property to define an interceptor that is executed after an action: - -{code:java} -def afterInterceptor = { model -> - println "Tracing action ${actionUri}" -} -{code} - -The after interceptor takes the resulting model as an argument and can hence manipulate the model or response. - -An after interceptor may also modify the Spring MVC [ModelAndView|api:org.springframework.web.servlet.ModelAndView] object prior to rendering. In this case, the above example becomes: - -{code:java} -def afterInterceptor = { model, modelAndView -> - println "Current view is ${modelAndView.viewName}" - if (model.someVar) modelAndView.viewName = "/mycontroller/someotherview" - println "View is now ${modelAndView.viewName}" -} -{code} - -This allows the view to be changed based on the model returned by the current action. Note that the @modelAndView@ may be @null@ if the action being intercepted called @redirect@ or @render@. - -h4. Interception Conditions - -Rails users will be familiar with the authentication example and how the 'except' condition was used when executing the interceptor (interceptors are called 'filters' in Rails; this terminology conflicts with Servlet filter terminology in Java): - -{code:java} -def beforeInterceptor = [action: this.&auth, except: 'login'] -{code} - -This executes the interceptor for all actions except the specified action. A list of actions can also be defined as follows: - -{code:java} -def beforeInterceptor = [action: this.&auth, except: ['login', 'register']] -{code} - -The other supported condition is 'only', this executes the interceptor for only the specified action(s): - -{code:java} -def beforeInterceptor = [action: this.&auth, only: ['secure']] -{code} From e7fcd5c6a36dc97ba42ecbf78626d269a6509e3b Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Sat, 18 Jul 2015 22:37:18 +0530 Subject: [PATCH 216/230] Update to remove reference to interceptor Update to remove reference to controller interceptors --- src/en/guide/theWebLayer/interceptors.gdoc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/en/guide/theWebLayer/interceptors.gdoc b/src/en/guide/theWebLayer/interceptors.gdoc index aedbdc7d3ef..59ce7b62504 100644 --- a/src/en/guide/theWebLayer/interceptors.gdoc +++ b/src/en/guide/theWebLayer/interceptors.gdoc @@ -1,6 +1,4 @@ -Although Grails [controllers|guide:controllers] support fine grained interceptors, these are only really useful when applied to a few controllers and become difficult to manage with larger applications. - -To solve this you can create standalone Interceptors using the [create-interceptor|commandLine] command: +Grails provides standalone Interceptors using the [create-interceptor|commandLine] command: {code} $ grails create-interceptor MyInterceptor From fe2b55e6cfbde1fb246327711c4a40ffce4f433e Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Wed, 22 Jul 2015 01:10:08 +0530 Subject: [PATCH 217/230] Added information to use via gvm --- src/en/guide/contributing/build.gdoc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/en/guide/contributing/build.gdoc b/src/en/guide/contributing/build.gdoc index 29d186a5bbd..444a2da0c44 100644 --- a/src/en/guide/contributing/build.gdoc +++ b/src/en/guide/contributing/build.gdoc @@ -23,6 +23,14 @@ This will fetch all the standard dependencies required by Grails and then build Once the above command has finished, simply set the @GRAILS_HOME@ environment variable to the checkout directory and add the "bin" directory to your path. When you next type @grails@ command to run, you'll be using the version you just built. +If you are using @gvm@ then that can also be used to work with this local installation via the following: + +{code} +gvm install grails dev /path/to/grails-core +{code} + +Now you will have a dev version in your local which you can use to test your features. + h3. Running the test suite All you have to do to run the full suite of tests is: From 6d9c986306ee56a1b529e79362dae6b290d273db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ronny=20L=C3=B8vtangen?= Date: Wed, 22 Jul 2015 08:40:02 +0200 Subject: [PATCH 218/230] Use GitHub issue id rather than Jira id in example commit message --- src/en/guide/contributing/patchesCore.gdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/en/guide/contributing/patchesCore.gdoc b/src/en/guide/contributing/patchesCore.gdoc index eee9e6d76b3..aa957bf1cdc 100644 --- a/src/en/guide/contributing/patchesCore.gdoc +++ b/src/en/guide/contributing/patchesCore.gdoc @@ -55,4 +55,4 @@ You're now ready to send the pull request from the GitHub user interface. h4. Say what your pull request is for -A pull request can contain any number of commits and it may be related to any number of issues. In the pull request message, please specify the IDs of all issues that the request relates to. Also give a brief description of the work you have done, such as: "I refactored the data binder and added support for custom number editors (GRAILS-xxxx)". +A pull request can contain any number of commits and it may be related to any number of issues. In the pull request message, please specify the IDs of all issues that the request relates to. Also give a brief description of the work you have done, such as: "I refactored the data binder and added support for custom number editors. Fixes #xxxx". From d705738368e48fa8fc4dcb80006162d1e3a651a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ronny=20L=C3=B8vtangen?= Date: Wed, 22 Jul 2015 10:01:46 +0200 Subject: [PATCH 219/230] Specify branch for git pull from upstream. If not, you will get this error message: You asked to pull from the remote 'upstream', but did not specify a branch. Because this is not the default configured remote for your current branch, you must specify a branch on the command line. --- src/en/guide/contributing/patchesCore.gdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/en/guide/contributing/patchesCore.gdoc b/src/en/guide/contributing/patchesCore.gdoc index eee9e6d76b3..17bd4d95507 100644 --- a/src/en/guide/contributing/patchesCore.gdoc +++ b/src/en/guide/contributing/patchesCore.gdoc @@ -29,7 +29,7 @@ Since the core developers must merge your commits into the main repository, it m Let's say you have the main repository set up as a remote called "upstream" and you want to submit a pull request. Also, all your changes are currently on the local "mine" branch but not on "master". The first step involves pulling any changes from the main repository that have been added since you last fetched and merged: {code} git checkout master -git pull upstream +git pull upstream master {code} This should complete without any problems or conflicts. Next, rebase your local branch against the now up-to-date master: From 39b4b57e758b4691ac2290021257e70bf4bcc908 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ronny=20L=C3=B8vtangen?= Date: Wed, 22 Jul 2015 10:21:55 +0200 Subject: [PATCH 220/230] Update from upstream before creating branch --- src/en/guide/contributing/patchesCore.gdoc | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/en/guide/contributing/patchesCore.gdoc b/src/en/guide/contributing/patchesCore.gdoc index 17bd4d95507..8ede5b127fc 100644 --- a/src/en/guide/contributing/patchesCore.gdoc +++ b/src/en/guide/contributing/patchesCore.gdoc @@ -5,6 +5,13 @@ One of the benefits of [GitHub|http://github.com] is the way that you can easily What follows are some guidelines to help ensure that your pull requests are speedily dealt with and provide the information we need. They will also make your life easier! +h4. Make sure your fork is up to date + +Making changes to outdated sources is not a good idea. Maybe someone already done the change. +{code} +git pull upstream master +{code} + h4. Create a local branch for your changes Your life will be greatly simplified if you create a local branch to make your changes on. For example, as soon as you fork a repository and clone the fork locally, execute @@ -22,7 +29,7 @@ h4. Include github issue ID in commit messages This may not seem particularly important, but having a github issue ID in a commit message means that we can find out at a later date why a change was made. Include the ID in any and all commits that relate to that issue. If a commit isn't related to an issue, then there's no need to include an issue ID. -h4. Make sure your fork is up to date +h4. Make sure your fork is up to date again and rebase Since the core developers must merge your commits into the main repository, it makes life much easier if your fork on GitHub is up to date before you send a pull request. From 608b0dbbbc86e9ace24438e04df7256d0b06eb84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ronny=20L=C3=B8vtangen?= Date: Wed, 22 Jul 2015 10:45:51 +0200 Subject: [PATCH 221/230] Send Pull Request from branch, not from master. If not you risk being out of sync with upstream master forever. Also, if you add more changes to master they will all be part of the same Pull Request. --- src/en/guide/contributing/patchesCore.gdoc | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/en/guide/contributing/patchesCore.gdoc b/src/en/guide/contributing/patchesCore.gdoc index eee9e6d76b3..e3b462c77fd 100644 --- a/src/en/guide/contributing/patchesCore.gdoc +++ b/src/en/guide/contributing/patchesCore.gdoc @@ -40,17 +40,18 @@ git rebase master What this does is rearrange the commits such that all of your changes come after the most recent one in master. Think adding some cards to the top of a deck rather than shuffling them into the pack. -You'll now be able to do a clean merge from your local branch to master: -{code} -git checkout master -git merge mine -{code} +h4. Push your branch to GitHub and send Pull Request + +Finally, you must push your changes to your fork on GitHub, otherwise the core developers won't be able to pick them up: -Finally, you must push your changes to your remote repository on GitHub, otherwise the core developers won't be able to pick them up: {code} -git push +git push origin mine {code} +{note} +You should not merge your branch to your forks master. If the Pull Request is not accepted, your master will then be out of sync with upstream forever. +{note} + You're now ready to send the pull request from the GitHub user interface. h4. Say what your pull request is for From 2cf82fc7a86f8774574c564e8f55ba0eee73b4b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ronny=20L=C3=B8vtangen?= Date: Wed, 22 Jul 2015 10:52:50 +0200 Subject: [PATCH 222/230] There is no README.txt, suppose it's now README.md --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index a1d3e6cd5c8..5daeb62f802 100644 --- a/build.gradle +++ b/build.gradle @@ -42,7 +42,7 @@ task fetchGrailsSource << { println "Downloading Grails source code. If you already have a copy " + "of the Grails source code checked out you can avoid this download " + "by setting the grails.home system property to point to your local " + - "copy of the source. See README.txt for more information." + "copy of the source. See README.md for more information." def zipFile = "${checkOutDir}/grails-src.zip" ant.get src: "http://github.com/grails/grails-core/zipball/${githubBranch}", dest: zipFile, verbose: true From 2fd9558e1d9bd189c9b37fd7166b34be29298325 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ronny=20L=C3=B8vtangen?= Date: Wed, 22 Jul 2015 22:39:54 +0200 Subject: [PATCH 223/230] Grammar correction, thanks to chery-qualset-hcd-ca-gov --- src/en/guide/contributing/patchesCore.gdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/en/guide/contributing/patchesCore.gdoc b/src/en/guide/contributing/patchesCore.gdoc index 8ede5b127fc..52ff5a6b6b0 100644 --- a/src/en/guide/contributing/patchesCore.gdoc +++ b/src/en/guide/contributing/patchesCore.gdoc @@ -7,7 +7,7 @@ What follows are some guidelines to help ensure that your pull requests are spee h4. Make sure your fork is up to date -Making changes to outdated sources is not a good idea. Maybe someone already done the change. +Making changes to outdated sources is not a good idea. Someone else may have already made the change. {code} git pull upstream master {code} From 3a407812c7c62ab908c0b36ebdb907cc87aa11f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ronny=20L=C3=B8vtangen?= Date: Wed, 22 Jul 2015 22:57:23 +0200 Subject: [PATCH 224/230] Use "issue_123" as example branch name to illustrate that there should be a branch for each Pull Request. --- src/en/guide/contributing/patchesCore.gdoc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/en/guide/contributing/patchesCore.gdoc b/src/en/guide/contributing/patchesCore.gdoc index e3b462c77fd..dada8924d7f 100644 --- a/src/en/guide/contributing/patchesCore.gdoc +++ b/src/en/guide/contributing/patchesCore.gdoc @@ -9,10 +9,10 @@ h4. Create a local branch for your changes Your life will be greatly simplified if you create a local branch to make your changes on. For example, as soon as you fork a repository and clone the fork locally, execute {code} -git checkout -b mine +git checkout -b issue_123 {code} -This will create a new local branch called "mine" based off the "master" branch. Of course, you can name the branch whatever you like - you don't have to use "mine". +This will create a new local branch called "issue_123" based off the "master" branch. Of course, you can name the branch whatever you like, but a good idea would be to reference the GitHub issue number that the change is relevant to. Each Pull Request should have its own branch. h4. Create Github issues for non-trivial changes @@ -26,7 +26,7 @@ h4. Make sure your fork is up to date Since the core developers must merge your commits into the main repository, it makes life much easier if your fork on GitHub is up to date before you send a pull request. -Let's say you have the main repository set up as a remote called "upstream" and you want to submit a pull request. Also, all your changes are currently on the local "mine" branch but not on "master". The first step involves pulling any changes from the main repository that have been added since you last fetched and merged: +Let's say you have the main repository set up as a remote called "upstream" and you want to submit a pull request. Also, all your changes are currently on the local "issue_123" branch but not on "master". The first step involves pulling any changes from the main repository that have been added since you last fetched and merged: {code} git checkout master git pull upstream @@ -34,7 +34,7 @@ git pull upstream This should complete without any problems or conflicts. Next, rebase your local branch against the now up-to-date master: {code} -git checkout mine +git checkout issue_123 git rebase master {code} @@ -45,7 +45,7 @@ h4. Push your branch to GitHub and send Pull Request Finally, you must push your changes to your fork on GitHub, otherwise the core developers won't be able to pick them up: {code} -git push origin mine +git push origin issue_123 {code} {note} From d9bb0ee00eaaecfd1123f2d4824990b93c4062de Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Tue, 28 Jul 2015 00:38:46 +0530 Subject: [PATCH 225/230] dynamic scaffolding docs added back --- src/en/guide/scaffolding.gdoc | 92 ++++++++++++++++++++++++++++++++--- src/en/guide/upgrading.gdoc | 2 +- 2 files changed, 87 insertions(+), 7 deletions(-) diff --git a/src/en/guide/scaffolding.gdoc b/src/en/guide/scaffolding.gdoc index 72ffb4d3b93..ee2a6e67b73 100644 --- a/src/en/guide/scaffolding.gdoc +++ b/src/en/guide/scaffolding.gdoc @@ -17,6 +17,86 @@ The way for an application to express a dependency on the scaffolding plugin is } {code} +h4. Dynamic Scaffolding + +The simplest way to get started with scaffolding is to enable it with the @scaffold@ property. Set the @scaffold@ property in the controller to @true@ for the @Book@ domain class: + +{code:java} +class BookController { + static scaffold = true +} +{code} + +This works because the @BookController@ follows the same naming convention as the @Book@ domain class. To scaffold a specific domain class we could reference the class directly in the scaffold property: + +{code:java} +class SomeController { + static scaffold = Author +} +{code} + +With this configured, when you start your application the actions and views will be autogenerated at runtime. The following actions are dynamically implemented by default by the runtime scaffolding mechanism: + +* index +* show +* edit +* delete +* create +* save +* update + +A CRUD interface will also be generated. To access this open @http://localhost:8080/app/book@ in a browser. + +If you prefer to keep your domain model in Java and [mapped with Hibernate|guide:hibernate] you can still use scaffolding, simply import the domain class and set its name as the @scaffold@ argument. + +You can add new actions to a scaffolded controller, for example: + +{code:java} +class BookController { + + static scaffold = Book + + def changeAuthor() { + def b = Book.get(params.id) + b.author = Author.get(params["author.id"]) + b.save() + + // redirect to a scaffolded action + redirect(action:show) + } } +} +{code} + +You can also override the scaffolded actions: + +{code:java} +class BookController { + + static scaffold = Book + + // overrides scaffolded action to return both authors and books + def index() { + [bookInstanceList: Book.list(), + bookInstanceTotal: Book.count(), + authorInstanceList: Author.list()] + } + + def show() { + def book = Book.get(params.id) + log.error(book) + [bookInstance : book] + } +} +{code} + +All of this is what is known as "dynamic scaffolding" where the CRUD interface is generated dynamically at runtime. + +{note} +By default, the size of text areas in scaffolded views is defined in the CSS, so adding 'rows' and 'cols' attributes will have no effect. + +Also, the standard scaffold views expect model variables of the form @InstanceList@ for collections and @Instance@ for single instances. It's tempting to use properties like 'books' and 'book', but those won't work. +{note} + h4. Static Scaffolding Grails lets you generate a controller and the views used to create the above interface from the command line. To generate a controller type: @@ -28,24 +108,24 @@ grails generate-controller Book or to generate the views: {code:java} -grails generate-views Book +grails generateviews Book {code} or to generate everything: {code:java} -grails generate-all Book +grails generateall Book {code} If you have a domain class in a package or are generating from a [Hibernate mapped class|guide:hibernate] remember to include the fully qualified package name: {code:java} -grails generate-all com.bookstore.Book +grails generateall com.bookstore.Book {code} h4. Customizing the Generated Views -The views adapt to [Validation constraints|guide:constraints]. For example you can change the order that fields appear in the views simply by re-ordering the constraints in the builder: +The views adapt to [Validation constraints|guide:constraints]. For example you can change the order that fields appear in the views simply by reordering the constraints in the builder: {code:java} def constraints = { @@ -59,7 +139,7 @@ You can also get the generator to generate lists instead of text inputs if you u {code:java} def constraints = { title() - category(inList: ["Fiction", "Non-fiction", "Biography"]) + category(inList: ["Fiction", "Nonfiction", "Biography"]) releaseDate() } {code} @@ -82,4 +162,4 @@ def constraints = { h4. Customizing the Scaffolding templates -The templates used by Grails to generate the controller and views can be customized by installing the templates with the [install-templates|commandLine] command. +The templates used by Grails to generate the controller and views can be customized by installing the templates with the [installtemplates|commandLine] command. diff --git a/src/en/guide/upgrading.gdoc b/src/en/guide/upgrading.gdoc index cbe75322ab9..cc2a131a2b1 100644 --- a/src/en/guide/upgrading.gdoc +++ b/src/en/guide/upgrading.gdoc @@ -2,7 +2,7 @@ Grails 3.0 is a complete ground up rewrite of Grails and introduces new concepts When upgrading an application or plugin from Grails 3.0 there are many areas to consider including: -* Removal of dynamic scaffolding +* Removal of dynamic scaffolding from Grails 3.0.0 till 3.0.4 when it was re-introduced * Removal of before and after interceptors * Project structure differences * File location differences From 789e3f019931dc00cbc5e2b30f037ff51b61bdd8 Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Tue, 28 Jul 2015 00:49:21 +0530 Subject: [PATCH 226/230] - Added install-templates docs again from 1251a021a432de7bde6d42a4bc28b63faa4738ae - Fixed reference to install-templates --- src/en/guide/scaffolding.gdoc | 2 +- .../ref/Command Line/install-templates.gdoc | 39 +++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 src/en/ref/Command Line/install-templates.gdoc diff --git a/src/en/guide/scaffolding.gdoc b/src/en/guide/scaffolding.gdoc index ee2a6e67b73..2edf840c08a 100644 --- a/src/en/guide/scaffolding.gdoc +++ b/src/en/guide/scaffolding.gdoc @@ -162,4 +162,4 @@ def constraints = { h4. Customizing the Scaffolding templates -The templates used by Grails to generate the controller and views can be customized by installing the templates with the [installtemplates|commandLine] command. +The templates used by Grails to generate the controller and views can be customized by installing the templates with the [install-templates|commandLine] command. diff --git a/src/en/ref/Command Line/install-templates.gdoc b/src/en/ref/Command Line/install-templates.gdoc new file mode 100644 index 00000000000..526fc0aafcf --- /dev/null +++ b/src/en/ref/Command Line/install-templates.gdoc @@ -0,0 +1,39 @@ +h1. install-templates + +h2. Purpose + +Copies the the templates used by Grails during code generation to your project directory + +h2. Examples + +{code:java} +grails install-templates +{code} + +h2. Description + +Usage: + +{code:java} +grails install-templates +{code} + +Fired Events: + +* @InstallTemplatesStart@ - Before the templates are installed +* @StatusUpdate@ - When the templates are successfully installed +* @InstallTemplatesEnd@ - After the templates have been installed + +The @install-templates@ command will copy the templates Grails uses for all code generation activities to the application's @src/templates@ directory. The templates directories include: + +{code:java} +src + templates + artifacts + scaffolding + war +{code} + +The @artifacts@ directory contains the templates used by the @create-* @ commands. +The @scaffolding@ directory contains templates used by the @generate-* @ commands. +The @war@ directory contains the web.xml template used to generate the deployment descriptor. From 4d4d06c04d8be4c9f5f98f577504922ced3c3eff Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Tue, 28 Jul 2015 00:52:48 +0530 Subject: [PATCH 227/230] Removed firing of events --- src/en/ref/Command Line/install-templates.gdoc | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/en/ref/Command Line/install-templates.gdoc b/src/en/ref/Command Line/install-templates.gdoc index 526fc0aafcf..5e55f86d12c 100644 --- a/src/en/ref/Command Line/install-templates.gdoc +++ b/src/en/ref/Command Line/install-templates.gdoc @@ -18,12 +18,6 @@ Usage: grails install-templates {code} -Fired Events: - -* @InstallTemplatesStart@ - Before the templates are installed -* @StatusUpdate@ - When the templates are successfully installed -* @InstallTemplatesEnd@ - After the templates have been installed - The @install-templates@ command will copy the templates Grails uses for all code generation activities to the application's @src/templates@ directory. The templates directories include: {code:java} From 1fecff403ee900623701631ca3a47f76fe4a4e95 Mon Sep 17 00:00:00 2001 From: Aseem Bansal Date: Tue, 28 Jul 2015 01:02:21 +0530 Subject: [PATCH 228/230] Fix mistakes in scaffolding docs --- src/en/guide/scaffolding.gdoc | 12 ++++++------ src/en/ref/Command Line/install-templates.gdoc | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/en/guide/scaffolding.gdoc b/src/en/guide/scaffolding.gdoc index 2edf840c08a..af1ddf90066 100644 --- a/src/en/guide/scaffolding.gdoc +++ b/src/en/guide/scaffolding.gdoc @@ -108,24 +108,24 @@ grails generate-controller Book or to generate the views: {code:java} -grails generateviews Book +grails generate-views Book {code} or to generate everything: {code:java} -grails generateall Book +grails generate-all Book {code} If you have a domain class in a package or are generating from a [Hibernate mapped class|guide:hibernate] remember to include the fully qualified package name: {code:java} -grails generateall com.bookstore.Book +grails generate-all com.bookstore.Book {code} h4. Customizing the Generated Views -The views adapt to [Validation constraints|guide:constraints]. For example you can change the order that fields appear in the views simply by reordering the constraints in the builder: +The views adapt to [Validation constraints|guide:constraints]. For example you can change the order that fields appear in the views simply by re-ordering the constraints in the builder: {code:java} def constraints = { @@ -139,7 +139,7 @@ You can also get the generator to generate lists instead of text inputs if you u {code:java} def constraints = { title() - category(inList: ["Fiction", "Nonfiction", "Biography"]) + category(inList: ["Fiction", "Non-fiction", "Biography"]) releaseDate() } {code} @@ -152,7 +152,7 @@ def constraints = { } {code} -Restricting the size with a constraint also effects how many characters can be entered in the generated view: +Restricting the size with a constraint also effects how many characters can be entered in the d view: {code:java} def constraints = { diff --git a/src/en/ref/Command Line/install-templates.gdoc b/src/en/ref/Command Line/install-templates.gdoc index 5e55f86d12c..1b30a85bcfe 100644 --- a/src/en/ref/Command Line/install-templates.gdoc +++ b/src/en/ref/Command Line/install-templates.gdoc @@ -18,7 +18,7 @@ Usage: grails install-templates {code} -The @install-templates@ command will copy the templates Grails uses for all code generation activities to the application's @src/templates@ directory. The templates directories include: +The @install-templates@ command will copy the templates Grails uses for all code generation activities to the application's @src/main/templates/scaffolding@ directory. The templates directories include: {code:java} src From bde386bac46ae59b27cccff2629b7abed3bc5bc2 Mon Sep 17 00:00:00 2001 From: Thomas Einwaller Date: Tue, 28 Jul 2015 21:31:16 +0200 Subject: [PATCH 229/230] copy commands for migration are wrong #345 --- src/en/guide/upgrading/upgradingApps.gdoc | 12 ++++++------ src/en/guide/upgrading/upgradingPlugins.gdoc | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/en/guide/upgrading/upgradingApps.gdoc b/src/en/guide/upgrading/upgradingApps.gdoc index e085d8c5892..35311c205ac 100644 --- a/src/en/guide/upgrading/upgradingApps.gdoc +++ b/src/en/guide/upgrading/upgradingApps.gdoc @@ -15,14 +15,14 @@ The next step is to copy the sources from the original Grails 2 application to t {code} # first the sources -cp -rf ../old_app/src/groovy src/main/groovy -cp -rf ../old_app/src/java src/main/groovy -cp -rf ../old_app/grails-app grails-app +cp -rf ../old_app/src/groovy/* src/main/groovy +cp -rf ../old_app/src/java/* src/main/groovy +cp -rf ../old_app/grails-app/* grails-app # then the tests -cp -rf ../old_app/test/unit src/test/groovy +cp -rf ../old_app/test/unit/* src/test/groovy mkdir -p src/integration-test/groovy -cp -rf ../old_app/test/integration src/integration-test/groovy +cp -rf ../old_app/test/integration/* src/integration-test/groovy {code} h4. Step 3 - Update the Gradle build with required dependencies @@ -51,7 +51,7 @@ h4. Step 7 - Migrate Static Assets not handled by Asset Pipeline If you have static assets in your @web-app@ directory of your Grails 2.x application such as HTML files, TLDs etc. these need to be moved. For public assets such as static HTML pages and so on these should go in @src/main/resources/public@. -TLD descriptors and non public assets should go in @src/main/resources/WEB-INF@. +TLD descriptors and non public assets should go in @src/main/resources/WEB-INF@. As noted earlier, @src/main/webapp@ folder can also be used for this purpose but it is not recommended. diff --git a/src/en/guide/upgrading/upgradingPlugins.gdoc b/src/en/guide/upgrading/upgradingPlugins.gdoc index e677e64070a..94316cb8ac9 100644 --- a/src/en/guide/upgrading/upgradingPlugins.gdoc +++ b/src/en/guide/upgrading/upgradingPlugins.gdoc @@ -16,18 +16,18 @@ The next step is to copy the sources from the original Grails 2 plugin to the Gr {code} # first the sources -cp -rf ../quartz-2.x/src/groovy src/main/groovy -cp -rf ../quartz-2.x/src/java src/main/groovy -cp -rf ../quartz-2.x/grails-app grails-app +cp -rf ../quartz-2.x/src/groovy/* src/main/groovy +cp -rf ../quartz-2.x/src/java/* src/main/groovy +cp -rf ../quartz-2.x/grails-app/* grails-app cp -rf ../quartz-2.x/QuartzGrailsPlugin.groovy src/main/groovy/grails/plugins/quartz # then the tests -cp -rf ../quartz-2.x/test/unit src/test/groovy +cp -rf ../quartz-2.x/test/unit/* src/test/groovy mkdir -p src/integration-test/groovy -cp -rf ../quartz-2.x/test/integration src/integration-test/groovy +cp -rf ../quartz-2.x/test/integration/* src/integration-test/groovy # then templates / other resources -cp -rf ../quartz-2.x/src/templates src/main/templates +cp -rf ../quartz-2.x/src/templates/* src/main/templates {code} h4. Step 3 - Alter the plugin descriptor From 600f01ba1c20f2ca288ea255ed670160bb9e17ef Mon Sep 17 00:00:00 2001 From: Thomas Einwaller Date: Wed, 29 Jul 2015 08:49:50 +0200 Subject: [PATCH 230/230] removed * form copy commands --- src/en/guide/upgrading/upgradingApps.gdoc | 10 +++++----- src/en/guide/upgrading/upgradingPlugins.gdoc | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/en/guide/upgrading/upgradingApps.gdoc b/src/en/guide/upgrading/upgradingApps.gdoc index 35311c205ac..e5424aa4da8 100644 --- a/src/en/guide/upgrading/upgradingApps.gdoc +++ b/src/en/guide/upgrading/upgradingApps.gdoc @@ -15,14 +15,14 @@ The next step is to copy the sources from the original Grails 2 application to t {code} # first the sources -cp -rf ../old_app/src/groovy/* src/main/groovy -cp -rf ../old_app/src/java/* src/main/groovy -cp -rf ../old_app/grails-app/* grails-app +cp -rf ../old_app/src/groovy/ src/main/groovy +cp -rf ../old_app/src/java/ src/main/groovy +cp -rf ../old_app/grails-app/ grails-app # then the tests -cp -rf ../old_app/test/unit/* src/test/groovy +cp -rf ../old_app/test/unit/ src/test/groovy mkdir -p src/integration-test/groovy -cp -rf ../old_app/test/integration/* src/integration-test/groovy +cp -rf ../old_app/test/integration/ src/integration-test/groovy {code} h4. Step 3 - Update the Gradle build with required dependencies diff --git a/src/en/guide/upgrading/upgradingPlugins.gdoc b/src/en/guide/upgrading/upgradingPlugins.gdoc index 94316cb8ac9..d625ae8493c 100644 --- a/src/en/guide/upgrading/upgradingPlugins.gdoc +++ b/src/en/guide/upgrading/upgradingPlugins.gdoc @@ -16,9 +16,9 @@ The next step is to copy the sources from the original Grails 2 plugin to the Gr {code} # first the sources -cp -rf ../quartz-2.x/src/groovy/* src/main/groovy -cp -rf ../quartz-2.x/src/java/* src/main/groovy -cp -rf ../quartz-2.x/grails-app/* grails-app +cp -rf ../quartz-2.x/src/groovy/ src/main/groovy +cp -rf ../quartz-2.x/src/java/ src/main/groovy +cp -rf ../quartz-2.x/grails-app/ grails-app cp -rf ../quartz-2.x/QuartzGrailsPlugin.groovy src/main/groovy/grails/plugins/quartz # then the tests @@ -27,7 +27,7 @@ mkdir -p src/integration-test/groovy cp -rf ../quartz-2.x/test/integration/* src/integration-test/groovy # then templates / other resources -cp -rf ../quartz-2.x/src/templates/* src/main/templates +cp -rf ../quartz-2.x/src/templates/ src/main/templates {code} h4. Step 3 - Alter the plugin descriptor