242
Space Details Key: GRAILS Name: Grails Description: Grails web application framework Creator (Creation Date): bwalding (Aug 12, 2005) Last Modifier (Mod. Date): hansamann (Oct 24, 2006) Available Pages Troubleshooting Using Constraints to Specify Database Column Types When Creating Tables from a Groovy Domain Class Community Contribute Developer Blogs Mailing lists User Groups Who we are Developer Documentation Compile Time Injection Developer - Dynamic Method Injection Developer - Groovy Server Pages Developer - Hibernate Integration Developer - Spring MVC Integration General Architecture Runtime Configuration Documentation Quick Start Reference Builders Reference Hibernate Criteria Builder Spring Bean Builder Command Line Dynamic Methods Reference Controller Dynamic Methods DomainClass Dynamic Methods Tag Library Reference GSP Tag Reference GSP Tag - collect GSP Tag - each GSP Tag - else Document generated by Confluence on Jan 31, 2007 10:29 Page 1

Grails Docs 0.4

Embed Size (px)

Citation preview

Space DetailsKey: Name: Description: Creator (Creation Date): GRAILS GrailsGrails web application framework

bwalding (Aug 12, 2005)

Last Modifier (Mod. Date): hansamann (Oct 24, 2006)

Available Pages Troubleshooting Using Constraints to Specify Database Column Types When Creating Tables from a Groovy Domain Class Community Contribute Developer Blogs Mailing lists User Groups Who we are Developer Documentation Compile Time Injection Developer - Dynamic Method Injection Developer - Groovy Server Pages Developer - Hibernate Integration Developer - Spring MVC Integration General Architecture Runtime Configuration Documentation Quick Start Reference Builders Reference Hibernate Criteria Builder Spring Bean Builder Command Line Dynamic Methods Reference Controller Dynamic Methods DomainClass Dynamic Methods Tag Library Reference GSP Tag Reference GSP Tag - collect GSP Tag - each GSP Tag - elsePage 1

Document generated by Confluence on Jan 31, 2007 10:29

GSP Tag - elseif GSP Tag - findAll GSP Tag - grep GSP Tag - if GSP Tag - layoutBody GSP Tag - layoutHead GSP Tag - layoutTitle GSP Tag - pageProperty GSP Tag - paginate GSP Tag - while Tag - actionSubmit Tag - actionSubmitImage Tag - checkBox Tag - createLink Tag - createLinkTo Tag - currencySelect Tag - datePicker Tag - eachError Tag - form Tag - formRemote Tag - hasErrors Tag - hiddenField Tag - link Tag - localeSelect Tag - message Tag - remoteField Tag - remoteFunction Tag - remoteLink Tag - render Tag - renderBean Tag - renderErrors Tag - richTextEditor Tag - select Tag - submitToRemote Tag - textArea Tag - textField Tag - timeZoneSelect Tag - validate JSP Tag Reference Validation Reference TipsAndTricks User guide Advanced Topics Ajax Artifact and Scaffolding TemplatesPage 2

Document generated by Confluence on Jan 31, 2007 10:29

FAQ

Auto Reloading Builders Command Line Scripting Command Line Tools Configuration Controllers Dynamic Encoding Methods Dynamic Tag Libraries Functional Testing GORM GORM - Creating a domain class GORM - CRUD GORM - Defining relationships GORM - Managing Relationships GORM - Mapping inheritance GORM - Querying Hibernate Integration Many-to-Many Mapping with Hibernate XML HTTP Method Restrictions IDE Integration Installation Introduction Job Scheduling (Quartz) Logging Sample Applications Scaffolding Services Spring Integration The Plug-in Developers Guide Auto Reloading Plugins Contribute a Plugin Creating Plugins Plugin Basics Plugin Dependencies Plugin Dynamic Methods ExpandoMetaClass Runtime Configuration Plugins Understanding Plugins Unit Testing Validation Views and Layouts

Document generated by Confluence on Jan 31, 2007 10:29

Page 3

TroubleshootingThis page last changed on Mar 22, 2006 by mittie.

Find hints how to avoid common pitfalls below.

grails cleanIn case your Grails application has been screwed and comes up with mysterious error messages try

grails clean

This may be needed after done the following operations: tbd tbd

restart the (jetty) serverGrails does a best effort to avoid the necessity of server restarts. However, under these circumstances, a server restart is required: tbd tbd In general, changes to the domain model do not require a server restart. When running with the internal HSQL database in 'in-memory' mode, changes to domain models force Grails to reload the classes, which will invevitably lead to all instances of the old classes being unavailable. This effectivly deletes the runtime objects of the HSQL DB. This does not happen with persistent DBs.

Problems with saving objects transparentlyIn case you have a bi-directional dependency, you need to care about proper synchronization of both sides, see XXX

Document generated by Confluence on Jan 31, 2007 10:29

Page 4

Using Constraints to Specify Database Column Types When Creating Tables from a Groovy Domain ClassThis page last changed on Dec 04, 2006 by [email protected].

Using Constraints to Specify Database Column Types When Creating Tables from a Groovy Domain Class

Note: This feature has been promoted to a JIRA issue (_GRAILS-391_). Grails should use a domain class's constraints to determine database column types when creating the underlying tables. Consider the following example. Suppose I have a domain model with the following attributes...

String state float salesTaxRate String description

In MySQL, Grails would define these columns as... column name salesTaxRate state description float varchar(255) varchar(255) data type

Assume that the developer would instead define the columns as follows if he were creating the table via an SQL script. column name salesTaxRate state description decimal(5,2) char(2) TEXT data type

Suppose the domain class includes the following constraints.

def constraints = { state(length:2..2,blank:false) salesTaxRate(range:0..100,blank:false) description(length:2..1000)}

The fact that the state attribute has a min length of 2 and a max length of 2 provides enough information for Grails to define the column as a char(2) instead of varchar(255). Since varchar needs one more byte compared to char to store its length, the developer could have saved one byte of memory. But what about the description? It's an optional property that length is specified between 2 and 1000, but as default it's mapped to a varchar(255). If the user enters more than 255 characters, he will get in touch with a hibernate exception message and his instance of domain will not persist! That could be

Document generated by Confluence on Jan 31, 2007 10:29

Page 5

prevented by using TEXT for String properties with a max-length > 255! Technically speaking: In grails, java.lang.String objects seem to be mapped as default using hibernate's "string"-mapping type and are stored as Standard-SQL build-in type "VARCHAR" with a length of 255. For the description property, either varchar's length has to be adapted to varchar(1000), or the hibernate mapping type "text" has to be used, that is stored as Standard-SQL build-in type "CLOB". We'd still need more configurable constraints though in order to for Grails to know that we want the salesTaxRate column defined as a decimal(5,2) instead of float. In other words, we'd need a way to specify the precision for any floating point numbers. (This would be a valuable constraint to have in its own right.) TODO: Define detailed rules regarding how various constraints map to hibernate mapping types and get hibernate's schema exporter do the rest for us.

Detailed Rules

This section explains the proposed rules for implementing this feature.

Scale - A New Constraint

Define a new constraint named scale (i.e., the number of digits to the right of the decimal point for a floating point number). For maximum usability, instead of generating validation errors when a property's value exceeds the defined scale, it would probably make more sense to just round off the value to the defined scale.

Replacing minLength/maxLength/length with minSize/maxSize/size

The minSize/maxSize/size constraints already provide the functionality found in minLength/maxLength/length. We should remove minLength/maxLength/length as the minSize/maxSize/size constraints offer more functionality and flexibility. The minLength, maxLength, and length constraints will be deprecated in the next Grails release and any use of these constraints will generate warnings. In the following Grails release, these constraints will be completely removed, and any use of these constraints will result an application error.

Which Constraints Affect the Schema Definition?

For String properties, the following constraints affect the schema definition: minSize/maxSize size For numeric properties, the following constraints affect the schema definition: minSize/maxSize size range

Document generated by Confluence on Jan 31, 2007 10:29

Page 6

