Loading...

Saturday, May 29, 2010

Gradle Goodness: Use gradlew for Easy Gradle Execution

Gradle is a great build language. To use gradle for our project we can download the Gradle distribution and install it on our machine. But maybe we want to share our project with other people that don't have Gradle installed. Or suppose we use a continuous integration server without native Gradle support, but with support to run command-line commands. Then we can use the Gradle wrapper. The wrapper is responsible for downloading the Gradle distribution and making it available for our project.

To enable the Gradle wrapper for our project we first add a new task to our build.gradle:

// File: build.gradle
task createWrapper(type: Wrapper) {
    gradleVersion = '0.9-preview-1'
}

Next we run $ gradle createWrapper and when the process is finished we take a look at the project directory and see the following new files:

gradle-wrapper.jar
gradle-wrapper.properties
gradlew
gradlew.bat

Now we only have to distribute this files with our project. Now anyone can run $ gradlew to execute the tasks defined in the Gradle build file. If Gradle hasn't been installed yet, it will be downloaded and installed for the user and the task is executed!

More information is available in the Gradle User Guide.

Friday, May 28, 2010

Groovy Goodness: Use GrabResolver for Custom Repositories

In Groovy we can use the @Grab annotation to define dependencies and automatically download them from public repositories. But maybe we have created our own package and we want to use it in our Groovy script. Our own package is deployed to a customer Maven 2 compatible repository with the url http://customserver/repo, so it is not available to the general public. We can use @GrabResolver to add this repository as a source to look for dependencies in our script. In the following sample code we assume the module groovy-samples, version 1.0 is deployed in the repository accessible via http://customserver/repo:

@GrabResolver(name='custom', root='http://customserver/repo', m2Compatible='true')
@Grab('com.mrhaki:groovy-samples:1.0')
import com.mrhaki.groovy.Sample

def s = new Sample()
s.justToShowGrabResolver()  // Just a sample

Wednesday, May 26, 2010

Groovy Goodness: Use Collect with Initial Collection Value

The collect() method in Groovy can be used to iterate over collections and transform each element of the collection. The transformation is defined in as a closure and is passed to the collect() method. But we can also add an initial collection to which the transformed elements are added.

// Collect without 
// initial collection.
assert [0,2,4,6] == (0..3).collect { it * 2 }
assert ['Groovy', 'Grails'] == [lang: 'Groovy', framework: 'Grails'].collect { it.value }

// Collect with initial collection argument.
assert [0, 1, 2, 3] == [2, 3].collect([0, 1]) { it }
assert [0, 3, 6, 9] == [2, 3].collect([0, 3], { it * 3})
assert ['Gradle', 'groovy', 'grails'] == ['Groovy', 'Grails'].collect(['Gradle']) { it.toLowerCase() }
assert ['m','r','h','a','k','i'] == [4, -3, 7, 5].collect(['m', 'r']) { (it + 100) as char }

Tuesday, May 25, 2010

Griffon Goodness: Getting the Current Running Mode

A Griffon application can run as standalone application, applet or webstart application. We can access the current running mode of our application from the RunMode class. The following sample view shows how we can access the current running mode with RunMode.current:

import java.awt.FlowLayout
import griffon.util.RunMode

application(title:'Sample to show RunMode.current',
  pack:true,
  locationByPlatform:true,
) {
    flowLayout alignment: FlowLayout.CENTER, hgap: 0, vgap: 0 
    label "<html>This app is running in <b>${RunMode.current}</b> mode.</html>"
}

When we run the application with $ griffon run-app we get the following view:

Run with $ griffon run-applet and we get:

And finally if we run our application with $ griffon run-webstart we get:

Grails Goodness: Execute Code for Current Environment

In Grails we can use the Environment class to execute code for specific environments. The method executeForCurrentEnvironment() takes a closure with the different environments and the code to be executed. This provides an elegant way to execute different blocks of code depending on the current environment.

The following sample is a simple controller where we set the value of the result variable depending on the environment. Besides the default environments - development, test, production - we can define our own custom environments. In the controller we provide the custom environment myenv.

package environment

import grails.util.Environment

class ExecuteController {

    def index = { 
     def result
     
     Environment.executeForCurrentEnvironment {
         development {
             result = 'Running in DEV mode.'
         }
            production {
             result = 'Running in production mode.'
         }
         myenv {
             result = 'Running in custom "myenv" mode.'
         }
     }
    
     render result
    }
}

We we run the Grails application with $ grails run-app and go to the URL http://localhost:8080/app/execute, we get the following output: Running in DEV mode.. When we run $ grails -Dgrails.env=myenv run-app we get the following output in our browser: Running in custom "myenv" mode..

