You are on page 1of 120

Table

of Contents
Introduction 1.1
Project setup 1.2
Command Line 1.2.1
IntelliJ IDEA 1.2.2
Eclipse 1.2.3
NetBeans 1.2.4
Plugin Configuration 1.2.5
Clean up 1.2.6
Best Practices 1.2.7
Database 1.3
GORM 1.3.1
Create Domain Model 1.3.1.1
Transactions 1.3.1.2
LazyInitializationException 1.3.1.3
Open Session In View I. 1.3.1.4
Open Session In View II. 1.3.1.5
Table Container 1.3.1.6
Groovy SQL 1.3.2
Create Sql 1.3.2.1
Execute SQLs 1.3.2.2
MyBatis 1.3.3
Configuration 1.3.3.1
Basics 1.3.3.2
JdbcTemplate 1.3.4
Create Beans 1.3.4.1
Usage 1.3.4.2
Clean Up With Alternatives 1.3.5
Architecture 1.4
Model View Presenter 1.4.1
Spring Autowiring 1.5

2
Create Simple Application 1.5.1
Application With Navigator 1.5.2
UI 1.6
Re-using GORM Validations 1.6.1
Async Push 1.6.2
Multiple application 1.6.3
SASS Compilation 1.6.4
Widgetset Compilation 1.6.5
Spring Security 1.7
Spring Security Dependency 1.7.1
Spring Security Basics 1.7.2
Secured Navigator 1.7.3
Localization 1.8
Localization Basics 1.8.1
Custom MessageSource 1.8.2
REST 1.9
Without using root URL 1.9.1
Using root URL for Vaadin app 1.9.2
Plugin development 1.10
Github 1.10.1
Development 1.10.2

3
Introduction

Vaadin on Grails
The book describes how to create project, setup configuration, what code is created
automatically and how to clean up the code that will become useless when we use Vaadin
for user interface.

We will go through two approaches how to work with database. The first one is GORM,
which is the default option. And then few alternatives to GORM that are MyBatis,
JdbcTemplate and Groovy Sql.

We will look at data binding tricks, basic ideas for architecture and how to compose the
components using Model View Presenter (MVP).

The book also contains tutorials how to compile SASS and widget set, after you add an add-
on. How to use Spring security, localization and how to add a REST API from a Vaadin
application and many other things.

If you are completely new to both technologies, the book will show you first steps to start up
and then you can continue with Vaadin and Grails documentation.

If you are both Vaadin and also Grails expert, you might look at the book as a reference
book, set of tutorials and also a place with several solutions that you might have to solve in
your applications.

Behind The Scenes


This book could be written thanks to:

Questions you have been asking during last few years about development of Vaadin
using Groovy and Grails.
Many years spend with development of applications using Grails and Vaadin.
Chapter about Grails in Vaadin 7 Cookbook that showed there is more to discover.

Vaadin
Vaadin provides both simple and complex web UI components that can be displayed in
browser or in mobile app, while the client side, an applicaiton running inside a web browser,
is still connected to the server and communication happens when required, after user's
action or when server pushes data to the client from the server.

4
Introduction

Developers who like object oriented programing and design patterns that result in
predictable APIs, might feel excited about the way how the development of an user interface
can be done with Vaadin. We can play with UI components and still keep thinking about it as
object structures in Java.

Grails
Grails 2.x is supported in the book. Support for Grails 3.x is comming soon.

Grails is framework used to build applications in really short time, because it provides:

Dependency management
Dependency injection with Spring application context
URL mapping
Filters
Controllers
Groovy Server Pages (.gsp) & tags
AJAX support
REST, SOAP
GORM (Grails ORM)
Transactional service layer
Async behavior
Internationalization i18n
Environments
Using Groovy and Java languages
Groovy-powered Gant command line
On the fly reloading

The most useful feature of Grails might be GORM (Grails Object Relation Mapping) that
makes really easy to create a database layer. Then there are services, which support
transactions, that are the place to put the application logic.

Rich internet applications in Grails


In case you want to build a rich JavaScript client, you need to invest quite some time to build
client side components. Which makes sense if we need to develop own components with
special features (for example new generation of paginated table that looks like a chart). But
sometimes, we need to build applications that should rather focus on solving customers

5
Introduction

issues and implementation of business logic rather than spend time on implementation of
JavaScript components. If that is the case, we could choose Vaadin to implement our Rich
Internet Applications (RIA).

Vaadin plugin
There is a Grails plugin called vaadin that integrates Vaadin into Grails realm, by providing
dependencies to Vaadin libraries. Also, the plugin provides some support for development.

Create start-up code with sample application


Help to access beans and localization values
SASS compilation
Widgetset compilation

6
Project setup

Project setup
We are going to learn how to create and configure Grails application with Vaadin plugin in
this chapter.

First we need to get Grails installed on your local machine. Type grails --version in your
console in order to make sure you have the latest version, because Vaadin plugin is always
updated to work with latest version of both Vaadin and Grails frameworks.

If Grails is not on your local and you need some help with installation, follow these tutorials.

Mac OS X
http://www.grailsexample.net/installing-a-grails-development-environment-on-os-x

Windows
http://www.grailsexample.net/installing-a-grails-development-environment-on-windows

7
Project setup

Linux
http://www.grailsexample.net/installing-a-grails-development-environment-on-linux

8
Command Line

Command line
Working example project, which results from this tutorial, can be downloaded from
github.com/vaadin-on-grails/quickstart-app.

Using Grails command line to create a new application is probably the most reliable way. We
can basically say that if you are not able to create project using the command line, you will
be not able to work with Grails at all and you need to re-install Grails or fix its configuration.

Create application
These instructions are supposed to be executed by using the command line.

Step 1
Open your console and run grails create-app my-app that will create new directory called
my-app with sample Grails application.

Step 2
Go to that directory cd my-app and open that folder in a text editor of your choice.

Step 3
Open BuildConfig.groovy and add latest version of vaadin plugin into compile scope
compile ":vaadin:7.6.1" .

9
Command Line

Step 4
Now we need to run grails vaadin-quickstart , so Vaadin plugin can generate sample
application for us.

Step 5
We want to prevent Grails to take over URL mapping. Open UrlMappings.groovy and make
sure the URL mapping is empty.

class UrlMappings {
static mappings = {
}
}

Step 6

10
Command Line

We are ready to start up the application. Run grails run-app command. Vaadin application
running on http://localhost:8080/my-app will become accessible after a while.

11
IntelliJ IDEA

IntelliJ IDEA
Working example project, which results from this tutorial, can be downloaded from
github.com/vaadin-on-grails/quickstart-app.

Grails support in IntelliJ IDEA is added through Grails plugin. Make sure it is installed in your
IntelliJ IDEA before you start with the tutorial.

Step 1
Go to http://grails.org/download and get the latest version of Grails. Unpack the Grails
archive on your local computer and start up IntelliJ IDEA.

Step 2
Open the New Project window and select Grails from the list and click on Next button.

Optional

If it is your first Grails project in IDEA, click on Create... button and then select the root of
your unpacked Grails archive. It will add Grails into IDEA.

Step 3
Fill in the name of the project and choose the latest version of Grails.

12
IntelliJ IDEA

Step 4
Click on Finish and on the next dialog, choose Run 'create app' .

Warning: sometimes, IDEA is not able to create Grails project and you end up with
weird errors. In that case, try to upgrade IDEA version or run grails create-app my-app
in console. Then after that open the project in IDEA.

Step 5
Open file BuildConfig.groovy and add Vaadin plugin compile ":vaadin:7.6.1" .

13
IntelliJ IDEA

The latest version of the plugin is always available on http://grails.org/plugin/vaadin

Now we need to tell IDEA to reload dependencies. Run grails compile or refresh the
dependencies as shown on the following picture.

Synchronize Grails setting should be performed always when you run into issues with

dependencies.

Step 6
Run grails vaadin-quickstart that will generate sample code to easier project
configuration.

14
IntelliJ IDEA

The command vaadin-quickstart will generate MyUI.groovy and remove URL mapping
inside UrlMapping.groovy .

Optional

We have to disable Grails to take control over the URLs, so Vaadin can do it instead. Open
UrlMappings.groovy file and make sure the URL mapping is empty, so the content of the file

is the following.

class UrlMappings {
static mappings = {
}
}

If you see unable to resolve class com.vaadin.grails.VaadinConfiguration error during


compile, compile the project once more. There an issue with Grails together with IntelliJ
IDEA and it is not possible to compile the project in the first run. Note that everything
will work properly and you can ingnore that error.

Step 8
We are ready to run the application. Click on the little green triangle in toolbar.

You can also press Alt+Cmd+G on Mac OS or Ctrl+Alt+G on Windows and type run-
app in order to run the application.

Step 9

15
IntelliJ IDEA

Run the application again and a Vaadin application with a single Home label will be available
on http://localhost:8080/ria-app in your browser.

16
Eclipse

Eclipse
Working example project, which results from this tutorial, can be downloaded from
github.com/vaadin-on-grails/quickstart-app.

Spring provides great tool Groovy/Grails Tool Suite for development of Groovy and Grails
based projects. If Eclipse is your development IDE, you should definetelly get GGTS.

We will show how to create a new Grails project with Vaadin using GGTS in this article.

Step 1
Search for Grails type of project in New Project wizard and click on Next .

Step 2
Type a name of the project and click on Finish .

17
Eclipse

Step 3
Open file BuildConfig.groovy and add Vaadin plugin compile ":vaadin:7.6.1" .

The latest version of the plugin is always available on http://grails.org/plugin/vaadin

18
Eclipse

Run grails compile to reload dependencies. Click on Grail icon in GGTS and type there
compile .