For all properties, the following constraints affect the schema definition: unique Question: Is there a way to make use of the minLength and minSize constraints? In other words, is there any way to force Hibernate to recognize that the state property (in the example above) should be declared as CHAR(2) instead of VARCHAR(2)? No. We unfortunately cannot achieve this functionality with Hibernate in a DBMS-neutral manner. Question: By default, all properties/columns are not nullable. If the optionals property in the domain class includes property x, then column x is defined as nullable in the schema. However, we also have the nullable constraint which provides the validation logic. Am I correct in thinking we have some redundancy here? If so, can eliminate that duplication? Yes. See [GRAILS-472|http://jira.codehaus.org/browse/GRAILS-472].

How Do Constraints Affect the Schema Definition?

String Properties

If the maxsize constraint is defined or the size constraint is defined, then set the max column length based on the constraint value. If both the maxsize constraint and the size constraint are defined, then use min(maxsize, size.toInt) as the column length. (We want to use the minimum of the two, because any length that exceeds that minimum will result in a validation error.)

Numberic Properties

If the maxsize constraint, the size constraint, or the range constraint is defined, then set the column precision based on the constraint value. (Precision is the maximum number of digits for the number.) If more than one of these constraints is defined, then use the minimum precision value from the constraints. (We want to use the minimum of the two, because any number that exceeds that minimum precision will result in a validation error.) If the scale constraint is defined, then set the scale for the column based on the constraint value. This rule only applies to floating point numbers (i.e., java.lang.Float, java.Lang.Double, java.lang.BigDecimal, or subclasses of java.lang.BigDecimal). The constraints define the minimum/maximum numeric values, and we derive the maximum number of digits for use in the precision. For example... someFloatValue(maxSize:1000000, scale:3) would yield: someFloatValue DECIMAL(10, 3) precision = number of digits in maxSize + scale 10 = 7 + 3

Document generated by Confluence on Jan 31, 2007 10:29

Page 7

All Properties

If the unique constraint is defined, then declare the column as unique. (See GRAILS-339.)

Document generated by Confluence on Jan 31, 2007 10:29

Page 8

CommunityThis page last changed on Oct 13, 2006 by [email protected].

Get Involved!Grails has a growing following and if you want to get involved the developers are all nice people (promise!) who are keen to have ideas, code and just about anything contributed. There are a number of ways to get involved with the Grails community, you can: Take a look at the Mailing lists archives and post new questions/ideas to the commnity! Head over to the Grails Wiki an ever growing knowledge base of information about Grails. Actually, you're already at the Wiki, just click the "Edit" button at the bottom of this page! Get involved in the User Groups, the place where people meet to talk about Groovy and Grails. Come and chat to us on IRC at irc.codehaus.org where most Grails developers can be found in the #groovy room Write a Blog post about Grails, or even a Tutorial! Just talking about your experiences with Grails can either help others get involved or provide constructive feedback to the Grails team. Follow what is happening with Grails now and in the future with the Grails Issue Tracker and on the Roadmap. Or even better checkout the latest commits! Contribute your own Custom Tags that could eventually be included in Grails core! Post some ideas for new Grails features in the development Sandbox. This is the area we where play around with ideas before they are promoted into JIRA issues. Add one of the Grails buttons on the left to your site or blog to help spread the word about Grails Contribute yourself by becoming part of the Grails Team !

Document generated by Confluence on Jan 31, 2007 10:29

Page 9

ContributeThis page last changed on Feb 24, 2006 by [email protected].

How to ContributeWe're always on the lookout for people who can contribute to Grails so if you have new ideas, patches to submit, code to contribute anything let us know via the Mailing lists or contact Graeme the Grails project lead.

Document generated by Confluence on Jan 31, 2007 10:29

Page 10

Developer BlogsThis page last changed on Jan 28, 2007 by [email protected].

Developer BlogsMany of the Grails developers are active bloggers, see below for a list of developers and their blogs: Graeme's Blog Guillaume's Blog Dierk's WebTest Blog and Groovy in Action Blog Steven Devijver's Blog Marc Palmer's Blog Jeff Brown's Blog Jason Rudolph's Blog

Document generated by Confluence on Jan 31, 2007 10:29

Page 11

Mailing listsThis page last changed on Dec 20, 2006 by [email protected].

Here are the mailing lists that have been established for this project. For each list, there is a subscribe, unsubscribe, and an archive link. If you have trouble subscribing via email you can go to http://xircles.codehaus.org/manage_email and register an e-mail to subscribe. NOTE: If you are using gmail to subscribe and you are using an alternate "send mail as" address, it will not work. Use your actual gmail address to subscribe, and make sure you send messages from your gmail account when you send messages to the list. Once you've done that you can then choose which mailing lists you want to subscribe to on the Grails project page: http://xircles.codehaus.org/projects/grails List name Grails developer list Grails user list Grails SCM and JIRA list Grails JIRA Activity German Grails list Subscribe subscribe subscribe subscribe RSS Yahoo Unsubscribe unsubscribe unsubscribe unsubscribe Archive

http://www.nabble.com/grails---dev-f1

http://www.nabble.com/grails---user-f

http://archive.grails.codehaus.org/scm

Document generated by Confluence on Jan 31, 2007 10:29

Page 12

User GroupsThis page last changed on Jun 05, 2006 by mittie.

The first user group so far The London Groovy and Grails User Group

Document generated by Confluence on Jan 31, 2007 10:29

Page 13

Who we areThis page last changed on Jan 27, 2007 by marceloverdijk.

Meet the team!Grails was started by a small group of keen followers of the Groovy language and inspired by the "code by convention" paradigm of frameworks like Ruby on Rails. The project was initiated by Guillaume LaForge and founded by Steven Devijver and Graeme Rocher ([email protected]) - who is the current Project Lead. Below the current active members on the project and their roles: Name Graeme Rocher Role Project Lead/Committer Bio Photo Moment!

As well as being project lead of Grails, Graeme is CTO at a company called SkillsMatter where he provides strategic direction, training and mentoring on Skills Matters array of Open Source and Technology based courseware. Graeme is the co-founder and current project lead on Grails. Blog at http://graemerocher.blogspot.com . Marc is a freelance Java/Web contractor who is sick of forever creating yet another web framework and is overjoyed that Grails has arrived. He is slowly getting more into the code base and committing more features. He's also a JIRA obsessive and loves having a well defined release roadmap. Blog at http://www.anyware.co.uk

Marc Palmer

Committer

Document generated by Confluence on Jan 31, 2007 10:29

Page 14

Dierk Koenig

Committer

Dierk focusses on the functional testing aspect of Grails and provided provided the open-source Canoo WebTest integration. Dierk works for Canoo Engineering in Basel, Switzerland. He is lead author of

Groovy in Action. Steven Devijver Committer Steven co-founded Grails together with Graeme, Guillaume Laforge and Dierk. Blog. Sven is responsible for the Grails Podcast and Grails Screencasts and is an active Grails evangelist. He is working at Actionality and his responsibilities include the evolution of their web platforms as well as J2ME development for their mobile advertisement solutions. Check out his blog at svenhaiges.de for further information. Jason has written a number of articles about Grails and committed a handful of patches. Jason is an Application Architect at Railinc, where he develops software that helps trains move more efficiently throughout North America. Jason's interests include

Sven Haiges

Evangelist / Patcher

Jason Rudolph

Committer / Evangelist

Document generated by Confluence on Jan 31, 2007 10:29

Page 15

dynamic languages, lightweight development methodologies, improving developer productivity, and a quest to keep programming fun. It's these interests that led Jason to become a Grails committer and evangelist. You can find Jason online at http://jasonrudolph.com. Jeff Brown Committer Jeff Brown is a Principal Software Engineer with Object Computing Inc. based in St. Louis, Missouri. OCI is a software engineering company founded upon the principles of Object Oriented Technology to produce quality software. OCI is the largest Java training company in the mid-west and the largest CORBA training company in the United States. OCI is a leading provider of open source services to organizations building mission critical infrastructure systems. For over 10 years Jeff has been involved in designing and building object oriented systems. Jeff currently teaches a number of Java and object oriented training courses in addition to doing consulting and mentoring work for industries including Aerospace, Financial and Medical. Areas of expertise include Java, agile web development with Groovy and Grails, distributed computing, object database

Document generated by Confluence on Jan 31, 2007 10:29

Page 16

systems, object oriented analysis and design and agile development. Jeff became a Grails committer in 2006 and will continue to be an active contributor. Blog at javajeff.blogspot.com. Marcel Overdijk Committer Marcel is a Technical Consultant at Valid ICT based in The Netherlands. From origin he is an Oracle developer building client/server database applications using Oracle's productive 4GL tooling. After 5 years as Oracle developer he needed a new challenge and as a result he switched to Java at the end of 2003. Since then he is always looking for a highly productive, standards-based and industry accepted development framework for designing and building database applications. With Grails, he thinks a true candidate has arrived. Blog at http://marceloverdijk.blogspot.com.

Document generated by Confluence on Jan 31, 2007 10:29

Page 17

Developer DocumentationThis page last changed on Dec 28, 2006 by mpancotti.

Developer DocumentationThese pages are designed to help new committers on the Grails project get up to speed on the various parts of Grails and how they function: General Architecture Runtime Configuration Dynamic Method Injection Compile Time Injection Spring MVC Integration Hibernate Integration SiteMesh Integration Groovy Server Pages Tag Libraries Scaffolding Architecture Command Line UML class model (0.4)

Document generated by Confluence on Jan 31, 2007 10:29

Page 18

Compile Time InjectionThis page last changed on Jul 20, 2006 by wangjammer5.

Compile Time InjectionGrails contains an architecture to implement compile time injection of properties, methods etc. This is built on functionality provided by the GroovyClassLoader and is important when used in conjunction with Java libraries because they are not aware of the Groovy runtime environment and hence dynamic property injection does not work. The core classes for compile time injection are found in the org.codehaus.groovy.grails.injection package. As of this writing only injection of properties into domain classes is supported (sorry if this is out-of-date when you read it). To do this create a class that implements the org.codehaus.groovy.grails.injection.GrailsDomainClassInjector and add it as a bean definition to the applicationContext.xml file. The org.codehaus.groovy.grails.injection.GrailsInjectionOperation class will automatically look up implementors of the GrailsDomainClassInjector interface and execute them at which point you have the oppurtunity to add new properties before compilation occurs. Remember to check if they already exist otherwise you will get weird ClassFormatError errors. An example of injecting a property called id can be seen below:

import import import import

org.codehaus.groovy.grails.injection.*; org.codehaus.groovy.ast.ClassNode; org.codehaus.groovy.classgen.GeneratorContext; org.codehaus.groovy.control.SourceUnit;

public class ExampleDomainClassInjector implements GrailsDomainClassInjector { public void performInjection(SourceUnit source, GeneratorContext context, ClassNode classNode) { if(classNode.getGetterMethod("getId") != null) { classNode.addProperty("id", ClassNode.ACC_PUBLIC, ClassHelper.long_TYPE,null,null,null); } } }

Document generated by Confluence on Jan 31, 2007 10:29

Page 19

Developer - Dynamic Method InjectionThis page last changed on Jul 26, 2006 by [email protected].

Dynamic Method InjectionThe core classes that make up the Grails dynamic method injection architecture are found in the org.codhaus.groovy.grails.commons.metaclass package. The org.codhaus.groovy.grails.commons.metaclass.ProxyMetaClass class extends the Groovy MetaClass to allow constructor, method and property interceptors to be set on the MetaClass which "intercept" calls. A Groovy MetaClass is what Groovy uses to dispatch method, constructor and property calls to objects with. These could be real methods or dynamically injected methods. Grails' ProxyMetaClass allows you to intercept calls to methods that may be real or not and choose whether to invoke the target "real" method at runtime. ProxyMetaClass tends to be used with instances and the setMetaClass method of GroovyObject as opposed to being registered within the MetaClassRegistry:

GroovyObject go = ..// some object ProxyMetaClass pmc = ProxyMetaClass.getInstance(go.getClass()); go.setMetaClass(pmc)

Once you have a ProxyMetaClass instance registered as the objects MetaClass you can then set an interceptor on the ProxyMetaClass to handle the interception. There are three interfaces for this: Interceptor - For intercepting method calls PropertyAccessInterceptor - For intercepting property getters/setters ConstructorInterceptor - For intercepting constructors Fortunately, Grails provides an abstract implementation of these that makes life easier called AbstractDynamicMethodsInterceptor. This abstract class implements the DynamicMethods interface that allows you to add dynamic methods, contructors and properties as objects. For example the following code will register an anonymous AbstractDynamicMethodsInterceptor as the interceptor:

DynamicMethods dm = new AbstractDynamicMethodsInterceptor(){}; pmc.setInterceptor(dm);

You can then add dynamic methods, constructors and properties to the interceptor which implement either the DynamicMethodInvocation, DynamicConstructor or DynamicProperty interfaces. Fortunately there are abstract implementations of these all:

dm.addDynamicMethodInvocation( new AbstractDynamicMethodInvocation("hello") { public Object invoke(Object target, Object[] arguments) { System.out.println("world!"); } });

Once the above has been added to my previously defined "go" object invoking the method from groovy will print "world!" to standard out:

Document generated by Confluence on Jan 31, 2007 10:29

Page 20

go.hello() // prints "world!"

This mechanism is uses in several places including for controller and tag lib in the classes: ControllerDynamicMethods TagLibDynamicMethods To make this even easier Grails provides a class called GroovyDynamicMethodsInterceptor which takes a GroovyObject in the constructor, registers a ProxyMetaClass on it and sets itself as the interceptor allowing you to shorten the above code example to:

GroovyObject go = //.. created from somewhere GroovyDynamicMethodsInterceptor i = new GroovyDynamicMethodsInterceptor(go); i.addDynamicMethodInvocation( new AbstractDynamicMethodInvocation("hello") { public Object invoke(Object target, Object[] arguments) { System.out.println("world!"); } });

The proxy/interception mechanism is best used on instances of GroovyObject, but Grails provides another MetaClass called DelegatingMetaClass which takes an instance of the DynamicMethods interface in its constructor and delegates to it hence not requiring any interceptors to be set on it. Essentially it attempts to call a dynamic method first and if it fails falls back to trying to invoke a real method. This MetaClass is used by domain classes in conjunction with the DomainClassMethods class which is an instance of DynamicMethods.

Document generated by Confluence on Jan 31, 2007 10:29

Page 21

Developer - Groovy Server PagesThis page last changed on Jul 20, 2006 by [email protected].

Groovy Server PagesThe GSP implementation in Grails was forked from the original GSP, but has been heavily refactored and is now based around the TemplateEngine pattern found in the rest of Groovy. The core classes for GSP can be found in the org.codehaus.groovy.grails.web.pages package. There is a servlet that maps to *.gsp that handles all GSP request called GroovyPagesServlet. This class uses the GroovyPagesTemplateEngine class to process a GSP request. As mentioned the API for the GroovyPagesTemplateEngine is very similar to the other TemplateEngine's in Groovy, making GSP into a re-usable component. General API usage is as follows:

groovy.text.Template t = engine.createTemplate(context,request,response); if(t != null) { groovy.lang.Writable w = t.make(); Writer out = ..// get writer from somewhere w.writeTo(out); }

Thanks to the refactoring into a TemplateEngine the GroovyPagesTemplateEngine is re-used in several places including in the GSP servlet, in tags libraries and in the render method of controllers. The Parse, Reverse, Scan, Strip and Tokens classes in the org.codehaus.groovy.grails.web.pages are used to convert a GSP into a Groovy class that extends the GroovyPage class which in turn extends groovy.lang.Script.

Document generated by Confluence on Jan 31, 2007 10:29

Page 22

Developer - Hibernate IntegrationThis page last changed on Jul 20, 2006 by [email protected].

Hibernate IntegrationConfigurationGrails uses Hibernate for ORM, but implements it's own configuration strategy for Hibernate to use convention to perform ORM mapping. The result is GORM. The core Hibernate integration classes can be found within the org.codehaus.groovy.grails.orm.hibernate directory. Within this package resides a Spring factory bean called ConfigurableLocalSessionFactoryBean that extends the Spring factory bean for creating Hibernate session factories allowing a custom hibernate Configuration class to be set. Grails then provides its own configuration class within the org.codehaus.groovy.grails.orm.hibernate.cfg package called DefaultGrailsDomainConfiguration this class extends the Hibernate Configuration the implication of which means it will still read in a regular hibernate.cfg.xml file if you want to use Hibernate XML mapping instead. Grails provides a second Configuration class called GrailsAnnotationConfiguration that extends the Hibernate AnnotationConfiguration class to allow EJB3 annotation mapping in Grails. Both configuration classes delegate to a class called org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsDomainBinder that performs the object relational mapping. It "binds" the Grails domain class conventions to the Hibernate meta model.

Persistence MethodsThe dynamic methods that magically appear on domain classes such as "save" and "delete" can be found in the package org.codehaus.groovy.grails.orm.hibernate.metaclass . They use the architecture described in the section on Dynamic Method Injection. The class which these methods are added to is called org.codehaus.groovy.grails.metaclass.DomainClassMethods so essentially adding a new method to a domain class would involve creating a new one in the aformentioned package and adding a line such as:

addDynamicMethodInvocation(new MyBrandNewMethod(sessionFactory, classLoader,application));

Or for static methods:

addStaticMethodInvocation(new MyNewStaticMethod(sessionFactory, classLoader));

Document generated by Confluence on Jan 31, 2007 10:29

Page 23

Developer - Spring MVC IntegrationThis page last changed on Jul 20, 2006 by [email protected].

Spring MVC IntegrationGrails uses Spring MVC as the underlying web application framework. Spring MVC might not be the simplist framework to use but it is most definitely one of the most extensible making it perfect for Grails. The Grails servlet extends Spring's DispatcherServlet to bootstrap the Grails environment, there is then a single Spring MVC controller called org.codehaus.groovy.grails.web.servlet.mvc.SimpleGrailsController that handles all Grails controller requests. The SimpleGrailsController delegates to a class called org.codehaus.groovy.grails.web.servlet.mvc.SimpleGrailsControllerHelper that actually handles the request. This class breaks the handling of the request down into a number of steps. The entry point for the class is the handleUri method which: 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. Parses the URI into its components (controller name, action name, id etc.) Looks up a GrailsControllerClass instance for the URI Creates a new Grails controller instance Configures the controller instance's dynamic methods and properties Retrieves a scaffolder if is scaffolding is enabled for the controller Gets a reference to the closure action to execute for the URI Increments flash scope moving it on to its next state Gets the view name for the URI Executes any before inteceptors registered Executes the closure that is the controller action if the before interceptor didn't return false Creates a Spring MVC ModelAndView instance from the view name and the model returned by the closure action 12. Executes any after interceptors registered passing returned model 13. Returns the Spring MVC ModelAndView instance

Document generated by Confluence on Jan 31, 2007 10:29

Page 24

General ArchitectureThis page last changed on Aug 08, 2006 by mercnboy3.

General ArchitectureThe commons packageThe core Grails classes that make up the foundation of Grails can be found in the org.codehaus.groovy.grails.commons package. The classes within this package deal with the conventions and most implement the interface org.codehaus.groovy.grails.commons.GrailsClass which defines methods for retrieving various representations of the class name based on the convention. The classes themselves are loaded into an instance of org.codehaus.groovy.grails.commons.GrailsApplication the default implementation for which can be found here. The DefaultGrailsApplication class defines two constructors one which takes an array of Spring resources. The resources are a set of the set of .groovy files that resides within the grails-app directory and are loaded by the Spring applicationContext.xml file found in the WEB-INF directory. The DefaultGrailsApplication class also defines a constructor that takes an array of classes which is mainly used in test cases for example:

GroovyClassLoader gcl = new GroovyClassLoader(); Class domainClass = gcl.parseClass("class Test { Long id; Long version; }" ); Class controller = gcl.parseClass("class TestController { def list = {} }"); GrailsApplication app = new DefaultGrailsApplication( new Class[] { domainClass, controller } );

The above code creates an GrailsApplication instance with a domain class called Test and a controller called TestController. The domain class is encapsulated by an instance of org.codehaus.groovy.grails.commons.GrailsDomainClass and the controller by an instance of org.codehaus.groovy.grails.commons.GrailsControllerClass

Utility Classes for the commons packageThere are a number of utility classes for working with the commons package. The class org.codehaus.groovy.grails.commons.GrailsClassUtils provides methods for evaluating the conventions of classes and retrieving different naming representations. org.codehaus.groovy.grails.commons.GrailsResourceUtils provides methods for working with Grails resources before they are loaded into classes (ie the .groovy files themselves and where they reside in the app structure). The org.codehaus.groovy.grails.commons.GrailsResourceLoader class is an instance of groovy.lang.ResourceLoader. This class is set on the GroovyClassLoader instance and ensures that

Document generated by Confluence on Jan 31, 2007 10:29

Page 25

classes can be loaded from Spring Resource instances.

Document generated by Confluence on Jan 31, 2007 10:29

Page 26

Runtime ConfigurationThis page last changed on Jul 23, 2006 by [email protected].

Runtime ConfigurationGrails automatically configures itself at runtime using the conventions within the classes and Spring. The class that performs the runtime configuration is called org.codehaus.groovy.grails.commons.spring.GrailsRuntimeConfigurator which takes a GrailsApplication and produces a bunch of bean references which can be used to create a Spring application context. The GrailsRuntimeConfigurator class does many things including, but not limited to: Configuring the data source Setting up the Hibernate session factory Creating the handler mappings for the Spring MVC servlet Setting up any Quartz scheduled tasks Configuring Grails service classes for transaction demarcation

An example of its usage can be seen in the grails.util.GrailsUtil class which is used when running unit tests and scaffolding. It essentially bootstraps the Grails environment using the GrailsRuntimeConfigurator class and an applicationContext.xml on the classpath:

ApplicationContext parent = new ClassPathXmlApplicationContext("applicationContext.xml"); DefaultGrailsApplication application = (DefaultGrailsApplication)parent.getBean("grailsApplication", DefaultGrailsApplication.class); GrailsRuntimeConfigurator config = new GrailsRuntimeConfigurator(application,parent); ApplicationContext appCtx = config.configure(new MockServletContext());

When a Grails web application is executed this configuration takes place in the org.codehaus.groovy.grails.web.servlet.GrailsDispatcherServlet class which is a class that extends Spring MVC's DispatcherServlet to bootstrap the Grails environment

Document generated by Confluence on Jan 31, 2007 10:29

Page 27

DocumentationThis page last changed on Nov 08, 2006 by kgkiran.

DocumentationBelow is a list of documentation currently available for Grails: 1. 2. 3. 4. 5. 6. Installation - General installation notes Quick Start - Help to get up and running quickly User Guide - Comprehensive user guide Reference - Method, tag and builder references for more detailed API info Tutorials - Loads of info here including screencasts, podcasts, tutorials, articles and more!! Tips n Tricks- Little nice to know things

Document generated by Confluence on Jan 31, 2007 10:29

Page 28

Quick StartThis page last changed on Dec 08, 2006 by takamori.

Quick StartThe following makes it simple to start a grails project. There's also a screencast that follows these steps for creating a small app.

Create a Grails projectOnce you have installed Grails you can use the built-in target for creating new projects:

grails create-app

The target will prompt you for the name of your project and create the project structure below:

%PROJECT_HOME% + grails-app + conf + controllers + domain + i18n + services + taglib + views + layouts + lib + spring + hibernate + war + WEB-INF

---> ---> ---> ---> ---> ---> --->

location of configuration artifacts like data sources location of controller artifacts location of domain classes location of message bundles for i18n location of services location of tag libraries location of views ---> location of layouts

---> optional spring config ---> optional hibernate config

Configure a Data Source (Optional)The "create-app" target created several Grails data source artifacts for you in the "/grails-app/conf" directory, one for each of the standard environments: DevelopmentDataSource, TestDataSource, and ProductionDataSource. All the examples that follow operate on the development environment. For more information on environments see Configuration#environments. By default, each data source is configured with an in-memory HSQLDB database (great for testing, but probably not that useful for live deployment) so this step is optional:

class DevelopmentDataSource { boolean pooling = true String dbCreate = "create-drop" // one of 'create', 'create-drop','update' String url = "jdbc:hsqldb:mem:testDB" String driverClassName = "org.hsqldb.jdbcDriver" String username = "sa" String password = ""

Document generated by Confluence on Jan 31, 2007 10:29

Page 29

}

Configuring the data source is a simple matter of changing the values for the desired database and driver and placing the driver jar file in the /lib directory

Create a Domain ClassMake sure you are in the root directory of your project (for argument sake "my-project) by typing

cd my-project grails create-domain-class

The target will prompt you for the name of your domain class. A domain class is a persistent artifact and all properties are by default persisted to the database (Go the the section on GORM (Grails Object Relational Mapping) for more info):

class Book { String title String author }

At this point you may want to create some test data. An easy way to do this is to build and save the domain objects in the "init" closure of the Grails application bootstrap class found in "/grails-app/conf/ApplicationBootStrap.groovy":

class ApplicationBootStrap { def init = { servletContext -> // Create some test data new Book(author:"Stephen King",title:"The Shining").save() new Book(author:"James Patterson",title:"Along Came a Spider").save() } def destroy = { } }

(Note that you can build and save domain objects here the same as in controllers or other parts of Grails applications; see Grails Object Relational Mapping (GORM) for more on domain objects.)

Create a controllerControllers are central to Grails applications they handle web requests and URLs of the request map to a controller class and a closure within the class. Run the "grails generate-all" target and type in the name of the controller. In our example we type "book" which generates a controller called grails-app/controllers/BookController.groovy. Open up this controller and change it as follows to use dynamic Scaffolding which dynamically generates your application at runtime:

Document generated by Confluence on Jan 31, 2007 10:29

Page 30

class BookController { def scaffold = Book }

Make sure that you typed "Book" with a capital B. Alternatively, you could also have left the generated controller alone, instead of replacing it with the default scaffolding. It might be worth learning from.

Start GrailsTo start your Grails app run the following target

grails run-app

This will startup in instance of the Jetty servlet engine running on port 8080. In order to start in on a different port like e.g. 9090 use grails -Dserver.port=9090 run-app. To access the list of books open up a browser and type:

http://localhost:8080/my-project/book/list

Or, as the "list" closure is the default action for the BookController you can type:

http://localhost:8080/my-project/book

Document generated by Confluence on Jan 31, 2007 10:29

Page 31

ReferenceThis page last changed on Feb 27, 2006 by [email protected].

Reference Guide1. 2. 3. 4. 5. Command Line Dynamic Methods & Properties Tag Library Validation Builders

Document generated by Confluence on Jan 31, 2007 10:29

Page 32

Builders ReferenceThis page last changed on Nov 24, 2006 by [email protected].

Grails Builders.

Introduction

Grails uses many Groovy builders to provide mini-DSL like constructs for an array of different things. This page details the builders with in Grails and provides a reference to the syntax. Hibernate Criteria Builder Domain Class Constraints Builder Spring Bean Builder

Document generated by Confluence on Jan 31, 2007 10:29

Page 33

Hibernate Criteria BuilderThis page last changed on Nov 24, 2006 by [email protected].

Hibernate Criteria BuilderDescriptionA builder for creating criteria-based queries analogous to those found in the Hibernate Criteria API, the nodes on this builder map the the static methods found in the Restrictions class of the Hibernate Criteria API. Example Usage:

def c = Account.createCriteria() def results = c { like("holderFirstName", "Fred%") and { between("balance", 500, 1000) eq("branch", "London") } maxResults(10) order("holderLastName", "desc") }

Setting properties in the Criteria instanceIf a node within the builder tree doesn't match a particular criterion it will attempt to set a property on the Criteria object itself. Thus allowing full access to all the properties in this class. The below example calls "setMaxResults" and "setFirstResult" on the Criteria instance:

import org.hibernate.FetchMode as FM .... def results = c.list { maxResults(10) firstResult(50) fetchMode("aRelationship", FM.EAGER) }

If you invoke the builder with no method name such as:

c { ... }

It defaults to the 'list' call, if this is not desired use the specific methods 'list','get' and 'scroll' which return a list, a unique result and a scrollable result set respectively.

Querying AssociationsAssociations can be queried by having a node that matches the property name. For example say the Account class had many Transaction objects:

Document generated by Confluence on Jan 31, 2007 10:29

Page 34

class Account { ... def relatesToMany = [transactions:Transaction] Set transactions ... }

We can query this association by using the property name "transaction" as a builder node:

def c = Account.createCriteria() def now = new Date() def results = c.list { transactions { between('date',now-10, now) } }

The above code will find all the accounts that have performed transactions within the last 10 days. You can also nest such association queries within logical blocks:

def c = Account.createCriteria() def now = new Date() def results = c.list { or { between('created',now-10,now) transactions { between('date',now-10, now) } } }

Here we find all accounts that have either performed transactions in the last 10 days OR have been recently created in the last 10 days.

Querying with ProjectionsProjections to be used to customise the results. To use projections you need to define a "projections" node within the criteria builder tree. There are equivalent methods within the projections node to the methods found in the Hibernate Projections class:

def c = Account.createCriteria() def numberOfBranches = c.get { projections { countDistinct('branch') } }

Using Scrollable ResultsYou can use Hibernate's ScrollableResults feature by calling the scroll method:

Document generated by Confluence on Jan 31, 2007 10:29

Page 35

def results = crit.scroll { maxResults(10) } def f = results.first() def l = results.last() def n = results.next() def p = results.previous() def future = results.scroll(10) def accountNumber = results.getLong('number')

To quote the documentation of Hibernate ScrollableResults:

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. Contrary to JDBC, columns of results are numbered from zero.

Node ReferenceNode and Description Logical AND operatorand { between("balance", 500, 1000) eq("branch", "London") }

Example

between

Where the property value is between to distinct values

between("balance", 500, 1000)

eq

Where a property equals a particular value Where one property must equal another Where a property is greater than a particular value Where a one property must be greater than another Where a property is greater than or equal to a particular value Where a one property must be greater than or equal to another

eq("branch", "London")

eqProperty

eqProperty("lastTransaction","firstTransa

gt

gt("balance",1000)

gtProperty

gtProperty("balance","overdraft")

ge

ge("balance",1000)

geProperty

geProperty("balance","overdraft")

Document generated by Confluence on Jan 31, 2007 10:29

Page 36

idEq

Where an objects id equals the specified value A case sensitive 'like' expression

idEq(1)

ilike

ilike("holderFirstName","Steph%")

in

Where a one property is contained within the specified list of values Where a collection property is empty Where a collection property is not empty Where a property is null

in("holderAge",[18..65])

isEmpty

isEmpty("transactions")

isNotEmpty

isNotEmpty("transactions")

isNull

isNull("holderGender")

isNotNull

Where a property is not nullisNotNull("holderGender")

lt

Where a property is less than a particular value Where a one property must be less than another Where a property is less than or equal to a particular value Where a one property must be less than or equal to another Equivalent to SQL like expression

lt("balance",1000)

ltProperty

ltProperty("balance","overdraft")

le

le("balance",1000)

leProperty

leProperty("balance","overdraft")

like

like("holderFirstName","Steph%")

ne

Where a property does not equals a particular value Where one property does not equal another Negates an expression, logical NOT

ne("branch", "London")

neProperty

neProperty("lastTransaction","firstTransa

not

not { between("balance", 500, 1000) }

Document generated by Confluence on Jan 31, 2007 10:29

Page 37

or

Logical OR operatoror { between("balance", 500, 1000) eq("branch", "London") }

order

Order the results by a particular property

order("holderLastName", "desc")

sizeEq

Where a collection property's size equals a particular value

sizeEq("transactions", 10)

Document generated by Confluence on Jan 31, 2007 10:29

Page 38

Spring Bean BuilderThis page last changed on Dec 01, 2006 by [email protected].

The Spring Bean Builder (Since 0.4)Motivation

Spring is very powerful, but the XML based syntax is very verbose and violates DRY at multiple levels even with the recent additions to Spring 2.0. This Bean builder in Grails aims to provide a simplified way of wiring together dependencies that uses Spring at its core. In addition, Spring's regular way of configuration (via XML) is essentially static and very difficult to modify and configure at runtime other than programmatic XML creation which is both error prone and verbose. Grails' BeanBuilder changes all that by making it possibly to programmatically wire together components at runtime thus allowing you to adapt the logic based on system properties or environment variables. This enables the code to adapt to its environment and avoids unnecessary duplication of code (having different Spring configs for test, development and production environments)

The BeanBuilder class

Grails provides a grails.spring.BeanBuilder class that uses dynamic Groovy to construct bean definitions. The basics are as follows:

import org.apache.commons.dbcp.BasicDataSource import org.codehaus.groovy.grails.orm.hibernate.ConfigurableLocalSessionFactoryBean; import org.springframework.context.ApplicationContext; def bb = new grails.spring.BeanBuilder() bb.beans { dataSource(BasicDataSource) { driverClassName = "org.hsqldb.jdbcDriver" url = "jdbc:hsqldb:mem:grailsDB" username = "sa" password = "" } sessionFactory(ConfigurableLocalSessionFactoryBean) { dataSource = dataSource hibernateProperties = [ "hibernate.hbm2ddl.auto":"create-drop", "hibernate.show_sql":true ] } } ApplicationContext appContext = bb.createApplicationContext()

The above example shows how you would configure Hibernate with an appropriate data source with the BeanBuilder class. Basically what is happening here is the name of each method call (in this case "dataSource" and

Document generated by Confluence on Jan 31, 2007 10:29

Page 39

"sessionFactory" maps to the name of the bean in Spring. The first argument to the method is the beans class, whilst the last argument is a closure. Within the body of the closure you can set properties on the bean using standard Groovy syntax Bean references are resolved automatically be using the name of the bean. This can be seen in the example above with the way the sessionFactory bean resolves the dataSource reference.

Using Constructor arguments

Constructor arguments can be defined using parameters to each method that reside between the class of the bean and the last closure:

bb.beans { exampleBean(MyExampleBean, "firstArgument", 2) { someProperty = [1,2,3] } }

Configuring the BeanDefinition (Using factory methods)

The first argument to the closure is a reference to the bean configuration instance, which you can use to configure factory methods and invoke any method on the AbstractBeanDefinition class:

bb.beans { exampleBean(MyExampleBean) { bean -> bean.factoryMethod = "getInstance" bean.singleton = false someProperty = [1,2,3] } }

As an alternative you can also use the return value of the bean defining method to configure the bean:

bb.beans { def example = exampleBean(MyExampleBean) { someProperty = [1,2,3] } example.factoryMethod = "getInstance" }

Using Factory beans

Spring defines the concept of factory beans and often a bean is created not from a class, but from one of these factories. In this case the bean has no class and instead you must pass the name of the factory bean to the bean:

bb.beans { myFactory(ExampleBeanFactory) { someProperty = [1,2,3] } myBean(myFactory) {

Document generated by Confluence on Jan 31, 2007 10:29

Page 40

name = "blah" } }

Note in the example above instead of a class we pass a reference to the myFactory bean into the bean defining method. Another common task is provide the name of the factory method to call on the bean factory. This can be done using Groovy's named parameter syntax:

bb.beans { myFactory(ExampleBeanFactory) { someProperty = [1,2,3] } myBean(myFactory:"getInstance") { name = "blah" } }

Here the getInstance method on the ExampleBeanFactory bean will be called in order to create the myBean bean.

Creating bean references at runtime

Sometimes you don't know the name of the bean to be created until runtime. In this case you can use a GString to invoke a bean defining method dynamically:

def beanName = "example" bb.beans { "${beanName}Bean"(MyExampleBean) { someProperty = [1,2,3] } }

In this case the beanName variable defined earlier is used when invoking a bean defining method.

Referencing beans dynamically and from a Parent ApplicationContext

Furthermore, because sometimes bean names are not known until runtime you may need to reference them by name when wiring together other beans. In this case using the "ref" method:

def beanName = "example" bb.beans { "${beanName}Bean"(MyExampleBean) { someProperty = [1,2,3] } anotherBean(AnotherBean) { example = ref("${beanName}Bean") } }

Here the example property of AnotherBean is set using a runtime reference to the "exampleBean". The "ref" method can also be used to refer to beans from a parent ApplicationContext that is provided in the constructor of the BeanBuilder:

Document generated by Confluence on Jan 31, 2007 10:29

Page 41

ApplicationContext parent = ...// der bb = new BeanBuilder(parent) bb.beans { anotherBean(AnotherBean) { example = ref("${beanName}Bean", true) } }

Here the second parameter "true" specifies that the reference will look for the bean in the parent context.

Using anonymous (inner) beans

You can use anonymous inner beans by setting a property of the bean to a closure that takes an argument that is the bean type:

bb.beans { marge(Person.class) { name = "marge" husband = { Person p -> name = "homer" age = 45 props = [overweight:true, height:"1.8m"] } children = [bart, lisa] } bart(Person) { name = "Bart" age = 11 } lisa(Person) { name = "Lisa" age = 9 } }

In the above example we set the "marge" bean's husband property to a closure that creates an inner bean reference. Alternatively if you have a factory bean you can ommit the type and just use passed bean definition instead to setup the factory:

bb.beans { personFactory(PersonFactory.class) marge(Person.class) { name = "marge" husband = { bean -> bean.factoryBean = "personFactory" bean.factoryMethod = "newInstance" name = "homer" age = 45 props = [overweight:true, height:"1.8m"] } children = [bart, lisa] } }

Adding variables to the Binding (context)

TODO

Loading Bean definitions from the file system

Document generated by Confluence on Jan 31, 2007 10:29

Page 42

You can use the BeanBuilder class to load external Groovy scripts that define beans using the same path matching syntax defined here. Example:

def bb = new BeanBuilder("classpath:*SpringBeans.groovy") def applicationContext = bb.createApplicationContext()

Here the BeanBuilder will load all Groovy files on the classpath ending with SpringBeans.groovy and parse them into bean definitions. An example script can be seen below:

beans = { dataSource(BasicDataSource) { driverClassName = "org.hsqldb.jdbcDriver" url = "jdbc:hsqldb:mem:grailsDB" username = "sa" password = "" } sessionFactory(ConfigurableLocalSessionFactoryBean) { dataSource = dataSource hibernateProperties = [ "hibernate.hbm2ddl.auto":"create-drop", "hibernate.show_sql":true ] } }

Document generated by Confluence on Jan 31, 2007 10:29

Page 43

Command LineThis page last changed on Jan 24, 2007 by marceloverdijk.

Command Line ReferenceUsage: For Grails 0.3 and earlier - grails [options] (target name) For Grails 0.4 and later - grails [options] (target name) (target parameters) Target bug-report clean Description (since 0.4) Generates a ZIP containing your source artifacts for attaching to a JIRA issue Cleans the current app 'tmp' directory, can be combined with other commands eg. grails clean run-app Creates a new Grails application Convenience target for creating a controller Convenience target for creating domain classes Convenience target for creating data sources Convenience target for creating jobs Convenience target for creating services Convenience target for creating tag libraries Convenience target for creating test suites Convenience target for creating functional web tests Generates a controller for a specified domain class Generates CRUD views for a specified domain class Generates both a controller and the views for a specified domain class (since 0.4) Installs the artifact and scaffolding templates Runs a grails app using the default Jetty container Runs the functional web tests contained within the app Runs the unit tests contained within the app Creates a JEE Web Application Archive (WAR) file from the current grails app

create-app create-controller create-domain-class create-data-source create-job create-service create-taglib create-test-suite create-webtest generate-controller generate-views generate-all install-templates run-app run-webtest test-app war

Document generated by Confluence on Jan 31, 2007 10:29

Page 44

Options can be given in the format -Dname=value name server.port value the port number to start the server on, default:8080

See also: Command Line Tools

Document generated by Confluence on Jan 31, 2007 10:29

Page 45

Dynamic Methods ReferenceThis page last changed on Jan 23, 2007 by wangjammer5.

Dynamic Methods ReferenceGrails uses special features of Groovy to provide dynamic methods and properties that are accessible from your classes without you defining them or inheriting from a base class. This is extremely convenient and contributes to having far less "code noise" in your applications. The dynamic features available vary depending on the type of class you are calling from.

ControllersProperties actionUri controllerUri actionName controllerName flash grailsApplication grailsAttributes log 0.3 params session request response servletContext

Methods bindData chain render redirect getViewUri getTemplateUri

Domain ClassesProperties

Document generated by Confluence on Jan 31, 2007 10:29

Page 46

errors constraints properties

Methods add add* delete discard hasErrors ident merge refresh save validate

Static Methods count countBy* createCriteria executeQuery executeUpdate exists find findAll findBy* findAllBy* findWhere findAllWhere get list listOrderBy* withCriteria withTransaction

Document generated by Confluence on Jan 31, 2007 10:29

Page 47

Controller Dynamic MethodsThis page last changed on Jan 09, 2007 by mfoldbjerg.

Controller Dynamic Methods & PropertiesProperties

actionUri

Description

The relative Uri of the action

controllerUri

Description

The relative Uri of the controller

actionName

Description

The name of the current action

controllerName

Description

The name of the current controller

flash

Description

A map that allows temporary storage of objects for the next request and the next request only. The subequent request will clear the storage of any variables stored in the first request. This is a convenience map that allows you to store information temporarily, which is very convenient when using redirection or chaining.

Document generated by Confluence on Jan 31, 2007 10:29

Page 48

Example

flash['message'] = 'hello world!'

grailsApplication

Description

An instance of org.codehaus.groovy.grails.commons.GrailsApplication that provides information about the grails application

Example

return [controllers : grailsApplication.controllers]

grailsAttributes

Description

An instance of org.codehaus.groovy.grails.web.servlet.GrailsApplicationAttributes that provides convenience methods for the current grails request

Example

def templateUri = grailsAttributes.getTemplateUri("myTemplate",request)

log

Description

An instance of the Log4J logger for the controller. Grails creates a log per controller, which you can call on at any time to perform logging. When configuring Log4J using WEB-INF/log4j.properties you should use properties of the form: log4j.logger.TestController=debug, stdout Where "TestController" is the fully qualified class name of your controller class.

Example

You simply use the standard Log4J logging methods:

Document generated by Confluence on Jan 31, 2007 10:29

Page 49

log.trace('Doing something') log.debug('Debug info here') log.error('Something went wrong') log.error('Something went wrong', someException)

params

Description

A map of the available request parameters and/or controller parameters

Example

def a = Account.get( params["id"] )

request

Description

The HttpServletRequest instance for the request. Request attributes can be accessed with the Map syntax provided by groovy

Example

request['anAttribute'] request.getHeader("user-agent")

response

Description

The HttpServletResponse instance

Example

response.setHeader("myheader", "myvalue")

servletContext

Description

The ServletContext instance as per the servlet API

Document generated by Confluence on Jan 31, 2007 10:29

Page 50

Example

def myUrl = servletContext.getResource("/path/to/url")

session

Description

Provides access to a map of the HttpSession instance

Example

def loggedUser = session["loggedUser"]

Methods

bindData

Description

Binds data to a target instance performing type conversion if necessary. Useful for binding request parameters to properties of objects

Parameters

target - The target object to bind to params - The parameters to bind to the target object

Examples

bindData(target, this.params) // binds request parameters to a target object

chain

Description

Chains the model (The model is retained from one action to the next) from one action to the next allowing you to build up the model from an action chain.

Parameters

Document generated by Confluence on Jan 31, 2007 10:29

Page 51

uri - The full uri to redirect to (example /book/list, book/show/2) controller - The controller to redirect to, defaults to the current controller if not specified action - The action to redirect to, either a string name or a reference to an action within the current controller id - The id to use in redirection model (required) - The model to chain to the next action params (optional) - Parameters to pass to the action chained to.

Examples

chain(action:"details",model:[book:new Book(title:'The Shawshank Redemption')])

getViewUri

Description

Retrieves the relative uri of a named view within the Grails application. If the view contains a '/' at the start it will be resolved relative to the views folder as a shared view otherwise it will be relative to the current controller

Parameters

name (required) - The name of the view

Examples

assert getViewUri('myView') == /WEB-INF/grails-app/views/controllerName/myView.gsp assert getViewUri('/mySharedView') == /WEB-INF/grails-app/views/mySharedView.gsp

getTemplateUri

Description

Retrieves the relative uri of a named template within the Grails application. If the template contains a '/' at the start it will be resolved relative to the views folder as a shared template otherwise it will be relative to the current controller

Parameters

name (required) - The name of the template

Examples

Document generated by Confluence on Jan 31, 2007 10:29

Page 52

assert getTemplateUri('myTemplate') == /WEB-INF/grails-app/views/controllerName/_myTemplate.gsp assert getTemplateUri('/mySharedTemplate') == /WEB-INF/grails-app/views/_mySharedTemplate.gsp

redirect

Description

Redirects the current action to another action, optionally passing parameters and/or errors

Parameters

uri - The full uri to redirect to (example /book/list, book/show/2) controller - The controller to redirect to, defaults to the current controller if not specified action - The action to redirect to, either a string name or a reference to an action within the current controller id - The id to use in redirection params - Parameters to pass to the action redirected to.

Examples

redirect(uri:"book/list") redirect(action:"show") redirect(controller:"book",action:"list") redirect(action:"show",id:4, params:[author:"Stephen King"])

render

Description

A multi-purpose method for rendering responses to the client which is best illustrated with a few examples!

Parameters

text (optional) - The text to render builder (optional) - The builder to use when rendering markup view (optional) - The view to delegate the rendering to template (optional) - The template to render var (optional) - The name of the variable to be passed into a template, defaults to the groovy default argument 'it' if not specified bean (optional) - The beanto use in rendering model (optional) - The model to use in rendering collection (optional) - For rendering a template against each item in a collection contentType (optional) - The contentType of the response encoding (optional) - The encoding of the response

Document generated by Confluence on Jan 31, 2007 10:29

Page 53

Examples

// renders text to response render "some text" // renders text for a specified content-type/encoding render(text:"some xml",contentType:"text/xml",encoding:"UTF-8") // render a template to the response for the specified model render(template:"book",model:[book:new Book(title:'The Shining',author:'Stephen King')]) // render each item in the collection using the specified template render(template:"book",collection:[b1, b2, b3]) // render a template to the response for the specified bean render(template:"book",bean:new Book(title:'The Shining',author:'Stephen King')) // render the view with the specified model render(view:"viewName",model:[book:new Book(author:'Stephen King')]) // render the view with the controller as the model render(view:"viewName" ) // render some markup to the response render { div(id:"myDiv") { "some body text" } } // render some XML markup to the response render(contentType:"text/xml") { books { for(b in books) { book(title:b.title,author:b.author) } } } // render an OpenRico (http://www.openrico.org) response with the builder attribute: def b = new Book(title:"Kiss the Girls", author:"James Patterson") render(builder:"rico") { object(id:"bookUpdater") { book(title:b.title,author:b.author) } } // render a JSON ( http://www.json.org ) response with the builder attribute: render(builder:"json") { book(title:b.title,author:b.author) }

Document generated by Confluence on Jan 31, 2007 10:29

Page 54

DomainClass Dynamic MethodsThis page last changed on Jan 18, 2007 by brownj.

Domain Class Dynamic Methods & PropertiesProperties

errors

Description

A list of errors from the last call to the "validate" or "save" method

Example

def b = new Book(title:"The Shining") if(!b.validate()) { b.errors.each { println it } }

constraints

Description

A list of org.codehaus.groovy.grails.validation.ConstrainedProperty instances applied against the domain class by the constraints property (see Validation)

Example

def b = new Book(title:"The Shining") b.constraints.each { println it.name println it.maxLength }

properties

Description

Allows access to the domain class properties as a map and perform types conversion when set allowing properties to be set from request parameters for example.

Document generated by Confluence on Jan 31, 2007 10:29

Page 55

Example

def b = new Book(title:"The Shining") b.properties = this.params

Methods

add

Description

Adds a domain class relationship to a specific one-to-many or many-to-many relationship.

Parameters

to - specifies the hasMany relationship name to which the object is being added

Example

def a = new Author(name:"Stephen King") .add(to:"fiction", new Book(title:"IT")) .add(to:"non-fiction", new Book(title:"On Writing: A Memoir of the Craft")) .save()

add*

Description

Adds a domain class relationship for one-to-many or many-to-many relationship, where the relationship is indicated by the class used as the suffix to the method.

Example

def a = new Author(name:"Stephen King") .addBook(new Book(title:"IT")) .addBook(new Book(title:"The Stand")) .save()

delete

Description

Deletes a domain class instance from the database

Document generated by Confluence on Jan 31, 2007 10:29

Page 56

Example

def b = Book.get(1) b.delete()

discard

Description

Discards any changes that have been made during an update. Note that this method will not clean or reset the object with the original values it will just prevent it from being automatically saved by Grails.

Example

def b = Book.get(1) b.title = "Blah" b.discard() // changes won't be applied now

hasErrors

Description

True if the domain class instance has errors following a call to "validate" or "save"

Example

def b = new Book(title:"The Shining") b.validate() if(b.hasErrors()) { b.errors.each { println it } }

ident

Description

Returns the value of the identity property of the domain class regardless of the name of the identity property itself

Example

def b = new Book(title:"The Shining") b.save()

Document generated by Confluence on Jan 31, 2007 10:29

Page 57

println b.ident()

merge

Description

see Hibernate3's merge

refresh

Description

Refreshes a domain classes state from the database

Example

def b = Book.get(1) b.refresh()

save

Description

Saves a domain class instance to the database cascading updates to any child instances if required. Returns false if validation failed and the instance was not saved

Parameters

validate (optional) - Set to false if validation should be skipped

Example

def b = new Book(title:"The Shining") if( !b.save() ) { b.errors.each { println it } }

validate

Description

Document generated by Confluence on Jan 31, 2007 10:29

Page 58

Validates a domain class against the applied constraints (see Validation)

Example

def b = new Book(title:"The Shining") if( !b.validate() ) { b.errors.each { println it } }

Static Methods

count

Description

Counts the number of instances in the database and returns the result

Parameters

None

Example

def noOfBooks = Book.count()

countBy

Description

Dynamic method that uses the properties of the domain class to allow the creation of Grails query method expressions that count the number of records returned

Examples

class Book { Long id Long version String title Date releaseDate String author }

def c = Book.countByTitle("The Shining")

Document generated by Confluence on Jan 31, 2007 10:29

Page 59

c c c c c c c

= = = = = = =

Book.countByTitleAndAuthor("The Sum of All Fears", "Tom Clancy") Book.countByReleaseDateBetween(firstDate, new Date()) Book.countByReleaseDateGreaterThanOrEqual(firstDate) Book.countByTitleLike("%Hobbit%") Book.countByTitleNotEqual("Harry Potter") Book.countByReleaseDateIsNull() Book.countByReleaseDateIsNotNull()

createCriteria

Description

Creates a grails.orm.HibernateCriteriaBuilder instance for the domain class. (see Builders)

Example

def c = Account.createCriteria() def results = c { like("holderFirstName", "Fred%") and { between("balance", 500, 1000) eq("branch", "London") } maxResults(10) order("holderLastName", "desc") }

exists

Description

Checks whether an instance exists for the specified id and returns true if it does

Parameters

id (required) - The id of the instance

Example

if(Account.exists(1)) { // do something }

executeQuery

Description

Allows the execution of HQL queries against a domain class

Document generated by Confluence on Jan 31, 2007 10:29

Page 60

Parameters

query (required) - A query in HQL params (optional) - A set of positional parameters as a List of or single object

Example

Account.executeQuery( "select distinct a.number from Account a where a.branch = ?", 'London' ); Account.executeQuery( "select distinct a.number from Account a where a.branch = ? and a.created > ?", ['London',lastMonth] );

find

Description

Finds and returns the first result for the given query or null if no instance was found

Parameters

query (required) - Either an HQL query or a instance of the domain class for query by example arguments (optional) - A List of arguments for a positional parametrized HQL query

Example

Book.find("from Book as b where b.author='Dan Brown'") // Dan brown's first book Book.find("from Book as b where b.author=?",['Dan Brown']) // with a positional parameter def b = new Book(author:"Dan Brown") Book.find(b) // query by example

findAll

Description

Finds all of the domain class instances for the specified query

Parameters

query (optional) - Either an HQL query or a instance of the domain class for query by example arguments (optional) - A List of arguments for a positional parametrized HQL query max (optional) - The maximum number of results to retrieve

Examples

Document generated by Confluence on Jan 31, 2007 10:29

Page 61

Book.findAll() // everything Book.findAll("from Book as b where b.author='Dan Brown'",10) // The first 10 books from Dan Brown Book.findAll("from Book as b where b.author=?",['Dan Brown'],10) // with a positional parameter def b = new Book(author:"Dan Brown") Book.findAll(b) // query by example

findBy

Description

Dynamic method that uses the properties of the domain class to allow the creation of Grails query method expressions that return the first result of the query

Examples

class Book { Long id Long version String title Date releaseDate String author }

def b = b = b = b = b = b = b =

b = Book.findByTitle("The Shining") Book.findByTitleAndAuthor("The Sum of All Fears", "Tom Clancy") Book.findByReleaseDateBetween(firstDate, new Date()) Book.findByReleaseDateGreaterThanOrEqual(firstDate) Book.findByTitleLike("%Hobbit%") Book.findByTitleNotEqual("Harry Potter") Book.findByReleaseDateIsNull() Book.findByReleaseDateIsNotNull()

findAllBy

Description

Dynamic method that uses the properties of the domain class to allow the creation of Grails query method expressions that return all instances of the domain class

Examples

class Book { Long id Long version String title Date releaseDate String author }

def results = Book.findAllByTitle("The Shining", [max:10, sort:"title", order:"desc",

Document generated by Confluence on Jan 31, 2007 10:29

Page 62

offset:100] ) results = Book.findAllByTitleAndAuthor("The Sum of All Fears", "Tom Clancy") results = Book.findAllByReleaseDateBetween(firstDate, new Date()) results = Book.findAllByReleaseDateGreaterThanOrEqual(firstDate) results = Book.findAllByTitleLike("%Hobbit%") results = Book.findAllByTitleNotEqual("Harry Potter") results = Book.findAllByReleaseDateIsNull() results = Book.findAllByReleaseDateIsNotNull()

findWhere

Description

Uses named arguments that match the property names of the domain class to produce a query that returns the first result.

Examples

class Book { Long id Long version String title Date releaseDate String author }

def b = Book.findWhere(title:"The Shining", author:"Stephen King")

findAllWhere

Description

Uses named arguments that match the property names of the domain class to produce a query that returns all of the matching results.

Examples

class Book { Long id Long version String title Date releaseDate String author }

def books = Book.findAllWhere(author:"Stephen King")

get

Document generated by Confluence on Jan 31, 2007 10:29

Page 63

Description

Retrieves an instance of the domain class for the specified id, otherwise returns null

Examples

def b = Book.get(1)

list

Description

Lists all of the instances of the domain class.

Parameters

max - The maximum number to list offset - The offset from the first result to list from order - The order to list by, either "desc" or "asc" sort - The property name to sort by

Examples

def results = Book.list() // everything def results = Book.list(max:10) // 10 results def results = Book.list(max:10, offset:100) // 10 results, offset by 100 def results = Book.list(max:10, offset:100, sort:"title", order:"desc") // 10 results, offset by 100, orderd by title in descending order

listOrderBy

Description

Lists all of the instances of the domain class ordered by the property in the method expression

Parameters

max - The maximum number to list

Examples

def results = Book.listOrderByAuthor() // everything def results = Book.listOrderByTitle(max:10) // 10 results def results = Book.listOrderByTitle(max:10, offset:100, order:"desc") // 10 results, offset from 100

Document generated by Confluence on Jan 31, 2007 10:29

Page 64

withCriteria

Description

Allows inline execution of criteria with a closure. (Since 0.4)

Parameters

arguments (optional) - A map on named arguments that will be set on the criteria instance closure - A closure that defines the criteria

Examples

def results = Book.withCriteria { def now = new Date() between('releaseDate', now-7, now) like('title', '%Groovy%') }

withTransaction

Description

Uses Spring's TransactionTemplate combination with a closure. Since 0.4

Parameters

closure - A closure that gets passed an instance of the Spring TransactionStatus to allow programmatic management of savepoints (See SavepointManager) and transaction rollback

Examples

Book.withTransaction { tx -> def b = new Book(title:"Groovy in Action") b.save() // some logic that goes wrong tx.setRollbackOnly() }

Document generated by Confluence on Jan 31, 2007 10:29

Page 65

Tag Library ReferenceThis page last changed on Aug 08, 2006 by mercnboy3.

The Grails Custom Tag LibraryGrails supports both GSP and JSP as view technologies. There are however some key differences between the 2 view technologies which are listed below: GSP uses groovy inside scriptlets while JSP is Java GSP attribute values when surrounded with the ${..} (eg. test="${it=='true'}") syntax are Groovy expressions, while in JSP these are JSTL expressions (and hence more limited) JSP supports custom tag libraries through the TLD while GSP supports custom tag libraries with Grails Dynamic Tag Libraries and does not support JSTL GSP supports GString expressions inside the content whilst JSP requires you to use There are many shared tags but some additional ones for both GSP (mainly groovy syntax tags) and JSP hence we have 2 reference sections: 1. GSP Tag Reference 2. JSP Tag Reference

Document generated by Confluence on Jan 31, 2007 10:29

Page 66

GSP Tag ReferenceThis page last changed on Jan 25, 2007 by wangjammer5.

GSP Tag ReferenceLogical Tags

if else elseif

Iterative Tags

while each collect findAll grep

Linking Tags

link createLink createLinkTo

Ajax Tags

remoteField remoteFunction remoteLink formRemote submitToRemote

Form Tags

actionSubmit actionSubmitImage checkBox currencySelect form hiddenField datePicker select localeSelect textField

Document generated by Confluence on Jan 31, 2007 10:29

Page 67

textArea timeZoneSelect

UI Tags

richTextEditor

Rendering & Layout Tags

render renderErrors layoutHead layoutBody layoutTitle pageProperty paginate

Validation Tags

eachError hasErrors message

Document generated by Confluence on Jan 31, 2007 10:29

Page 68

GSP Tag - collectThis page last changed on Feb 17, 2006 by [email protected].

Tag - collect

Description

Uses the Groovy JDK collect method to iterate over each element of the specified object transforming the result using the expression in the closure

Parameters

in - The object to iterative over

Examples

Books titles: Title: ${it}

Document generated by Confluence on Jan 31, 2007 10:29

Page 69

GSP Tag - eachThis page last changed on Aug 17, 2006 by takamori.

Tag - each

Description

Uses the Groovy JDK each method to iterate over each element of the specified object

Parameters

in - The object to iterative over var (optional) - The name of the item. Note that this must be specified when the iterator value is to be used from within the body of a GSP Dynamic Tag , such as in g:link. See the example below.

Examples

Title: ${it.title} Author: ${it.author}

With a named item:

Title: ${book.title} Author: ${book.author}

Another example, where a named item is necessary (otherwise the access to the title property will fail):

${item.title}

Document generated by Confluence on Jan 31, 2007 10:29

Page 70

GSP Tag - elseThis page last changed on Feb 17, 2006 by [email protected].

Tag - else

Description

The logical else tag

Parameters

None

Examples

Hello Fred! Hello ${name}! Do I know you?

Document generated by Confluence on Jan 31, 2007 10:29

Page 71

GSP Tag - elseifThis page last changed on May 25, 2006 by [email protected].

Tag - elseif

Description

The logical elseif tag

Parameters

test - The expression to test

Examples

Hello Fred! Hello bob!

Document generated by Confluence on Jan 31, 2007 10:29

Page 72

GSP Tag - findAllThis page last changed on Feb 17, 2006 by [email protected].

Tag - findAll

Description

Uses the Groovy JDK findAll method to iterate over each element of the specified object that match the GPath expression within the attribute "expr"

Parameters

in - The object to iterative over expr - A GPath expression

Examples

Stephen King's Books: Title: ${it.title}

Document generated by Confluence on Jan 31, 2007 10:29

Page 73

GSP Tag - grepThis page last changed on Feb 17, 2006 by [email protected].

Tag - grep

Description

Uses the Groovy JDK grep method to iterate over each element of the specified object that match the specified "filter" attribute. The filter can be different instances such as classes, regex patterns etc.

Parameters

in - The object to iterative over filter - The filter instance

Examples

Stephen King's non-fiction Books: Title: ${it.title}

Document generated by Confluence on Jan 31, 2007 10:29

Page 74

GSP Tag - ifThis page last changed on Feb 17, 2006 by [email protected].

Tag - if

Description

The logical if tag

Parameters

test - The expression to test

Examples

Hello ${name}!

Document generated by Confluence on Jan 31, 2007 10:29

Page 75

GSP Tag - layoutBodyThis page last changed on Apr 19, 2006 by [email protected].

Tag - layoutBody

Description

Used in layouts to output the contents of the body tag of the decorated page.

Parameters

None

Examples

Example decorated page:

Page to be decorated

Example decorator layout:

Results in:

Page to be decorated

Document generated by Confluence on Jan 31, 2007 10:29

Page 76

GSP Tag - layoutHeadThis page last changed on Apr 19, 2006 by [email protected].

Tag - layoutHead

Description

Used in layouts to output the contents of the head tag of the decorated page. Equivalent to the SiteMesh tag.

Parameters

None

Examples

Example decorated page:

Page to be decorated

Example decorator layout:

Results in:

Page to be decorated

Document generated by Confluence on Jan 31, 2007 10:29

Page 77

GSP Tag - layoutTitleThis page last changed on Apr 19, 2006 by [email protected].

Tag - layoutTitle

Description

Used in layouts to output the contents of the title tag of the decorated page. Equivalent to the SiteMesh tag.

Parameters

None

Examples

Example decorated page:

Hello World! Page to be decorated

Example decorator layout:

Results in:

Hello World! Page to be decorated

Document generated by Confluence on Jan 31, 2007 10:29

Page 78

GSP Tag - pagePropertyThis page last changed on May 25, 2006 by [email protected].

Tag - pageProperty

Description

Used in layouts to output the contents a property of the decorated page. Equivalent to the SiteMesh tag.

Parameters

None

Examples

Example decorated page:

Page to be decorated

Example decorator layout:

Results in:

Page to be decorated

Document generated by Confluence on Jan 31, 2007 10:29

Page 79

GSP Tag - paginateThis page last changed on Nov 08, 2006 by [email protected].

Tag - paginate

Description

Creates next/previous buttons and a breadcrumb trail to allow pagination of results

Parameters

total (required) - The total number of results to paginate 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 params (optional) - A map containing request parameters prev (Optional) - The text to display for the previous link (defaults to "Previous") next (Optional) - The text to display for the next link (defaults to "Next") breadcrumb (Optional) - Whether to display a breadcrumb (defaults to "true")

Examples

Example domain class:

class Book { String title String author }

Example controller:

class BookController { def list = { [books: Book.list(params)] } }

Paginate code:

or

Document generated by Confluence on Jan 31, 2007 10:29

Page 80

Document generated by Confluence on Jan 31, 2007 10:29

Page 81

GSP Tag - whileThis page last changed on Feb 17, 2006 by [email protected].

Tag - while

Description

Executes a condition in a loop until the condition returns false

Parameters

test - The conditional expression

Examples

Current i = ${i}

Document generated by Confluence on Jan 31, 2007 10:29

Page 82

Tag - actionSubmitThis page last changed on Sep 02, 2006 by takamori.

Tag - actionSubmit

Description

Creates a submit button with the indicated value. Javascript event handlers can be added using the same parameter names as in HTML.

Parameters

value - The title of the button and indicated action.

Examples

Document generated by Confluence on Jan 31, 2007 10:29

Page 83

Tag - actionSubmitImageThis page last changed on Jan 25, 2007 by wangjammer5.

Tag - actionSubmitImage

Description

Creates a submit button using the input type="image" with the indicated value. Javascript event handlers can be added using the same parameter names as in HTML.

Parameters

value - The title of the button and indicated action. src - The source of the image to use

Examples

Document generated by Confluence on Jan 31, 2007 10:29

Page 84

Tag - checkBoxThis page last changed on Feb 17, 2006 by [email protected].

Tag - checkBox

Description

Creates a checkbox form field. All the usual HTML elements apply beyond the below:

Parameters

name (optional) - The name of the checkbox value (optional) - The value of the checkbox, if evaluates to true sets to checkbox to checked

Examples

// a checked checkbox

Document generated by Confluence on Jan 31, 2007 10:29

Page 85

Tag - createLinkThis page last changed on Jun 25, 2006 by glaforge.

Tag - createLink

Description

Creates a link that can be used where necessary (for example in an href, javascript, ajax call etc.)

Parameters

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 url (op