Sunday, May 23, 2010

Finished the DemoConsole App from the Griffon Guide

Thursday, May 20, 2010

Groovy Goodness: Multiple Assignments Revisited

Multiple assignments in Groovy is something already covered before in the Groovy Goodness series. But today at the Gr8Conf I got some extra information about it's possibilities. First of all we can use type information in the multiple assignment. So we can assign the returning values to typed variables. The next thing is we can use multiple assignments basically for anything with a getAt method. And this works also for our own classes, we only have to provide an implementation for the getAt method.

class Size {
    int x, y

    Object getAt(int index) {
        index == 0 ? x : y
    }
}

def (int myX, int myY) = new Size(x: 12, y: 30)
assert 12 == myX
assert 30 == myY

Wednesday, May 19, 2010

Griffon Goodness: Run Your App as Applet or via Webstart

Griffon is a great framework to build desktop applications. But that doesn't mean your application code cannot be run as an applet or via webstart. Without changing the code we can run the application as applet or webstart with the following commands:


$ griffon run-applet
$ griffon run-webstart

Friday, May 7, 2010

Grails Goodness: Using Codecs in Test Classes

When we run Grails a lot of metaClass information is added to the classes of our application. This also include the support for encoding and decoding String values. For example in our Grails application we can use "<b>Grails</b>".encodeAsHTML() and we get "&lt;b&gt;Grails&lt;/b&gt;". But if we want to use the encodeAsHTML() method in our class we get an exception, because the method is not available. To make a Grails encoder/decoder available in our test class we must use the loadCodec() method. See the following example:

package com.mrhaki.grails

class HTMLCodecControllerTests extends grails.test.ControllerUnitTestCase {
    void testAction() {
        loadCodec HTMLCodec  // Now we can use encodeAsHTML, decodeAsHTML
        assertEquals "&lt;b&gt;Grails&lt;/b&gt;", '<b>Grails</b>'.encodeAsHTML()
    }
}

Thursday, May 6, 2010

Grails Goodness: Use the GSP Template Engine in a Controller

The GSP TemplateEngine used to render the GSP pages in Grails is also available as standalone service in for example our controllers, taglibs or services. In the Spring application context the template engine is loaded with the name groovyPagesTemplateEngine. This means we only have to define a new variable in our controller with this name and the Spring autowire by name functionality will automatically insert the template engine in our class. See the following code sample where we use the template engine, notice we even can use taglibs in our template code.

package com.mrhaki.grails

class SimpleController {
    def groovyPagesTemplateEngine
    
    def index = {
        def templateText = '''\
<html>
<body>
<h1>GSP Template Engine</h1>

<p>This is just a sample with template text.</p>

<g:if test="${show}"><p>We can use taglibs in our template!</p></g:if>

<ul>
<g:each in="${items}" var="item">
    <li>${item}</li>
</g:each>
</ul>
</body>
</html>
        '''
        
        def output = new StringWriter()
        groovyPagesTemplateEngine.createTemplate(templateText, 'sample').make([show: true, items: ['Grails','Groovy']]).writeTo(output)
        render output.toString()
    }
}

We get the following HTML output:

<html>
<body>
<h1>GSP Template Engine</h1>

<p>This is just a sample with template text.</p>

<p>We can use taglibs in our template!</p>

<ul>

    <li>Grails</li>

    <li>Groovy</li>

</ul>
</body>
</html>

Sunday, May 2, 2010

Grails Goodness: Testing for Chain Result in Controller

Testing a controller in Grails in easy with the ControllerUnitTestCase. If we extend our test class from the ControllerUnitTestCase we get a lot of extra functionality to write our tests. For example the controller is extended with a parameters map so we can set parameter values in our test case. Suppose we the following controller and want to test it:

class SimpleController {
    def hello = {
        chain action: 'world', controller: 'other', model: [message: new Expando(text: params.msg)]
    }
}

By extending the ControllerUnitTestCase the mockController(SimpleController) method is invoked. This will add (among other things) the map chainArgs to the controller. The map is filled with the attributes of our chain() method. And we can use this map in our test to check for correct results:

class SimpleControllerTests extends grails.test.ControllerUnitTestCase {
    void setUp() { super.setUp() }

    void testHelloAction() {
        controller.params.msg = 'Hello world'
        controller.hello()
        assertTrue 'world', controller.chainArgs.action
        assertTrue 'other', controller.chainArgs.controller
        assertTrue 'Hello world', controller.chainArgs.model.message.text
    }
}