Then run grails vaadin-quickstart that will generate sample code to easier project
configuration.

The command vaadin-quickstart will generate MyUI.groovy and remove URL mapping
inside UrlMapping.groovy .

Optional

We have to disable Grails to take control over the URLs, so Vaadin can do it instead. Open
UrlMappings.groovy file and make sure the URL mapping is empty, so the content of the file

is the following.

19
Eclipse

Step 6
Click on Grail icon again and run run-app command.

Step 7
Now your application is running on http://localhost:8080/my-app

20
NetBeans

NetBeans
Working example project, which results from this tutorial, can be downloaded from
github.com/vaadin-on-grails/quickstart-app.

You need to install full version of NetBeans (where Groovy is included).

Then you need to install Grails plugin for NetBeans. Search for grails and mark Groovy
and Grails plugin as selected.

Click on Install button and finish the instalation which will require restart Netbeans IDE.

Step 1
Open New Project window to create Grails application. Select Grails Application and
click on Next .

21
NetBeans

Step 2
Type name of the project and finish the wizard.

Also configure Grails version that will be used for your project.

22
NetBeans

Step 3
Open BuildConfig.groovy and add dependency to vaadin plugin compile ":vaadin:7.6.1" .

The latest version of the plugin is always available on http://grails.org/plugin/vaadin

Open commands window in Netbeans.

23
NetBeans

Run grails compile command. It will download Vaadin plugin together with all mandatory
dependencies.

Then click on Refresh Commands button and run grails vaadin-quickstart that will generate
sample code to easier project configuration.

The command vaadin-quickstart will generate MyUI.groovy and remove URL mapping
inside UrlMapping.groovy .

24
NetBeans

Optional

We want to prevent Grails to take over URL mapping. Open UrlMappings.groovy and make
sure the URL mapping is empty.

class UrlMappings {
static mappings = {
}
}

Step 5
We are ready to start up the application. Run grails run-app command.

Vaadin application running on http://localhost:8080/my-app will become accessible after a


while.

25
NetBeans

26
Plugin Configuration

Basics
When we add dependency to Vaadin plugin into BuildConfig.groovy and run grails
compile the plugin generates the following files inside our Grails application.

MyUI.groovy
Sample UI class src/groovy/app/MyUI.groovy which contains code that just shows a label in
the web browser.

We can immediatelly start coding Vaadin application using that file, or maybe rather do a
refactoring. For example, rename the file to AppUI.groovy and move it to different package
(folder) src/groovy/com/company/app . Then you need to change mapping property inside
VaadinConfig.groovy .

VaadinConfig.groovy
Vaadin configuration file grails-app/conf/VaadinConfig.groovy contains all the configuration
that is required by the plugin.

We will explore what all can be configured in VaadinConfig.groovy .

mapping
We can provide multiple Vaadin UI classes that extends com.vaadin.ui.UI and they will be
mapped to specified URL patterns. There must be at least one UI class.

Let's look at this example where we map three URL paters, each to separate UI class.

mapping = [
"/*": "app.MyUI",
"/admin/*": "app.AdminUI",
"/client/*": "app.ClientUI"
]

The application UIs will then become available at:

http://localhost:8080/grails-vaadin7-demo
http://localhost:8080/grails-vaadin7-demo/client
http://localhost:8080/grails-vaadin7-demo/admin

27
Plugin Configuration

Be aware, creating multiple UIs is not the way how to navigate in the Vaadin applicatin.
Use views navigator for this.

