Loading...

Thursday, April 17, 2014

Grails Goodness Notebook is Published

Today Grails Goodness Notebook is published. This book is an electronic publication with all blog posts about Grails Goodness bundled. The posts are slightly edited and categorized into sections.

The book is published at Leanpub and is available in three formats: PDF, MOBI (for Kindle) and EPUB (for iPad). Updates for the book are free. So when new Grails Goodness blog posts will be added to the book you will get those updates for free.

It is also possible to buy a Goodness Notebooks bundle. This bundle contains the Groovy and Grails Goodness Notebook books.

I hope you will enjoy the book and I will keep it up-to-date with new content when I publish new Grails Goodness blog posts.

Wednesday, April 16, 2014

Grails Goodness: Extending IntegrateWith Command

We can extend the integrate-with command in Grails to generate files for a custom IDE or build system. We must add a _Events.groovy file to our Grails projects and then write an implementation for the eventIntegrateWithStart event. Inside the event we must define a new closure with our code to generate files. The name of the closure must have the following pattern: binding.integrateCustomIdentifier. The value for CustomIdentifier can be used as an argument for the integrate-with command.

Suppose we want to extend integrate-with to generate a simple Sublime Text project file. First we create a template Sublime Text project file where we define folders for a Grails application. We create the folder src/ide-support/sublimetext and add the file grailsProject.sublimetext-project with the following contents:

{
    "folders": [
        {
            "name": "Domain classes",
            "path": "grails-app/domain"
        },
        {
            "name": "Controllers",
            "path": "grails-app/controllers"
        },
        {
            "name": "Taglibs",
            "path": "grails-app/taglib"
        },
        {
            "name": "Views",
            "path": "grails-app/views"
        },
        {
            "name": "Services",
            "path": "grails-app/services"
        },
        {
            "name": "Configuration",
            "path": "grails-app/conf"
        },
        {
            "name": "grails-app/i18n",
            "path": "grails-app/i18n"
        },
        {
            "name": "grails-app/utils",
            "path": "grails-app/utils"
        },
        {
            "name": "grails-app/migrations",
            "path": "grails-app/migrations"
        },
        {
            "name": "web-app",
            "path": "web-app"
        },
        {
            "name": "Scripts",
            "path": "scripts"
        },
        {
            "name": "Sources:groovy",
            "path": "src/groovy"
        },
        {
            "name": "Sources:java",
            "path": "src/java"
        },
        {
            "name": "Tests:integration",
            "path": "test/integration"
        },
        {
            "name": "Tests:unit",
            "path": "test/unit"
        },
        {
            "name": "All files",
            "follow_symlinks": true,
            "path": "."
        }
    ]
}

Next we create the file scripts/_Events.groovy:

includeTargets << grailsScript("_GrailsInit")

eventIntegrateWithStart = {

    // Usage: integrate-with --sublimeText
    binding.integrateSublimeText = {

        // Copy template file.
        ant.copy(todir: basedir) {
            fileset(dir: "src/ide-support/sublimetext/")
        }

        // Move template file to real project file with name of Grails application.
        ant.move(file: "$basedir/grailsProject.sublime-project", 
                 tofile: "$basedir/${grailsAppName}.sublime-project", 
                 overwrite: true)

        grailsConsole.updateStatus "Created SublimeText project file"
    }
}

We are done and can now run the integrate-with command with the new argument sublimeText:

$ grails integrate-with --sublimeText
| Created SublimeText project file.
$

If we open the project in Sublime Text we see our folder structure for a Grails application:

Code written with Grails 2.3.7.

Grails Goodness: Generate Default .gitignore Or .hgignore File

We can use the integrateWith command with Grails to generate for example IDE project files and build system files. We specify via an extra argument the type of files to be generated. We can use this command also to create a .gitignore file with some default settings for files to be ignored in Grails projects.

$ grails integrate-with --git

In the root of our project we have now have a .gitignore file with the following contents:

