JDriven Blog

Grails Goodness: Custom Data Binding with @DataBinding Annotation

Posted on by  
Hubert Klein Ikkink

Grails has a data binding mechanism that will convert request parameters to properties of an object of different types. We can customize the default data binding in different ways. One of them is using the @DataBinding annotation. We use a closure as argument for the annotation in which we must return the converted value. We get two arguments, the first is the object the data binding is applied to and the second is the source with all original values of type SimpleMapDataBindingSource. The source could for example be a map like structure or the parameters of a request object.

In the next example code we have a Product class with a ProductId class. We write a custom data binding to convert the String value with the pattern {code}-{identifier} to a ProductId object:

Continue reading →

Geb Gems: Using Pages and Modules

Posted on by  
Albert van Veen

In the previous blog post about Geb, we have been introduced to the Geb Framework. In this blogpost we will be introduced to Pages and Modules. A Page represents a specific page from a web application. A module represent a part of the page; for example a sign-up form, a menu bar or contact form. Pages and Modules are very useful since they are very easy to reuse and therefore useful to create more advanced UI tests. In this blogpost we are going to use Pages and Modules to test the contact form of the JDriven website. We will verify that a success message will appear if we submit a valid form. Pages have a url attribute which represent the address to the page. To get the complete url, Geb requires a baseUrl which we can define in the GebConfig.groovy

baseUrl = "http://www.jdriven.com/"

Continue reading →

Grails Goodness: Adding Health Check Indicators

Posted on by  
Hubert Klein Ikkink

With Grails 3 we also get Spring Boot Actuator. We can use Spring Boot Actuator to add some production-ready features for monitoring and managing our Grails application. One of the features is the addition of some endpoints with information about our application. By default we already have a /health endpoint when we start a Grails (3+) application. It gives back a JSON response with status UP. Let's expand this endpoint and add a disk space, database and url health check indicator.

We can set the application property endpoints.health.sensitive to false (securing these endpoints will be another blog post) and we automatically get a disk space health indicator. The default threshold is set to 10MB, so when the disk space is lower than 10MB the status is set to DOWN. The following snippet shows the change in the grails-app/conf/application.yml to set the property:

Continue reading →

Grails Goodness: Log Startup Info

Posted on by  
Hubert Klein Ikkink

We can let Grails log some extra information when the application starts. Like the process ID (PID) of the application and on which machine the application starts. And the time needed to start the application. The GrailsApp class has a property logStartupInfo which is true by default. If the property is true than some extra lines are logged at INFO and DEBUG level of the logger of our Application class.

So in order to see this information we must configure our logging in the logback.groovy file. Suppose our Application class is in the package mrhaki.grails.sample.Application then we add the following line to see the output of the startup logging on the console:

Continue reading →

Grails Goodness: Save Application PID in File

Posted on by  
Hubert Klein Ikkink

Since Grails 3 we can borrow a lot of the Spring Boot features in our applications. If we look in our Application.groovy file that is created when we create a new Grails application we see the class GrailsApp. This class extends SpringApplication so we can use all the methods and properties of SpringApplication in our Grails application. Spring Boot and Grails comes with the class ApplicationPidFileWriter in the package org.springframework.boot.actuate.system. This class saves the application PID (Process ID) in a file application.pid when the application starts.

In the following example Application.groovy we create an instance of ApplicationPidFileWriter and register it with the GrailsApp:

Continue reading →

Awesome Asciidoctor: Display Keyboard Shortcuts

Posted on by  
Hubert Klein Ikkink

When we want to explain in our documentation which keys a user must press to get to a function we can use the keyboard macro in Asciidoctor. The macro will output the key nicely formatted as a real key on the keyboard. The syntax of the macro is kbd:[key]. To get the desired output we must set the document attribute experimental otherwise the macro is not used.

In the next Asciidoctor example file we use the keyboard macro:

Continue reading →

Scala Snippet: How to filter a list in Scala

Posted on by  
Arthur Arts

In Scala, filtering and processing collections is easy and elegant. There are many filtermethods available, but the most used will probably the basic filter method. Here's a code example of some filtering on my (ex)camera collection. The filter method will not only work on Lists, but on any Scala collection.

object MyCameraCollection02 {

  case class Camera(brand: String, model: String, sensorType: String, yearBought: Int) {
    override def toString: String =
      s"$brand $model \t\t $sensorType \t($yearBought)"
  }