mappingExtras
We need to define extra mapping in case we need to 'reserve' a URL that should not be
mapped to, for example, /* by Vaadin.

For example, we need to enable console plugin. First we add plugin dependency compile
":console:1.4.4" into BuildConfig.groovy .

Then we provide mapping for /console/* pattern.

mappingExtras = [
'/console/*'
]

To get console plugin working, you need to apply this hack.

productionMode
When production mode is set to false, it enables debug mode. So, we can easily inspect
application in browser by adding ?debug to the end of URL.

By default, the productionMode is set to false also inside Grails.

productionMode = false

In order to enable productionMode in production, make sure the following code is present.

environments {
production {
vaadin {
productionMode = true
}
}
}

asyncSupported
Set this property to true to enable asynchronous communication, so you can use Vaadin
push.

28
Plugin Configuration

asyncSupported = true

themes
You can provide name of the themes, which is a directory name in web-app/VAADIN/themes
folder.

themes = ['sample']

sassCompile
You can specify exact version of Vaadin for SASS compilation.

sassCompile = '7.6.1'

widgetset
In order to use your own widget set, for example, if you need to use add-ons.

widgetset = 'com.mycompany.widgetset'

If widgetset is not set, the default widget set from Vaadin is used.

servletClass
There is a default servlet, com.vaadin.grails.server.DefaultServlet , provided by Vaadin
plugin that makes actually possible to run Vaadin inside Grails.

If you need to create your own servlet, you can do it by extending


com.vaadin.grails.server.DefaultServlet . Then set servletClass to your custom servlet.

servletClass = "com.app.MyGrailsAwareApplicationServlet"

packages
We can define a package name where Spring will search for components.

packages = ['com.mycompany.vaadin']

29
Plugin Configuration

This is optional, all packages will get scanned by default.

uiProvider
We can create own implementation of com.vaadin.server.UIProvider .

uiProvider = "com.mycompany.MyGrailsAwareUIProvider"

This is optional, default is com.vaadin.grails.server.DefaultUIProvider .

openSessionInViewFilter
In order to activate Open Session in View for Hibernate 3.

openSessionInViewFilter = 'org.springframework.orm.hibernate3.support.OpenSessionInVie
wFilter'

Or this for Hibernate 4.

openSessionInViewFilter = 'org.springframework.orm.hibernate4.support.OpenSessionInVie
wFilter'

30
Clean up

Clean up
Grails create-app command generates many code we do not really need in the application.
Let's clean it up.

Remove assets
We can remove grails-app/assets folder because all required assets are provided by
Vaadin.

Remove views
When we use Vaadin as UI framework, we need no .gsp pages in our application. We can
remove grails-app/views .

Dependencies
There are not needed dependencies if we use Vaadin. We can exclude them globaly.

Add excludes in BuildConfig.groovy as follows.

grails.project.dependency.resolution = {
inherits("global") {
'grails-plugin-gsp', 'grails-plugin-rest', 'grails-resources'
}

Verify what has been excluded by running grails dependency-report command. You
can add a scope as the parameter, for example, grails dependency-report compile ,
grails dependency-report runtime and so on. In order to be sure that a dependency is

excluded, run grails clean-all before the commands mentioned above.

The second step in clearing dependencies is to remove all dependencies and plugins that
are generated by Grails. Dependencies and plugins part of BuildConfig.groovy will then
become like this.

31
Clean up

dependencies {
}

plugins {
build ":tomcat:7.0.55"
compile ":vaadin:7.2.5"
}

Last step
Grails generates inline comments for almost each property trying to explain what is the
purpose of that property. I think if somebody wants to know what is the meaning of a
property, he should go to documentation, read about it and fully understand what is it about.
Therefore I suggest to remove these comments.

32
Best Practices

Best Practices

Keep work with GORM in Services


Never work with GORM in Vaadin code, use services or any other layer, like DAO, to
encapsulate work with database. It will keep your Vaadin and database code separated,
which will make the application code more readable and maintainable.

CompileStatic
Use @CompileStatic annotation everywhere you can. The exception not to use the
annotation is dynamic code where you need to utilize dynamic features of Grails, for
example, to access variables that are not visible during compilation.

Types
Use def only when it is required, because it always good to know type of a variable.
Together with @CompileStatic annotation, you will know about compilation errors during
compilation, not during runtime.

33
Database

Database
We will explore two ways how to access database from Grails together with Vaadin. The first
one is GORM (Grails Object Relation Mapping), which is the defualt way to access database
in Grails.

The second part will show how to integrate Grails with other than GORM database
frameworks and how to use it in Vaadin.

34
GORM

GORM
Grails Object Relational Mapping (GORM) provides easy way to define your database mode
and it comes for free with Grails.

Usually the only place you need to configure, to get GORM working with your database, is
DataSource.groovy . Grails will create bean dataSource that will be used for fetching data

from database and that will reflect data source configuration you have set there.

If you want to provide external configuration file, for example you deploy application to
several production environments, you can define external config and set the data
source configuration there.

35
Create Domain Model

Create domain model


Example code is available on github.com/vaadin-on-grails/gorm-domain.

Grails documentation has nice description how to work with domain classes. In case you are
new to Grails domain classes, you should definitelly read it.

Anyway, let's show an example how to create a domain object and use it in Vaadin
application.

Step 1
Run Grails create-domain command that will create the new domain class Item .

grails create-domain-class com.app.Item

The generated and empty domain class Item.groovy is in grails-app/domain/com/app


folder.

Step 2
Before we start testing the domain class, we need to add there at least one field, for
example, a string label .

package com.app

class Item {

String label

static constraints = {
}
}

Domain object must be stored in grails-app/domain , contain at static field


constraints to be considered as a valid domain object. Only then a database table for

a domain object will be created.

Step 3
Now, we need to create few records of Item in the database during the application start-up.

36
Create Domain Model

Open BootStrap.groovy and save few Item instances there.

import com.app.Item

class BootStrap {

def init = { servletContext ->


new Item(label: 'First').save()
new Item(label: 'Second').save()
new Item(label: 'Third').save()
new Item(label: 'Fourth').save()
}

def destroy = {
}
}

Step 4
Use domain class to fetch all records from the database and display them in the browser.

import com.app.Item
import com.vaadin.server.VaadinRequest
import com.vaadin.ui.Label
import com.vaadin.ui.UI
import com.vaadin.ui.VerticalLayout

class MyUI extends UI {

@Override
protected void init(VaadinRequest vaadinRequest) {

VerticalLayout layout = new VerticalLayout()


layout.setMargin(true)

List<Item> items = Item.findAll()


for (Item item : items) {
String label = item.label
layout.addComponent(new Label(label))
}

setContent(layout)
}
}

Run the application and database records will be displayed in UI.

37
Create Domain Model

38
Transactions

Transactions
Example code is available on github.com/vaadin-on-grails/gorm-transactions.

Grails service layer is the proper place to put all the application logic. Services are
transactional and also good place to make your applications code reusable.

In this article will show how to store user with a new account in a transaction. So, when
account is saved but saving user fails the transaction is rolled back. That results in scenario
that nothing is storred, user nor account.

Step 1
Create domain class that represents an account: grails create-domain-class
com.myapp.Account .

class Account {

static constraints = {
}
}

Step 2
Create domain class that represents an user that will have a reference to an accont: grails
create-domain-class com.myapp.User .

class User {

String username
String password

static belongsTo = [account: Account]

static constraints = {
}
}

Step 3

39
Transactions

In this step we create AccountService that will be transactional, meaning that all methods in
the service will be executed in a transaction. When an exception that extends
RuntimeException is thrown, the transaction will be rolled back automatically.

It is also possible to define transactional behavior on method level.

Run grails create-service com.myapp.AccountService to create the service.

import grails.transaction.Transactional

@Transactional
class AccountService {

void createUserWithAccount(String username, String password) {


Account account = new Account()
account.save(failOnError: true)

User user = new User()


user.username = username
user.password = password
user.account = account
user.save(failOnError: true)

throw new RuntimeException("unexpected exception to simulate failure")


}
}

Instead of defining failOnError: true everywhere, it is possible to enable failOnError


globaly grails.gorm.failOnError = true in Config.groovy .

Step 4
Create a view that will execute createUserWithAccount with dummy values. After the method
is executed, try to fetch values from database and print it into the console to see nothing is
stored in database because we let the transaction fail.

40
Transactions

package app

import com.myapp.Account
import com.myapp.AccountService
import com.myapp.User
import com.vaadin.grails.Grails
import com.vaadin.navigator.View
import com.vaadin.navigator.ViewChangeListener
import com.vaadin.ui.Button
import com.vaadin.ui.VerticalLayout

class AccountView extends VerticalLayout implements View {

static final String VIEW_NAME = "account"

@Override
void enter(ViewChangeListener.ViewChangeEvent viewChangeEvent) {

Button btn = new Button("Create account")


btn.addClickListener(new Button.ClickListener() {
@Override
void buttonClick(Button.ClickEvent clickEvent) {
AccountService accountService = Grails.get(AccountService)

try {
accountService.createUserWithAccount('test', 'password')
} catch (Exception e) {
println "failed: ${e.message}"
}

println Account.findAll()
println User.findAll()
}
})

addComponent(btn)
}
}

Step 3
In order to test the behavior, we can use the account view in MyUi class.

41
Transactions

package app

import com.vaadin.navigator.Navigator
import com.vaadin.server.VaadinRequest
import com.vaadin.ui.UI

class MyUI extends UI {

@Override
protected void init(VaadinRequest vaadinRequest) {

Navigator navigator = new Navigator(this, this)

navigator.addView(AccountView.VIEW_NAME, AccountView)

navigator.navigateTo(AccountView.VIEW_NAME)
}
}

When we run the application and a runtime exception is thrown in the service method, we
should see no database items fetched from the database. Have a look the console output to
see what has happend.

failed: database connection failed


[]
[]

After we remove throwing a runtime exception exception:

void createUserWithAccount(String username, String password) {


Account account = new Account()
account.save(failOnError: true)

User user = new User()


user.username = username
user.password = password
user.account = account
user.save(failOnError: true)
}

We will see that rows has been inserted into the database. Have a look the console output to
see what has happend.

[com.myapp.Account : 1]
[com.myapp.User : 1]

42
Transactions

43
LazyInitializationException

LazyInitializationException
Example code is available on github.com/vaadin-on-grails/gorm-
LazyInitializationException.

When we create a domain model that will cause lazy loading of other domain object, we
might run into the troubles with LazyInitializationException .

The Issue
In order to fully understand, lets show the code simulates LazyInitializationException .

Create Account class that will just contain name property.

class Account {

String name

static constraints = {
}
}

Now create class User that will belong to Account and in toString() method, just try to
get value from account field. When that code is executed, Hibernate will try to load an
account from database and will throw LazyInitializationException .

class User {

String username
String password

static belongsTo = [account: Account]

static constraints = {
}

public String getLabel() {


return "$username - $account.name"
}
}

In order to simulate the issue, here is the Vaadin code that will create a ComboBox with an
instance of User class.

44
LazyInitializationException

VerticalLayout layout = new VerticalLayout()

ComboBox userAccount = new ComboBox()

User user = User.findAll()[0]


BeanItem item = new BeanItem(user, 'label')

userAccount.addItem(item)

layout.addComponent(userAccount)
setContent(layout)

How to prevent LazyInitializationException


The solution to avoid LazyInitializationException , is to disable lazy loading for class that
should be also fetched at once with the other domain object.

Say to Hibernate to load account together with the user. Add the following code into User
class.

static mapping = {
account lazy: false
}

When you try to execute the application, you the account will be already loaded in
getLabel() method and it will not fail.

This also makes sense from performance point of view, because we will avoid multiple
database calls and the user and account will be loaded together, in single database call.

Another approach is to have open session for each request. Read the next two articles
about Open Session In View to find out how to implement it in your application.

45
Open Session In View I.

Open Session In View I.


Example code is available on github.com/vaadin-on-grails/gorm-open-session-in-view-i.

As described in LazyInitializationException article, we will run into troubles with


LazyInitializationException when domain object tries to load other object lazily. If the

disabling of lazy loading is not what we are looking for and we still want to do lazy fetching,
we have to use OSIV (Open Session In View).

Stephan Grundner has implemented adding OSIV filter into the plugin. Thanks to that we
can configure openSessionInViewFilter property in VaadinConfig.grovy .

openSessionInViewFilter = 'org.springframework.orm.hibernate4.support.OpenSessionInVie
wFilter'

Or add older Hibernate filter in case you are using Hibernate 3.

openSessionInViewFilter = 'org.springframework.orm.hibernate3.support.OpenSessionInVie
wFilter'

46
Open Session In View II.

Open Session In View II.


Example code is available on github.com/vaadin-on-grails/gorm-open-session-in-view-
ii.

In the previous article we have described how to enable OSIV in VaadinConfig.groovy. This
tutorial will show way how to do it in the old way, without configuration.

The other way to use OSIV in Grails with Vaadin is to manually add an extra filter
OpenSessionInViewFilter into web.xml file.

Step 1
Generate project templates in your project. install-templates command will generate
many files inside src/templates folder.

grails install-templates

Leave only web.xml and remove folders artifacts , scaffolding and testing .

Step 2
Add the following filter definition, that will keep session opened during each reqiest, into
generated web.xml .

<!-- OSIV Filter -->


<filter>
<filter-name>openSessionInView</filter-name>
<filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</
filter-class>
</filter>

<filter-mapping>
<filter-name>openSessionInView</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

47
Open Session In View II.

Change package name of OpenSessionInViewFilter for Hibernate 3


org.springframework.orm.hibernate3.support.OpenSessionInViewFilter

We are done. Now we can run the application and Hibernate session will be always opened,
during each Vaadin request.

48
Table Container

Table Container
Example code is available on github.com/vaadin-on-grails/gorm-vaadin-table.

In this tutorial we will show how to display GORM objects in Vaadin Grid.

Step 1
Create a domain object Item with two String fields name and other .

package com.vaadinongrails

class Item {

String name
String other

static constraints = {
}
}

Step 2
Create few records of Item in database in BootStrap.groovy file.

class BootStrap {

def init = { servletContext ->


new Item(name: "Hi 1", other: "There").save(failOnError: true)
new Item(name: "Hi 2", other: "There").save(failOnError: true)
new Item(name: "Hi 3", other: "There").save(failOnError: true)
new Item(name: "Hi 4", other: "There").save(failOnError: true)
}
def destroy = {
}
}

Step 3
Create instance of Grid in Vaadin code. We need to do two things to see GORM objects
nicely displayed in the grid:

1. Create new BeanItemContainer and add GORM objects into it.

49
Table Container

2. GORM object contains more fields then we have defined and we have to pick what
columns will be visible. Then we have to remove the others which are not supposed to
be visible.

package app

import com.vaadin.data.util.BeanItemContainer
import com.vaadin.grails.ui.VaadinUI
import com.vaadin.server.VaadinRequest
import com.vaadin.ui.Grid
import com.vaadin.ui.UI
import com.vaadin.ui.VerticalLayout
import com.vaadinongrails.Item

@VaadinUI(path = '/')
class MyUI extends UI {

@Override
protected void init(VaadinRequest vaadinRequest) {

VerticalLayout layout = new VerticalLayout()


layout.setMargin(true)

Grid grid = new Grid()


grid.setSelectionMode(Grid.SelectionMode.SINGLE)

BeanItemContainer<Item> container = new BeanItemContainer<>(Item.class)


List<Item> all = Item.findAll()
container.addAll(all)
grid.setContainerDataSource(container)

grid.setColumnOrder("id", "name", "other")


grid.removeColumn("attached")
grid.removeColumn("metaClass")
grid.removeColumn("properties")
grid.removeColumn("version")
grid.removeColumn("dirty")
grid.removeColumn("dirtyPropertyNames")
grid.removeColumn("errors")

layout.addComponent(grid)

setContent(layout)
}
}

Step 4
Run application and see the table with GORM objects from database.

50
Table Container

51
Groovy SQL

Groovy SQL
Groovy Sql provides simple way to access database. It can become handy when our
application is supposed to only fetch data and we do not want to utilize Hibernate.

Still, if we need to work with domain objects, it is better to use GORM that provides full
package to perform CRUD operations. This chapter provides information how to utilize
Groovy SQL in Grails application with Vaadin.

52
Create Sql

Create Sql
Example code is available on github.com/vaadin-on-grails/groovy-sql.

We can use Groovy Sql class to access a database. The proper way to create new instance
of Sql class is to define new bean in resources.groovy .

import groovy.sql.Sql

beans = {
sql(Sql, ref('dataSource')) { bean ->
bean.destroyMethod = 'close'
}
}

If, from any reason, you would need to create Sql manually, you can the alternative
approach to create Sql each time before SQL execution.

Sql sql = new Sql(dataSource: Grails.applicationContext.getBean('dataSource'))


// execute your queries
sql.close()

53
Execute SQLs

Execute SQLs
Example code is available on github.com/vaadin-on-grails/groovy-sql.

In order to execute a query with Groovy Sql just get dataSource bean from the application
context, which we have created it in Create Sql article.

import com.vaadin.ui.UI
import com.vaadin.ui.VerticalLayout
import com.vaadin.server.VaadinRequest
import com.vaadin.ui.Label
import com.vaadin.grails.Grails
import groovy.sql.GroovyResultSet
import groovy.sql.Sql

class MyUI extends UI {

@Override
protected void init(VaadinRequest vaadinRequest) {
VerticalLayout layout = new VerticalLayout()

Sql sql = Grails.get(Sql)


sql.eachRow("SELECT * FROM User") { GroovyResultSet result ->
String firstName = result.getString('username')
layout.addComponent(new Label(firstName))
}

setContent(layout)

// Sql sql = new Sql(dataSource: Grails.applicationContext.getBean('dataSource


'))
// execute your queries
// sql.close()
}
}

Constructing SQL strings in Java or Groovy code is not easy and it is, for some of us,
annoying. I recommend to use jOOQ library to construct SQL strings.

54
MyBatis

MyBatis
Since GORM is the default Grails database access framework, we need to add extra code to
support MyBatis.

This chapter will show how to configure MyBatis inside Grails framework and how to perform
basic operations.

55
Configuration

Configuration
Example code is available on github.com/vaadin-on-grails/mybatis.

Because Grails is based on Spring, we can use mybatis-spring library to integrate MyBatis
into Grails.

Step 1
Add mybatis and mybatis-spring dependencies into BuildConfig.groovy .

compile 'org.mybatis:mybatis:3.2.7'
compile 'org.mybatis:mybatis-spring:1.2.2'

Step 2
Define new beans in resources.groovy .

sqlSessionFactory configures connection factory using XML files at the specified

location
mapperScannerConfigurer will scan for mappers based on what is defined by

basePackage property

import org.apache.commons.dbcp.BasicDataSource
import org.mybatis.spring.SqlSessionFactoryBean
import org.mybatis.spring.mapper.MapperScannerConfigurer

beans = {

sqlSessionFactory(SqlSessionFactoryBean) {
dataSource = ref("dataSource")
mapperLocations = "classpath:com/app/mappers/**/*.xml"
}