*.iws
*Db.properties
*Db.script
.settings
stacktrace.log
/*.zip
/plugin.xml
/*.log
/*DB.*
/cobertura.ser
.DS_Store
/target/
/out/
/web-app/plugins
/web-app/WEB-INF/classes
/.link_to_grails_plugins/
/target-eclipse/

If we would use Mercurial then we can generate a .hgignore file with the argument --hg:

$ grails integrate-with --hg

The .hgignore file has the following contents:

syntax: glob
*.iws
*Db.properties
*Db.script
.settings
stacktrace.log
*.zip
plugin.xml
*.log
*DB.*
cobertura.ser
.DS_Store
target/
out/
web-app/plugins
web-app/WEB-INF/classes

Samples written with Grails 2.3.7.

Friday, April 11, 2014

Coloring Different Data Sources in IntelliJ IDEA

The database plugin in IntelliJ IDEA is a useful tool to work with data in databases. As long as we got a JDBC driver to connect to the database we can configure a data source. And then we can run queries, inspect the contents of tables and change data with the database tool window. It is not uncommon to have multiple data sources, for example development and test environment databases, which will have the same tables. When we open the tables or run queries we don't have a visual feedback to see to which data source such a table belongs. To have a visual feedback we can colorize our data source. This means we assign a color to a data source and when we open a table from that data source the tab color in the editor window will have a different color than other tabs or the background color of the data source objects have a color.

To add a color to a data source we must open the database tool window and right click on a data source. We select the option Color Settings... from the popup window:

Next a new dialog opens where we can select a color:

We can make a selection for one of the predefined colors or create a custom color we want to use. Also we can select in the Appearance Settings where in IntelliJ IDEA the colored data source must appear. We click on the OK button to save our settings. We can repeat these steps for other data sources and given them different colors.

Once we have added color to our data source we can see for example in the tabs of our editor window the different colors:

Or when we open the data sources in the database tool window to get a list of all objects in the data source:

Even we open a dialog to see recently changed files we can see the colorized data source objects:

Sample with IntelliJ IDEA 13.1.1

Friday, April 4, 2014

Groovy Goodness: Closure as Writable

In a previous post we learned about the Writable interface and how the GString implementation implements this interface. In Groovy we can also use a closure as an implementation of the Writable interface. The Closure class has the method asWritable() that will return a version of the closure with an implementation of the writeTo() method. The Writer object that is used as an argument for the writeTo() method will be passed as argument to the closure. The asWritable() method also adds a toString() implementation for the closure to return the result of a closure as a String.

In the following code we write a sample make() method. The make() method return a Writable closure. The closure is only executed when the writeTo() or toString() method is invoked.

Writable make(Map binding = [:], Closure template) {
    // Use asWritable() to make the closure
    // implement the Writable interface.
    def writableTemplate = template.asWritable()
    
    // Assing binding map as delegate so we can access
    // the keys of the maps as properties in the 
    // closure context.
    writableTemplate.delegate = binding
    
    // Return closure as Writable.
    writableTemplate
}

// Use toString() of Writable closure.
assert make { Writer out -> out <<  "Hello world!" }.toString() == 'Hello world!'

// Provide data for the binding.
// The closure is not executed when the 
// make method is finished.
final writable = make(user:'mrhaki', { out ->
    out.println "Welcome ${user},"
    out.print "Today on ${new Date(year: 114, month: 3, date: 4).format('dd-MM-yyyy')}, "
    out.println "we have a Groovy party!"
})

// We invoke toString() and now the closure
// is executed.
final result = writable.toString()

assert result == '''Welcome mrhaki,
Today on 04-04-2014, we have a Groovy party!
'''

// Append contents to a file.
// NOTE: The leftShift (<<) operator on File is implemented
// in Groovy to use the File.append() method.
// The append() method creates a new Writer and
// invokes the write() method which 
// is re-implemented in Groovy if the argument
// is a Writable object. Then the writeTo() method
// is invoked:
// Writer.write(Writable) becomes Writable.writeTo(Writer).
// So a lot of Groovy magic allows us to use the following one-liner
// and still the writeTo() method is used on Writable.
new File('welcome.txt') << writable

assert new File('welcome.txt').text == '''Welcome mrhaki,
Today on 04-04-2014, we have a Groovy party!
'''

Code written with Groovy 2.2.2

Groovy Goodness: GString as Writable

The Groovy API has the interface Writable. Classes that implement this interface are capable of writing their selves to a java.io.Writer object. The interface has one method writeTo() where the code is that writes the contents to a given Writer instance. Most implementations will also use the implementation of the writeTo() method in their toString() implementation.

The GString implementation in Groovy also implements the Writable interface. This means we can redirect the GString contents to some Writer instance if we want to. In the following code we use a FileWriter to write the contents of a GString to a file:

def data = [
    new Expando(id: 1, user: 'mrhaki', country: 'The Netherlands'),
    new Expando(id: 2, user: 'hubert', country: 'The Netherlands'),
]

data.each { userData ->
    new File("${userData.id}.txt").withWriter('UTF-8') { fileWriter ->
        // Use writeTo method on GString to save
        // result in a file.
        "User $userData.user lives in $userData.country".writeTo(fileWriter)
    }
}


assert new File('1.txt').text == 'User mrhaki lives in The Netherlands'
assert new File('2.txt').text == 'User hubert lives in The Netherlands'

Code written with Groovy 2.2.2

Thursday, April 3, 2014

Groovy Goodness: Converting Byte Array to Hex String

To convert a byte[] array to a String we can simply use the new String(byte[]) constructor. But if the array contains non-printable bytes we don't get a good representation. In Groovy we can use the method encodeHex() to transform a byte[] array to a hex String value. The byte elements are converted to their hexadecimal equivalents.

final byte[] printable = [109, 114, 104, 97, 107, 105]

// array with non-printable bytes 6, 27 (ACK, ESC)
final byte[] nonprintable = [109, 114, 6, 27, 104, 97, 107, 105]


assert new String(printable) == 'mrhaki'
assert new String(nonprintable) != 'mr  haki'


// encodeHex() returns a Writable
final Writable printableHex = printable.encodeHex()
assert printableHex.toString() == '6d7268616b69'
final nonprintableHex = nonprintable.encodeHex().toString()
assert nonprintableHex == '6d72061b68616b69'


// Convert back
assert nonprintableHex.decodeHex() == nonprintable

Code written with Groovy 2.2.1

Wednesday, March 26, 2014

Grails Goodness: Multiple BootStraps

In Grails we can execute code when the application starts and stops. We just have to write our code in grails-app/conf/BootStrap.groovy. Code that needs to be executed at startup must be written in the closure init. In the destroy closure we can write code that needs be executed when the application stops. But we are not limited to one BootStrap class. We can create multiple BootStrap classes as long as it is placed in the grails-app/conf directory and the name ends with BootStrap.

// File: grails-app/conf/BootStrap.groovy
class BootStrap {
    def init = { servletContext ->
        log.debug("Running init BootStrap")
    }
    def destroy = {
        log.debug("Running destroy BootStrap")
    }
}

And we can create another bootstrap class:

// File: grails-app/conf/SampleBootStrap.groovy
class SampleBootStrap {
    def init = { servletContext ->
        log.debug("Running init SampleBootStrap")
    }
    def destroy = {
        log.debug("Running destroy SampleBootStrap")
    }
}

Code written with Grails 2.3.7.

Wednesday, March 19, 2014

Grails Goodness: Using Groovy SQL

In a previous post we learned how we can use Hibernate native SQL queries in our Grails application. We can also execute custom SQL with Groovy SQL. We must create a new instance of groovy.sql.Sql in our code to execute SQL code. The easiest way is to use a javax.sql.DataSource as a constructor argument for the groovy.sql.Sql class. In a Grails application context we already have a DataSource and we can use it to inject it into our code. We must use the name dataSource to reference the default datasource in a Grails application.

In the following sample we invoke a custom query (for Firebird) using Groovy SQL. Notice we define a property dataSource in the Grails service PersonService and Grails will automatically inject a DataSource instance.

package com.mrhaki.grails

import groovy.sql.Sql
import groovy.sql.GroovyRowResult

class PersonService {

    // Reference to default datasource.
    def dataSource

    List<GroovyRowResult> allPersons(final String searchQuery) {
        final String searchString = "%${searchQuery.toUpperCase()}%"

        final String query = '''\
            select id, name, email 
            from person 
            where upper(email collate UNICODE_CI_AI) like :search
        '''

        // Create new Groovy SQL instance with injected DataSource.
        final Sql sql = new Sql(dataSource)

        final results = sql.rows(query, search: searchString)
        results
    }

}

We can even make the groovy.sql.Sql instance a Spring bean in our Grails application. Then we can inject the Sql instance in for example a Grails service. In grails-app/conf/spring/resources.groovy we define the Sql bean:

// File: grails-app/conf/spring/resources.groovy
beans = {

    // Create Spring bean for Groovy SQL.
    // groovySql is the name of the bean and can be used
    // for injection. 
    groovySql(groovy.sql.Sql, ref('dataSource'))

}

Now we can rewrite our previous sample and use the bean groovySql:

package com.mrhaki.grails

import groovy.sql.GroovyRowResult

class PersonService {

    // Reference to groovySql defined in resources.groovy.
    def groovySql

    List<GroovyRowResult> allPersons(final String searchQuery) {
        final String searchString = "%${searchQuery.toUpperCase()}%"

        final String query = '''\
            select id, name, email 
            from person 
            where upper(email collate UNICODE_CI_AI) like :search
        '''

        // Use groovySql bean to execute the query.
        final results = groovySql.rows(query, search: searchString)
        results
    }

}

Code written with Grails 2.3.7.

Tuesday, March 18, 2014

Grails Goodness: Using Hibernate Native SQL Queries

Sometimes we want to use Hibernate native SQL in our code. For example we might need to invoke a selectable stored procedure, we cannot invoke in another way. To invoke a native SQL query we use the method createSQLQuery() which is available from the Hibernate session object. In our Grails code we must then first get access to the current Hibernate session. Luckily we only have to inject the sessionFactory bean in our Grails service or controller. To get the current session we invoke the getCurrentSession() method and we are ready to execute a native SQL query. The query itself is defined as a String value and we can use placeholders for variables, just like with other Hibernate queries.

In the following sample we create a new Grails service and use a Hibernate native SQL query to execute a selectable stored procedure with the name organisation_breadcrumbs. This stored procedure takes one argument startId and will return a list of results with an id, name and level column.

// File: grails-app/services/com/mrhaki/grails/OrganisationService.groovy
package com.mrhaki.grails

import com.mrhaki.grails.Organisation

class OrganisationService {

    // Auto inject SessionFactory we can use
    // to get the current Hibernate session.
    def sessionFactory

    List<Organisation> breadcrumbs(final Long startOrganisationId) {

        // Get the current Hiberante session.
        final session = sessionFactory.currentSession

        // Query string with :startId as parameter placeholder.
        final String query = 'select id, name, level from organisation_breadcrumbs(:startId) order by level desc'

        // Create native SQL query.
        final sqlQuery = session.createSQLQuery(query)

        // Use Groovy with() method to invoke multiple methods
        // on the sqlQuery object.
        final results = sqlQuery.with {
            // Set domain class as entity. 
            // Properties in domain class id, name, level will
            // be automatically filled.
            addEntity(Organisation)

            // Set value for parameter startId.
            setLong('startId', startOrganisationId)

            // Get all results.
            list()
        }

        results
    }

}

In the sample code we use the addEntity() method to map the query results to the domain class Organisation. To transform the results from a query to other objects we can use the setResultTransformer() method. Hibernate (and therefore Grails if we use the Hibernate plugin) already has a set of transformers we can use. For example with the org.hibernate.transform.AliasToEntityMapResultTransformer each result row is transformed into a Map where the column aliases are the keys of the map.

// File: grails-app/services/com/mrhaki/grails/OrganisationService.groovy
package com.mrhaki.grails

import org.hibernate.transform.AliasToEntityMapResultTransformer

class OrganisationService {

    def sessionFactory

    List<Map<String,Object>> breadcrumbs(final Long startOrganisationId) {
        final session = sessionFactory.currentSession

        final String query = 'select id, name, level from organisation_breadcrumbs(:startId) order by level desc'

        final sqlQuery = session.createSQLQuery(query)

        final results = sqlQuery.with {
            // Assign result transformer.
            // This transformer will map columns to keys in a map for each row.
            resultTransformer = AliasToEntityMapResultTransformer.INSTANCE             

            setLong('startId', startOrganisationId)

            list()
        }

        results
    }

}

Finally we can execute a native SQL query and handle the raw results ourselves using the Groovy Collection API enhancements. The result of the list() method is a List of Object[] objects. In the following sample we use Groovy syntax to handle the results:

// File: grails-app/services/com/mrhaki/grails/OrganisationService.groovy
package com.mrhaki.grails

class OrganisationService {

    def sessionFactory

    List<Map<String,String>> breadcrumbs(final Long startOrganisationId) {
        final session = sessionFactory.currentSession

        final String query = 'select id, name, level from organisation_breadcrumbs(:startId) order by level desc'

        final sqlQuery = session.createSQLQuery(query)

        final queryResults = sqlQuery.with {
            setLong('startId', startOrganisationId)
            list()
        }

        // Transform resulting rows to a map with key organisationName.
        final results = queryResults.collect { resultRow ->
            [organisationName: resultRow[1]]
        }

        // Or to only get a list of names.
        //final List<String> names = queryResults.collect { it[1] }

        results
    }

}

Code written with Grails 2.3.7.