  def main(args: Array[String]) {
    val canon5dmarkIII = new Camera("Canon", "5D MkIII", "FF", 2013)
    val canon5dmarkII = new Camera("Canon", "5D MkII", "FF", 2009)
    val canon6d = new Camera("Canon", "6D", "FF", 2014)
    val canon550d = new Camera("Canon", "550D", "APS-C", 2010)
    val canon40d = new Camera("Canon", "40D", "APS-C", 2008)
    val canonIXUS330 = new Camera("Canon", "IXUS 330", "1/2.7", 2001)
    val canonIXUSZ90 = new Camera("Canon", "IXUS Z90", "APS-C", 1999)
    val panasonicGM1 = new Camera("Panasonic", "GM1", "M43", 2014)
    val panasonicFZ20 = new Camera("Panasonic", "FZ20", "1/2.5", 2005)
    val sonyrx100 = new Camera("Sony", "DSC-RX100", "1\"", 2013)
    val sonynex5 = new Camera("Sony", "NEX-5", "APS-C", 2011)
    val sonyr1 = new Camera("Sony", "DSC-R1", "APS-C", 2005)

    val myCameras = List(canon5dmarkIII, canon5dmarkII, canon6d, canon550d, canon40d, canonIXUS330, canonIXUSZ90, panasonicGM1, panasonicFZ20, sonyrx100, sonynex5, sonyr1)
    val canonCameras = myCameras filter (_.brand == "Canon") // Every Canon camera I ever owned
    val sonyCameras = myCameras filter (_.brand == "Sony") // Every Sony camera I ever owned
    val pansonicCameras = myCameras filter (_.brand == "Panasonic") // Every Panasonic camera I ever owned


    // apscCamera's only
    val apscCameras = myCameras filter (_.sensorType == "APS-C")
    println("==APS-C camera's owned==")
    apscCameras foreach println
    println()


    // Canon camera's which are not full frame. You can filter, filtered lists.
    val canonNonFF = myCameras filter (_.brand == "Canon") filter (_.sensorType != "FF")
    println("==Non-FF camera's owned==")
    canonNonFF foreach println
    println()

    // Filter by boolean expressions on class properties
    val apsBefore2012 = apscCameras filter (_.yearBought < 2012)
    println("==APS-C camera's bought before 2012 owned==")
    apsBefore2012 foreach println
    println()

    // Filter by combining boolean expressions.
    val ffcamerasBefore2012 = myCameras filter (cam => cam.yearBought < 2012 && cam.sensorType == "FF")
    println("==Every FF Camera I ever owned before 2012==")
    ffcamerasBefore2012 foreach println
    println()
  }
}

Continue reading →

Gradle Goodness: Handle Copying Duplicate Files

Posted on by  
Hubert Klein Ikkink

In Gradle we can configure how duplicate files should be handled by the Copy task. Actually we can configure how duplicate files are handled by any task that implements the CopySpec interface. For example archive tasks also implements this interface. We must use the setDuplicatesStrategy method to configure how Gradle behaves. The parameter is a value of the enumeration DuplicatesStrategy. We can use the values from the enum class or use String values, which are automatically converted to enum DuplicatesStrategy values.

We can choose the following strategies:

Continue reading →

Gradle Goodness: Use Git Commit Id in Build Script

Posted on by  
Hubert Klein Ikkink

The nice thing about Gradle is that we can use Java libraries in our build script. This way we can add extra functionality to our build script in an easy way. We must use the classpath dependency configuration for our build script to include the library. For example we can include the library Grgit, which provides an easy way to interact with Git from Java or Groovy code. This library is also the basis for the Gradle Git plugin.

In the next example build file we add the Grgit library to our build script classpath. Then we use the open method of the Grgit class. From the returned object we invoke the head to get the commit id identified as id. With the abbreviatedId property we get the shorter version of the Git commit id. The build file also includes the application plugin. We customize the applicationDistribution CopySpec from the plugin and expand the properties in a VERSION file. This way our distribution always includes a plain text file VERSION with the Git commit id of the code.

Continue reading →

Time libraries in Scala

Posted on by  
Tammo Sminia

Scala has no default way to deal with dates and times. We have a few options. java.util.Date and java.util.Calendar These come included with java, so they may do if you don't need to do much and don't want to add any dependencies. But they're horrible and it's best not to use them. Joda-Time http://www.joda.org/joda-time/ The de facto standard date and time library for Java. nscala-time https://github.com/nscala-time/nscala-time A thin scala layer around Joda-Time. This adds some implicit conversions to make it easier to use, like the + and < operators.

import com.github.nscala_time.time.Imports._
DateTime.now + 2.months // returns org.joda.time.DateTime

Continue reading →

shadow-left