mapperScannerConfigurer(MapperScannerConfigurer) {
basePackage = "com.app.mappers"
}
}

56
Basics

Basics
Example code is available on github.com/vaadin-on-grails/mybatis.

This article shows how to work with MyBatis in Groovy application. We will fetch data from
database and show them on UI.

Step 1
Create Item class that will represent a database entity. This class will be used by MyBatis
as a data transfare object. MyBatis will automatically fetch values from database in to an
instance of Item class.

package com.app.mappers

class Item {

Long id
String label
}

Step 2
Create mapper interface for Item class. Then this mapper will be referenced from XML
mapping file.

package com.app.mappers

interface ItemMapper {

Item findById(Long id)


}

Step 3
Create src/groovy/com/app/mappers/ItemMapper.xml XML mapper file and define SQL query
that will be executed when findById method is called.

57
Basics

<?xml version="1.0" encoding="UTF-8" ?>


<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/m
ybatis-3-mapper.dtd">

<mapper namespace="com.app.mappers.ItemMapper">
<select id="findById" resultType="com.app.mappers.Item">
select * from Item where id = #{id}
</select>
</mapper>

Step 4
To try out whether MyBatis is working, create Item database table and insert there a new
record. So, we can fetch it later in Vaadin UI.

import javax.sql.DataSource
import java.sql.Statement

class BootStrap {

DataSource dataSource

def init = { servletContext ->

Statement statement = dataSource.getConnection().createStatement()

statement.execute("CREATE TABLE Item (id INTEGER NOT NULL, label VARCHAR(255))"


)
statement.execute("INSERT INTO Item (id, label) VALUES (1, 'Sample')")

statement.close()
}

def destroy = {
}
}

Step 5
Here is an example of how to get the mapper and fetch values from database. Get the bean
from the context Grails.get(ItemMapper) and call the method findById(1) .

ItemMapper implementation is provided by mybatis-spring.

58
Basics

package app

import com.app.mappers.Item
import com.app.mappers.ItemMapper
import com.vaadin.grails.Grails
import com.vaadin.server.VaadinRequest
import com.vaadin.ui.Label
import com.vaadin.ui.UI
import com.vaadin.ui.VerticalLayout

class MyUI extends UI {

@Override
protected void init(VaadinRequest request) {

VerticalLayout layout = new VerticalLayout()

ItemMapper itemMapper = Grails.get(ItemMapper)


Item item = itemMapper.findById(1)

Label label = new Label(item.label)


layout.addComponent(label)

setContent(layout)
}
}

When grails run-app is executed the application is started, a value Sample is fetched from
database and displayed in the web browser.

59
JdbcTemplate

JdbcTemplate
JdbcTemplate provides simple way to execute SQL queries.

It can prevent your code from SQL injection. You can also provide mappers that will map
result set to your domain classes.

60
Create Beans

Create Beans
Example code is available on github.com/vaadin-on-grails/jdbc-template.

In this article, we will show how to define beans in order to start working with spring-jdbc.

Step 1
Add dependency to spring-jdbc into BuildConfig.groovy .

dependencies {
compile 'org.springframework:spring-jdbc:4.0.6.RELEASE'
}

Step 2
We can use JdbcTemplate to directly execute SQL queries, but if there will be inputs from
users, we have to use ? as a parameter placeholder or rather use
NamedParameterJdbcTemplate to prevent SQL injection.

import org.springframework.jdbc.core.JdbcTemplate
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate

beans = {

jdbcTemplate(JdbcTemplate, ref('dataSource'))

namedJdbcTemplate(NamedParameterJdbcTemplate, ref('dataSource'))
}

61
Usage

Usage
Example code is available on github.com/vaadin-on-grails/jdbc-template.

This article shows a few ways how to use JDBC template by Spring.

JdbcTemplate with parameters


The default way how to use JdbcTemplate with parameters.

JdbcTemplate jdbcTemplate = Grails.get(JdbcTemplate)

Object[] args = new Object[1]


args[0] = 1

int[] argsTypes = new int[1]


argsTypes[0] = Types.INTEGER

Map userFromDb = jdbcTemplate.queryForMap("SELECT * FROM User WHERE id=?", args, argsT


ypes)

String firstName = userFromDb.get('first_name')


layout.addComponent(new Label(firstName))

NamedParameterJdbcTemplate with parameters


Named parameters are more readable form of passing parameters into a query.

NamedParameterJdbcTemplate namedJdbcTemplate = Grails.get(NamedParameterJdbcTemplate)

Map params = [id: 1]

List<Map> usersX = namedJdbcTemplate.queryForList("SELECT * FROM User WHERE id=:id", p


arams)

usersX.each {
String firstName = it.get('first_name')
layout.addComponent(new Label(firstName))
}

If you use jOOQ for SQL string construction, there is a comfortable way to get named
parameters as a map.

62
Usage

SelectSelectStep select = ...


Map<String, Object> getParams() {
Map params = select.params.collectEntries { String key, Param value ->
[(key): value.value]
}
return params
}

NamedParameterJdbcTemplate with parameters and


RowMapper
Create a row mapper that will map result of a query to a domain object.

class UserRowMapper implements RowMapper {

@Override
Object mapRow(ResultSet rs, int rowNum) throws SQLException {
return new User(firstName: rs.getString('first_name'))
}
}

Now we can give UserRowMapper to named JDBC template and it will map the result of the
query into a new instance of User class.

NamedParameterJdbcTemplate namedJdbcTemplate = Grails.get(NamedParameterJdbcTemplate)

Map params = [id: 1]


UserRowMapper mapper = new UserRowMapper()

User usersY = namedJdbcTemplate.queryForObject("SELECT * FROM User WHERE id=:id", para


ms, mapper)

layout.addComponent(new Label(usersY.firstName))

Use BeanPropertyRowMapper in case your domain model matches name of columns in


a database table. Then you do not have to create mappers and data from your queries
will automatically transfered to instance of a domain class.

63
Clean Up With Alternatives

Clean Up With Alternatives


With alternative database frameworks, like Groovy Sql, MyBatis, JdbcTemplate, we do not
need some GORM libraries, like hibernate, let's remove them and maybe exclude some
others.

Before you start excluding and removing dependencies, let's run grails dependency-report
compile command to see what libraries are loaded for compile scope.

Step 1
Remove runtime ":hibernate4:4.x" or runtime ":hibernate:3.x" from
BuildConfig.groovy .

Step 2
Add exclude for grails-plugin-databinding in BuildConfig.groovy .

grails.project.dependency.resolution = {
inherits("global") {
'grails-plugin-databinding'
}

64
Architecture

Architecture
This chapter will show a way to architecture your Vaadin application despite you might
compose your application in various ways using different design patterns.

The reason of this chapter is to show how to create testable Vaadin application following
common patterns.

65
Model View Presenter

Model View Presenter


Example code is available on github.com/vaadin-on-grails/model-view-presenter.

This article shows an example of Model View Presenter implementation. The basic idea is to
show a way to split work with domain and service layer and UI view layer, not mixing all
together.

Martin Fowler wrote great article worth reading about UI patterns.

What are the roles of MVP.

Model represents database entities and provide way to manipulate with them.
View displays UI components and has no context of how the database is used to fetch
data.
Presenter connect Model and View together, while only the presenter has the right to
touch Model.

This example is intentionally simplified to easier understing of MVP implementation. We will


create application that displays user name fetched from database.

Step 1
Create domain model class for user entity. Run grails create-domain-class app.model.User
command to create User class.

package app.model

class User {

String firstname
String surname

String email

static constraints = {
}
}

Step 2
Now create service, by running grails create-service app.model.UserService command,
that will be used to manipulate with User domain object.

66
Model View Presenter

package app.model

import grails.transaction.Transactional

@Transactional
class UserService {

User findByEmail(String email) {


return User.findByEmail(email)
}
}

Step 3
Persist one user in BootStrap.groovy to have a database record in database. We will use it
later.

import app.model.User

class BootStrap {

def init = { servletContext ->

User john = new User()


john.firstname = 'John'
john.surname = 'Lustig'
john.email = 'john@app.com'
john.save()

}
def destroy = {
}
}

Step 4
Now create a view to display details about user. We will never do any database operations in
UserView class but instead we provide methods to populate values in UI.

67
Model View Presenter

package app.view

import app.model.User
import com.vaadin.navigator.View
import com.vaadin.navigator.ViewChangeListener
import com.vaadin.ui.Label
import com.vaadin.ui.VerticalLayout

class UserView extends VerticalLayout implements View {

UserView() {
setMargin(true)
}

@Override
void enter(ViewChangeListener.ViewChangeEvent event) {
}

void showUserDetail(User user) {


addComponent(new Label(user.firstname))
addComponent(new Label(user.surname))
}
}

We could create an interface for UserView that will define all mandatory methods for
that view. That would easier mocking of UserView in test and could give a way to make
multiple implementations of user view.

Step 5
Now we create presenter for UserView . It will have reference to UserView and
UserService .

The presenter will be responsible to add a view into navigator and to fetch values using
UserService .

68
Model View Presenter

package app.presenter

import app.model.User
import app.model.UserService
import app.view.UserView
import com.vaadin.grails.Grails
import com.vaadin.ui.UI

class UserPresenter {

public static final String USER = 'user'

UserView view

UserPresenter() {
}

void initialize() {
view = new UserView()
UI.current.navigator.addView(USER, view)
}

void navigateTo() {
UI.current.navigator.navigateTo(USER)

UserService model = Grails.get(UserService)


User user = model.findByEmail('john@app.com')
view.showUserDetail(user)
}
}

Step 6
Now we use UserPresenter in our UI class to display user details.

69
Model View Presenter

package app

import app.presenter.UserPresenter
import com.vaadin.navigator.Navigator
import com.vaadin.server.VaadinRequest
import com.vaadin.ui.UI

class MyUI extends UI {

@Override
protected void init(VaadinRequest r) {

Navigator navigator = new Navigator(this, this)


setNavigator(navigator)

new UserPresenter().initialize().navigate()
}
}

Now we can run the application and user will appear in the browser.

70
Spring Autowiring

Spring Autowiring
Managing Vaadin classes in Spring context has been added recently. Please report all
the issues you find.

Recently we have added support for autowiring. That makes Grails.get() method, which
returns beans from application context, useless.

This chapter shows how to configure and create sample application using new annotations
@VaadinUI and @VaadinView .

71
Create Simple Application

Create Simple Application


Example code is available on github.com/vaadin-on-grails/spring-autowiring-basics.

In this tutorial, we will create Vaadin application where we can use @Autowired annotation.

Step 1
We need to say the plugin that we want to do annotation based URL mapping. Comment out
mapping from VaadinConfig.groovy to do that.

vaadin {
// mapping = [
// "/*": "app.MyUI"
// ]
}

Step 2
Now we will create a dummy service ItemService that we will autowire in Vaadin code.

package app

import grails.transaction.Transactional

@Transactional
class ItemService {

String serviceMethod() {
return 'Value from service'
}
}

Step 3
Use @VaadinUI annotation to map your UI class to URL.

72
Create Simple Application

package app

import com.vaadin.grails.ui.VaadinUI
import com.vaadin.server.VaadinRequest
import com.vaadin.ui.Label
import com.vaadin.ui.UI
import com.vaadin.ui.VerticalLayout
import org.springframework.beans.factory.annotation.Autowired

@VaadinUI(path = '/')
class MyUI extends UI {

@Autowired
ItemService itemService

@Override
protected void init(VaadinRequest r) {

VerticalLayout layout = new VerticalLayout()


layout.setMargin(true)

String homeLabel = itemService.serviceMethod()

Label label = new Label(homeLabel)


layout.addComponent(label)

setContent(layout)
}
}

That is all, now you can run the application and ItemService will be autowired.

Step 5
Run the application grails run-app and open http://localhost:8080/spring-autowiring-basics
in a browser.

73
Application With Navigator

Application With Navigator


Example code is available on github.com/vaadin-on-grails/spring-autowiring-navigator.

In this tutorial we will show how to initialize Navigator and how to implement View .

The first two steps are the same as for the previous 'Create Simple Application'.

Step 1
We need to say the plugin that we want to do annotation based URL mapping. Comment out
mapping from VaadinConfig.groovy to do that.

vaadin {
// mapping = [
// "/*": "app.MyUI"
// ]
}

Step 2
Now we will create a dummy service ItemService that we will autowire in Vaadin code.

package app

import grails.transaction.Transactional

@Transactional
class ItemService {

String serviceMethod() {
return 'Value from service'
}
}

Step 3
In this step we will do the following things:

Create new UI that extends DefaulUI


Use @VaadinUI annotation to do URL mapping for MyUI
Call super.init(r) method that will initialize the navigator

74
Application With Navigator

After the point mentioned above are done, we can use Views class to open a view.
Continue to the next step to learn how views are registered using @VaadinUI annotation.

package app

import com.vaadin.grails.navigator.Views
import com.vaadin.grails.ui.DefaultUI
import com.vaadin.grails.ui.VaadinUI
import com.vaadin.server.VaadinRequest

@VaadinUI(path = '/')
class MyUI extends DefaultUI {

@Override
protected void init(VaadinRequest r) {
super.init(r)

Views.enter(ItemView)
}
}

Step 4
Before we use Views.enter(View) method we need to tell the pluging where are the views
and what is the URL path to them.

Add @VaadinUI annotation to every view that should be accesible by Views.enter method.

75
Application With Navigator

package app

import com.vaadin.grails.navigator.VaadinView
import com.vaadin.navigator.View
import com.vaadin.navigator.ViewChangeListener
import com.vaadin.ui.Label
import com.vaadin.ui.VerticalLayout
import org.springframework.beans.factory.annotation.Autowired

@VaadinView(path = "item")
class ItemView extends VerticalLayout implements View {

@Autowired
ItemService itemService

@Override
void enter(ViewChangeListener.ViewChangeEvent e) {
setMargin(true)

String label = itemService.serviceMethod()


addComponent(new Label(label))
}
}

Step 5
Run the application grails run-app and open http://localhost:8080/spring-autowiring-
navigator in a browser.

76
UI

UI
This chapter shows how to do basic operations with Vaadin UI components in Grails.

77
Re-using GORM Validations

Re-using GORM Validations


Example code is available on github.com/vaadin-on-grails/gorm-validations.

When we define validation rules, constraints, in domain class we probably do not want to
repeat that validation rules in Vaadin code. We would rather re-use it in Vaadin code for
validation of input fields.

We can get constraints from a domain class and use it. Because Vaadin provides many
validator, we can use them and fill it with what we have defined in constraints for a domain
class.

Assume we have a product, domain class, that has a name. The product name needs to
fulfil certiain validation rules. The name cannot be blank, it has too be more than 2
characters long and maximum lenght is 255.

class Product {

String name

static constraints = {
name(blank: false, minSize: 2, maxSize: 255)
}
}

Then we can get the constraints in Vaadin code and use it as parameters for validation.

78
Re-using GORM Validations

Product product = new Product()


product.name = "iPhone 7"
product.save()

FormLayout form = new FormLayout()


FieldGroup binder = new FieldGroup(new BeanItem(product))

TextField txnName = binder.buildAndBind("Name", "name")


txnName.setNullRepresentation("")

def constraints = Product.constraints


def name = constraints.name

int minSize = name.minSize


int maxSize = name.maxSize
boolean blank = name.blank

StringLengthValidator validator = new StringLengthValidator("Validation failed", minSi


ze, maxSize, blank)
txnName.addValidator(validator)

form.addComponent(txnName)

79
Async Push

Async Push
Example code is available on github.com/vaadin-on-grails/async-push.

Push has been added in Vaadin plugin version 7.3.0.1. Make sure you have this, or later,
version of the plugin.

Step 1
Enable anyc in VaadinConfig.groovy.

asyncSupported = true

Step 2
In order to demonstrate Vaadin push, we will create a view that will create a label that will
have initial value that will be overriden by a thread. The thread will wait one second and then
set other text into the label. Let's say, that we replace waiting by a call to external system,
where we expect a delay.

For pusing another label, we create Pusher thread that will change text of the label.

80
Async Push

package app.views.push

import app.MyUI
import com.vaadin.navigator.View
import com.vaadin.navigator.ViewChangeListener
import com.vaadin.ui.Label
import com.vaadin.ui.VerticalLayout

class PushView extends VerticalLayout implements View {

static final String VIEW_NAME = "push"

Label loadingText = new Label("Loading UI, please wait...");

@Override
void enter(ViewChangeListener.ViewChangeEvent viewChangeEvent) {
loadingText.setSizeUndefined();
addComponent(loadingText);
new Pusher().start();
}

class Pusher extends Thread {


@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}

MyUI.current.access(new Runnable() {
@Override
public void run() {
loadingText.setValue("Done!")
}
});
}
}
}

Step 3
Add Push annotation on your UI class.

81
Async Push

package app

import app.views.push.PushView
import com.vaadin.annotations.Push
import com.vaadin.navigator.Navigator
import com.vaadin.server.VaadinRequest
import com.vaadin.ui.UI

@Push
class MyUI extends UI {

@Override
protected void init(VaadinRequest vaadinRequest) {

Navigator navigator = new Navigator(this, this)


navigator.addView(PushView.VIEW_NAME, PushView)

navigator.navigateTo(PushView.VIEW_NAME)
}
}

82
Multiple application

Multiple UI application
Example code is available on github.com/vaadin-on-grails/multiple-ui-application.

In grails-app/conf/VaadinConfig.groovy , we can configure URL mapping to Vaadin UI


classes. We can define multiple UIs to be accessible from one Grails application.

In this article we will create two new UIs that we will show under different URLs.

Step 1
ClientUI will be available on http://localhost:8080/client.

package app

import com.vaadin.server.VaadinRequest
import com.vaadin.ui.Label
import com.vaadin.ui.UI
import com.vaadin.ui.VerticalLayout

class ClientUI extends UI {

protected void init(VaadinRequest request) {


VerticalLayout layout = new VerticalLayout()
layout.setMargin(true)

Label label = new Label("Client")


layout.addComponent(label)

setContent(layout)
}
}

And AdminUI that will be mapped to http://localhost:8080/server

83
Multiple application

package app

import com.vaadin.server.VaadinRequest
import com.vaadin.ui.Label
import com.vaadin.ui.UI
import com.vaadin.ui.VerticalLayout

class AdminUI extends UI {

protected void init(VaadinRequest request) {


VerticalLayout layout = new VerticalLayout()
layout.setMargin(true)

Label label = new Label("Admin")


layout.addComponent(label)

setContent(layout)
}
}

Step 2
Open VaadinConfig.groovy and change the mapping, so the mapping points to the new UIs.

mapping = [
"/client/*": "app.ClientUI",
"/admin/*": "app.AdminUI"
]

Now we can start up the application and access both URLs to see each is mapped to
different UI class.

84
SASS Compilation

SASS Compilation
Example code is available on github.com/vaadin-on-grails/sass-compilation.

SASS compilation will happen automatically, during runtime, in all environments except of
production environment. This is handy, because we do not have to recompile SASS files
after each change.

If automatic compilation of SASS is not happening, make sure productionMode is set to


false for development environment, in VaadinConfig.groovy .

Because automatic re-compilation shoud not happen in production, because of performance,


Vaadin plugin will compile SASS files for you when you build the production war file, as part
of grails prod war command.

Let's create an example theme that will extend new Valo theme provided by Vaadin 7.3.

Step 1
Create new folders /VAADIN/themes/mytheme in web-app . Then we create new SASS file
named styles.scss in web-app/VAADIN/themes/mytheme folder.

$v-app-background-color: hsl(71, 100%, 87%);

@import "../valo/valo";

.mytheme {
@include valo;
}

Step 2
Add the name of a theme to VaadinConfig.groovy , in our example mytheme .

We can also define Vaadin version for SASS compilation by defining sassCompile variable.
If we do not define Vaadin version a default version will be provided by Vaadin plugin.

vaadin {
themes = ['mytheme']
sassCompile = '7.3.0'
}

85
SASS Compilation

Then styles.scss gets compiled into styles.css when we run grails prod war
command.

This configuration is required for SASS compilation that is executed as part of grails
prod war command.

Step 3
The last step is to let Vaadin know what is the active theme. Add @Theme annotation with
name of our custom theme on our UI class.

package app

import com.vaadin.annotations.Theme
import com.vaadin.grails.Grails
import com.vaadin.server.VaadinRequest
import com.vaadin.ui.Button
import com.vaadin.ui.UI
import com.vaadin.ui.VerticalLayout

@Theme("mytheme")
class MyUI extends UI {

@Override
protected void init(VaadinRequest r) {

VerticalLayout layout = new VerticalLayout()


layout.setMargin(true)

String homeLabel = Grails.i18n("default.home.label")


Button label = new Button(homeLabel)
layout.addComponent(label)

setContent(layout)
}
}

Step 4
Run the app and notice the changed background and the button, which is using Valo theme.

When you add ?debug as a parameter into URL, you wil see what theme is used as
well as other debug logs.

86
SASS Compilation

87
Widgetset Compilation

Widgetset Compilation
Example code is available on github.com/vaadin-on-grails/widgetset-compilation.

This article shows how to recompile widgetset when we add an add-on that requires
widgetset recompilation.

We will demonstrate how to add tokenfield. But you can use this tutorial in the same way for
the other add-ons as well.

Step 1
Add the depedencies to add-ons in BuildConfig.groovy .

repositories {
inherits true

grailsPlugins()
grailsHome()
mavenLocal()
grailsCentral()
mavenCentral()

mavenRepo "http://maven.vaadin.com/vaadin-addons"
}

dependencies {
compile "org.vaadin.addons:tokenfield:7.0.1"
}

Step 2
Create src/java/app/widgetset.gwt.xml file with widgetset references.

<!DOCTYPE
module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 2.0//EN"
"http://google-web-toolkit.googlecode.com/svn/releases/2.0/distro-source/core/src/
gwt-module.dtd">
<module>
<inherits name="org.vaadin.tokenfield.TokenfieldWidgetset"/>
</module>

88
Widgetset Compilation

If you want to add more add-ons, just add more lines with widget sets.

<module>
<inherits name="org.vaadin.tokenfield.TokenfieldWidgetset"/>
<inherits name="org.vaadin.otheraddon1.TheWidgetset"/>
<inherits name="org.vaadin.otheraddon2.TheWidgetset"/>
</module>

Step 3
Add the widgetset reference into VaadinConfig.groovy .

vaadin {

mapping = [
"/*": "app.MyUI"
]

productionMode = false

widgetset = 'app.widgetset'
}

environments {
production {
vaadin {
productionMode = true
}
}
}

We can try to run the application in order to see that the application will not come up. That
will show that widgetset compilation is mandatory.

Step 4
We will add a text field on UI. Use TokenField in order to finish this example.

89
Widgetset Compilation

package app

import com.vaadin.server.VaadinRequest
import com.vaadin.ui.UI
import com.vaadin.ui.VerticalLayout
import org.vaadin.tokenfield.TokenField

class MyUI extends UI {

@Override
protected void init(VaadinRequest r) {

VerticalLayout layout = new VerticalLayout()


layout.setMargin(true)

TokenField f = new TokenField("Add tags")


layout.addComponent(f)

setContent(layout)
}
}

Step 5
Run grails vaadin-compile-widgetset --verbose to recompile the widgetset.

Step 6
After the widgetset compilation is done and you run the application, you will see the
tokenfield component in the browser.

90
Spring Security

Spring Security
Spring Security in pure Grails application, where no Vaadin is involved, is provided by
spring-security-core plugin, because if we work with pure Grails, the controllers are the end
points and we can define security at that level, by adding Spring security annotations. This is
not case for Vaadin application.

In Vaadin applications we use Navigator instead of Grails controllers or we render different


UI components based on user's roles. In this chapter we will explore way to do using Spring
security framework.

91
Spring Security Dependency

Spring Security Dependency


Add dependency to spring-security-core into BuildConfig.groovy . We need to exclude
several libraries to get it working.

dependencies {
String springSecurityVersion = '3.2.5.RELEASE'

compile "org.springframework.security:spring-security-core:$springSecurityVersion"
, {
excludes 'aopalliance', 'aspectjrt', 'cglib-nodep', 'commons-collections', 'co
mmons-logging', 'ehcache', 'fest-assert', 'hsqldb', 'jcl-over-slf4j', 'jsr250-api', 'j
unit', 'logback-classic', 'mockito-core', 'powermock-api-mockito', 'powermock-api-supp
ort', 'powermock-core', 'powermock-module-junit4', 'powermock-module-junit4-common', '
powermock-reflect', 'spring-aop', 'spring-beans', 'spring-context', 'spring-core', 'sp
ring-expression', 'spring-jdbc', 'spring-test', 'spring-tx'
}
}

Get the latest version from Grails Spring security plugin.

Follow the next chapters to learn how to setup Spring Security in your project.

92
Spring Security Basics

Spring Security Basics


Example code is available on github.com/vaadin-on-grails/spring-security-basics.

We will create basic classes that are required to work with Spring in Grails application.

The first step before you continue with this tutorial, is to enable OSIV, as described in Open
Session In View chapter to allow lazy loading in GORM. If you do not want OSIV in your
project, set lazy to false on roles collection in User class.

Step 1
Create Role domain class that will represent a role assigned to a user. For example, a user
can have multiple roles, like admin, client and so on.

grails create-domain-class app.security.Role

package app.security

class Role {

String name

static constraints = {
}
}

Step 2
Create User domain class that will represent your user.

grails create-domain-class app.security.User

Then implement UserDetails interface from Spring Security and provide all the required
fields.

93
Spring Security Basics

package app.security

import org.springframework.security.core.GrantedAuthority
import org.springframework.security.core.authority.SimpleGrantedAuthority
import org.springframework.security.core.userdetails.UserDetails

class User implements UserDetails {

String username
String password
boolean accountNonExpired
boolean accountNonLocked
boolean credentialsNonExpired
boolean enabled

static hasMany = [roles: Role]

static constraints = {
}

@Override
Collection<? extends GrantedAuthority> getAuthorities() {
println roles
return roles.collect { Role authority ->
new SimpleGrantedAuthority(authority.name)
}
}

@Override
boolean isAccountNonExpired() {
return accountNonExpired
}

@Override
boolean isAccountNonLocked() {
return accountNonLocked
}

@Override
boolean isCredentialsNonExpired() {
return credentialsNonExpired
}

@Override
boolean isEnabled() {
return enabled
}
}

Step 3

94
Spring Security Basics

Because we need a user with some roles during development, create a new user with few
roles in BootStrap .

import app.security.Role
import app.security.User

class BootStrap {

def init = { servletContext ->


Role adminRole = new Role(name: 'ADMIN')
adminRole.save(failOnError: true)
Role userRole= new Role(name: 'USER')
userRole.save(failOnError: true)

User user = new User()


user.username = "john"
user.password = "john"
user.enabled = true
user.accountNonExpired = true
user.accountNonLocked= true
user.credentialsNonExpired = true
user.roles = []
user.roles << userRole
user.roles << adminRole
user.save(failOnError: true)
}
def destroy = {
}
}

Step 4
Now create UserService that will search for user by name and password in the database.

grails create-service app.security.UserService

We will use this to login the users.

95
Spring Security Basics

package app.security

import grails.transaction.Transactional

@Transactional
class UserService {

User findByUsernameAndPassword(String username, String password) {


User user = User.findByUsernameAndPassword(username, password)
return user
}
}

Step 5
Create your implementation of AuthenticationManager interface in src/groovy that will
authentificate a user.

package app.security

import org.springframework.beans.factory.annotation.Autowired
import org.springframework.security.authentication.AuthenticationManager
import org.springframework.security.authentication.BadCredentialsException
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
import org.springframework.security.core.Authentication
import org.springframework.security.core.AuthenticationException
import org.springframework.security.core.GrantedAuthority

class AuthManager implements AuthenticationManager {

@Autowired
private UserService userService

public Authentication authenticate(Authentication auth) throws AuthenticationExcep


tion {
String username = (String) auth.principal
String password = (String) auth.credentials

User user = userService.findByUsernameAndPassword(username, password)


if (user != null) {
Collection<? extends GrantedAuthority> authorities = user.authorities
return new UsernamePasswordAuthenticationToken(username, password, authori
ties)
}

throw new BadCredentialsException("Bad Credentials")


}
}

96
Spring Security Basics

Open grails-app/conf/spring/resources.groovy and define a new bean. We have to have


AuthManager under Spring controll otherwise autowired would not be done automatically.

import app.security.AuthManager

beans = {
authenticationManager(AuthManager)
}

Step 6
This can be done in many ways, but let's create a helper class Auth that will encapsulate
authentification.

package app.security

import com.vaadin.grails.Grails
import org.springframework.security.authentication.AuthenticationManager
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
import org.springframework.security.core.Authentication
import org.springframework.security.core.context.SecurityContextHolder

class Auth {

static Authentication login(String username, String password) {


UsernamePasswordAuthenticationToken request = new UsernamePasswordAuthenticati
onToken(username, password)

AuthenticationManager authenticationManager = Grails.get(AuthenticationManager


)
Authentication result = authenticationManager.authenticate(request)

SecurityContextHolder.context.authentication = result

return result
}
}

We do not have to have the login method defined as static. Instead, we can define a
new bean and autoinject or use Grails.get(Auth) where needed.

97
Secured Navigator

Secured Navigator
Example code is available on github.com/vaadin-on-grails/spring-security-basics.

In this article we will show way how to create Vaadin application with secured views, where a
view will be viewable by certain role.

Step 1
In ViewSecurity class we will store the mapping of a view to user roles. The class will be
also responsible to verify whether a view is accesible by a user.

98
Secured Navigator

package app.security

import com.vaadin.navigator.View
import org.springframework.security.authentication.InternalAuthenticationServiceExcept
ion
import org.springframework.security.core.Authentication
import org.springframework.security.core.GrantedAuthority
import org.springframework.security.core.context.SecurityContextHolder

class ViewSecurity {

private static Map<Class<? extends View>, List<String>> views = [:]

static add(Class<? extends View> view, List<String> roles) {


views.put(view, roles)
}

static boolean isViewAccessible(View view) {

List<String> roles = views.get(view.class)


if (!roles) {
// if roles is null, the access is public (not secured)
return true
}

Authentication authentication = SecurityContextHolder.context.authentication


if (!authentication) {
throw new InternalAuthenticationServiceException('No authentication found
in the context.')
}

List<GrantedAuthority> authorities = authentication.authorities

for (String role : roles) {


boolean isRoleAssigned = role in authorities*.authority
if (isRoleAssigned) {
return true
}
}

return false
}
}

Step 2
We need to hook at event when a view changes, so we can verify whether a user is able to
access a view.

99
Secured Navigator

package app.security

import com.vaadin.navigator.View
import com.vaadin.navigator.ViewChangeListener

class SecuredViewChangeListener implements ViewChangeListener {

@Override
boolean beforeViewChange(ViewChangeListener.ViewChangeEvent event) {
View view = event.newView
boolean isViewAccessible = ViewSecurity.isViewAccessible(view)

return isViewAccessible
}

@Override
void afterViewChange(ViewChangeListener.ViewChangeEvent event) {
}
}

Step 3
Now we will create two views where one will be accesible only by "ADMIN" role.

package app.view.secured

import com.vaadin.navigator.View
import com.vaadin.navigator.ViewChangeListener
import com.vaadin.ui.Label
import com.vaadin.ui.VerticalLayout

class UserDataView extends VerticalLayout implements View {

static final String VIEW_NAME = "secured"

@Override
void enter(ViewChangeListener.ViewChangeEvent event) {
setMargin(true)

addComponent(new Label("Secured content, only after login!"))


}
}

And the second view, LoginView , that will public to everyone.

package app.view.login

import app.security.Auth
import app.view.secured.UserDataView

100
Secured Navigator

import com.vaadin.navigator.View
import com.vaadin.navigator.ViewChangeListener
import com.vaadin.ui.Button
import com.vaadin.ui.TextField
import com.vaadin.ui.VerticalLayout
import org.springframework.security.authentication.BadCredentialsException
import org.springframework.security.core.Authentication
import org.springframework.security.core.GrantedAuthority

import static com.vaadin.ui.UI.getCurrent

class LoginView extends VerticalLayout implements View {

static final String VIEW_NAME = "login"

@Override
void enter(ViewChangeListener.ViewChangeEvent viewChangeEvent) {
TextField txnUsername = new TextField("Username")
TextField txnPassword = new TextField("Password")
Button btnLogin = new Button("Login")

addComponent(txnUsername)
addComponent(txnPassword)
addComponent(btnLogin)

btnLogin.addClickListener(new Button.ClickListener() {

@Override
void buttonClick(Button.ClickEvent clickEvent) {
String username = txnUsername.value
String password = txnPassword.value

try {
Authentication auth = Auth.login(username, password)

List<GrantedAuthority> authorities = auth.authorities


if ('ADMIN' in authorities*.authority) {
current.navigator.navigateTo(UserDataView.VIEW_NAME)
} else {
current.navigator.navigateTo(LoginView.VIEW_NAME)
}

} catch (BadCredentialsException e) {
// TODO: handle error flow
current.navigator.navigateTo(LoginView.VIEW_NAME)
}
}
})
}
}

101
Secured Navigator

Step 4
Now we will create UI class that will initialize Navigator and ViewSecurity .

package app

import app.security.SecuredViewChangeListener
import app.security.ViewSecurity
import app.view.login.LoginView
import app.view.secured.UserDataView
import com.vaadin.annotations.PreserveOnRefresh
import com.vaadin.navigator.Navigator
import com.vaadin.server.VaadinRequest
import com.vaadin.ui.UI
import com.vaadin.ui.VerticalLayout

@PreserveOnRefresh
class MyUI extends UI {

@Override
protected void init(VaadinRequest r) {

VerticalLayout layout = new VerticalLayout()


layout.setMargin(true)

Navigator navigator = new Navigator(this, this)

SecuredViewChangeListener securedViewListener = new SecuredViewChangeListener(


)
navigator.addViewChangeListener(securedViewListener)

navigator.addView(LoginView.VIEW_NAME, LoginView)
navigator.addView(UserDataView.VIEW_NAME, UserDataView)

ViewSecurity.add(LoginView, null)
ViewSecurity.add(UserDataView, ['ADMIN'])

navigator.navigateTo(LoginView.VIEW_NAME)

setContent(layout)
}
}

Step 5
Run application grails run-app and fill in username and password.

102
Secured Navigator

Click on Login button and you will be authentificated and redirected to secured view.

103
Localization

Localization
This chapter shows way how to localize Vaadin application in Grails.

104
Localization Basics

Localization Basics
Example code is available on github.com/vaadin-on-grails/localization-basics.

Localization property files are stored in grails-app/i18n folder.

In order to access the values in from the localized property files, use Grails.i18n()
method. Grails class is provided by the plugin. Here are various ways how to use i18n
method.

import static com.vaadin.grails.Grails.i18n


import static java.util.Locale.ENGLISH

String label = i18n("default.home.label")

String homeEng = i18n("default.home.label", ENGLISH)

Object[] newItemArgs = ["Proper label to be shown"]


String newItem = i18n("default.home.label", newItemArgs)

String newItemEng = i18n("default.home.label", newItemArgs, ENGLISH)

String newItemEngDef = i18n("do.not.exist", newItemArgs, "Default label for {0}", ENGL


ISH)

105
Custom MessageSource

Custom MessageSource
Example code is available on github.com/vaadin-on-grails/custom-messagesource.

We might want to define a custom MessageSource that will return a localized message. If a
message is missing, we might want to log information about missing localization (in logs or
database) or we might want to provide other way to fetch the localized labels.

In this toturial we will show way to load localization from database.

Step 1
Enable OSIV in VaadinConfig.groovy . Add or comment out the following line.

openSessionInViewFilter = 'org.springframework.orm.hibernate4.support.OpenSessionInVie
wFilter'

Step 2
Create new domain object that will hold localization data. Run grails create-domain
app.Message command.

key holds the localization key that we will you in our application to refer a localized

string
value is localized string, for example a label in English

locale defines in what language is value string

package app

class Message {

String key
String value
Locale locale
}

Step 3
Create localized key-value pair for given language in BootStrap.groovy .

106
Custom MessageSource

import app.Message

class BootStrap {

def init = { servletContext ->

Message home = new Message(key: 'home', value: 'Home', locale: Locale.ENGLISH)


home.save(failOnError: true)
}
def destroy = {
}
}

Step 4
Implement a new message source that will use GORM domain object, Message in our case,
to load the localized messages. When a value is not found, we will return the key in
brackets.

107
Custom MessageSource

package app.i18n

import app.Message
import org.codehaus.groovy.grails.context.support.PluginAwareResourceBundleMessageSour
ce
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.context.support.AbstractMessageSource

import java.text.MessageFormat

class JdbcMessageSource extends AbstractMessageSource {

@Autowired
PluginAwareResourceBundleMessageSource messageBundleMessageSource

@Override
protected MessageFormat resolveCode(String code, Locale l) {
Message message = Message.findByKeyAndLocale(code, l)

MessageFormat format
if (message) {
format = new MessageFormat(message.value, message.locale)
} else {
format = messageBundleMessageSource.resolveCode(code, l)
if (!format) {
format = new MessageFormat("[$code]", l)
}
}
return format
}
}

Step 4
Open grails-app/conf/spring/resources.groovy and add a new bean messageSource and
messageBundleMessageSource that we use to get the localization in case the localization is not

found in database.

108
Custom MessageSource

import app.i18n.JdbcMessageSource
import org.codehaus.groovy.grails.context.support.PluginAwareResourceBundleMessageSour
ce

beans = {

messageSource(JdbcMessageSource)

messageBundleMessageSource(PluginAwareResourceBundleMessageSource) {
basenames = "WEB-INF/grails-app/i18n/messages"
}
}

Step 5
Now we can use standard Grails.i18 method to get localized strings.

package app

import com.vaadin.grails.Grails
import com.vaadin.server.VaadinRequest
import com.vaadin.ui.Label
import com.vaadin.ui.UI
import com.vaadin.ui.VerticalLayout

class MyUI extends UI {

@Override
protected void init(VaadinRequest r) {

VerticalLayout layout = new VerticalLayout()


layout.setMargin(true)

Label lbl1 = new Label(Grails.i18n('do.not.exist', Locale.ENGLISH))


layout.addComponent(new Label(lbl1))

Label lbl2 = new Label(Grails.i18n('home', Locale.ENGLISH))


layout.addComponent(new Label(lbl2))

setContent(layout)
}
}

Step 6
Run the application grails run-app and open it in the browser http://localhost:8080/custom-
messagesource. Then we will see the messages in the console.

109
Custom MessageSource

110
REST

REST
This chapter will show way how to add REST API to the same project where a Vaadin
application running.

111
Without using root URL

Without using root URL


Example code is available on github.com/vaadin-on-grails/rest-without-root.

If you need to provide REST API from your application and you do not want to provide that
from other application, there is a way how to do it from Grails even if we run there Vaadin
applications.

First thing if you want to have REST API, do not map any Vaadin UI on /* (root) url. If you
have to use the root, check the next article "Using root URL for Vaadin app".

Step 1
Your mapping should like like this.

mapping = [
"/admin/*": "app.AdminUI",
"/client/*": "app.ClientUI"
]

Step 2
Then, we can add URL mapping into UrlMappings.groovy .

class UrlMappings {
static mappings = {
group "/rest", {
"/$controller/$action?/$id?"()
}
}
}

Step 3
Create a controller grails create-controller app.ItemController and implement some logic
there. For example, fetch some data from database and return it as JSON. In our example,
we will just return a map, with dummy data, as JSON.

112
Without using root URL

package app

import grails.converters.JSON

class ItemController {

def index() {
Map data = ['some': 'data']

return data as JSON


}
}

Step 4
Create two sample Vaadin UIs, so we can verify URL mapping.

package app

import com.vaadin.grails.ui.DefaultUI
import com.vaadin.server.VaadinRequest
import com.vaadin.ui.Label
import com.vaadin.ui.VerticalLayout

class ClientUI extends DefaultUI {

protected void init(VaadinRequest request) {


VerticalLayout layout = new VerticalLayout()
layout.setMargin(true)

Label label = new Label("Client")


layout.addComponent(label)

setContent(layout)
}
}

113
Without using root URL

package app

import com.vaadin.grails.ui.DefaultUI
import com.vaadin.server.VaadinRequest
import com.vaadin.ui.Label
import com.vaadin.ui.VerticalLayout

class AdminUI extends DefaultUI {

protected void init(VaadinRequest request) {


VerticalLayout layout = new VerticalLayout()
layout.setMargin(true)

Label label = new Label("Admin")


layout.addComponent(label)

setContent(layout)
}
}

Step 5
Start up the application and try out different URLs:

http://localhost:8080/rest-without-root/client
http://localhost:8080/rest-without-root/admin
http://localhost:8080/rest-without-root/rest/item/index

114
Using root URL for Vaadin app

Using root URL for Vaadin app


Example code is available on github.com/vaadin-on-grails/rest-with-root.

URL mapping can be done also in way we use / root URL to display Vaadin application. In
this article, we are going to show how to do it.

Step 1
Create mapping in UrlMapping.groovy as follows:

class UrlMappings {

static mappings = {
"/" {
controller = "redirect"
}
// add your URL mapping for controllers
group "/rest", {
"/$controller/$action?/$id?"()
}
}
}

Step 2
Then we need to create the controller that will redirect the request to the Vaadin application.

package app

class RedirectController {

def index() {
redirect(uri: "/app")
}
}

Step 3
Last step is to make sure that VaadinConfig.groovy contains mapping to Vaadin UI class.

115
Using root URL for Vaadin app

vaadin {
mapping = [
"/app/*": "app.MyUI"
]
}

Step 4
Create a controller and implement some logic there. For example, fetch some data from
database and return it as JSON.

package app

class RedirectController {

def index() {
redirect(uri: "/app")
}
}

Step 5
Create two sample Vaadin UI, so we can verify URL mapping.

package app

import com.vaadin.ui.UI
import com.vaadin.ui.VerticalLayout
import com.vaadin.server.VaadinRequest
import com.vaadin.ui.Label
import com.vaadin.grails.Grails

class MyUI extends UI {

@Override
protected void init(VaadinRequest r) {

VerticalLayout layout = new VerticalLayout()


layout.setMargin(true)

String homeLabel = Grails.i18n("default.home.label")


Label label = new Label(homeLabel)
layout.addComponent(label)

setContent(layout)
}
}

116
Using root URL for Vaadin app

Step 6
Start up the application and try out these URLs:

http://localhost:8080/rest-with-root redirects user to application


http://localhost:8080/rest-with-root/rest/item displays JSON response

117
Plugin development

Plugin development
This chapter describes the way you can influence Grails plugin, for example, update Vaadin
version or add more support for Grails or Vaadin.

We will explore how Grails plugin for Vaadin is developed, maintained and also how to add
an enhancement.

118
Github

Github
Vaadin plugin source codes are publicly shared on Github.

First you need to fork and clone the following grails-vaadin-plugin repository.

After you have commited and pushed your changes, which will be described in Development
section, create a pull request back to original Github repository.

When the pull request is merged the authors of the plugin will create a new version.

119
Development

Development
Create a sample Grails application with Vaadin plugin that you will use for plugin
development.

There are two ways to use the plugin in the sample application.

Way 1
Add direct dependency to BuildConfig.groovy. You can add it as the last row there.

grails.plugin.location.'vaadin' = "/Users/john/projects/grails-vaadin7-plugin"

Then all the changes do in Vaadin plugin will become immediatelly available in the sample
application.

Way 2
The second way is to release plugin into local maven repository. Before you do so, you need
to set plugin version to SNAPSHOT.

grails set-version 7.3.0-SNAPSHOT

Then you reference SNAPSHOT version in the sample application. You can do the changes
in Vaadin plugin and release it as a snapshot to your local maven repository.

grails maven-install

It is recommended to test SNAPSHOT version in the sample application everytime


before you create a pull request.

120

You might also like