Monday, April 20, 2015

Awesome Asciidoctor: Adding Custom Content to Head and Footer

When we convert our Asciidoctor markup to HTML we automatically get a head and footer element. We can add custom content to the HTML head element and to the HTML div with id footer. We must set a document attribute and create the files that contain the HTML that needs to be added to the head or footer. We have three different document attributes we can set to include the custom content files:

  • :docinfo: include document specific content. Files to be included must be named <docname>-docinfo.html for head element and <docname>-docinfo-footer.html for footer content.
  • :docinfo1: include general custom content. Files to be included must be named docinfo.htmtl for head element and docinfo-footer.html for footer content.
  • :docinfo2: include document specific and general custom content. Files to be included must be named <docname>-docinfo.html and docinfo.html for head element and <docname>-docinfo-footer.html and docinfo-footer.html for footer content.

In this sample we create the files docinfo.html and docinfo-footer.html we want to include in the generated output from the following Asciidoctor source file:

= Asciidoctor custom header and footer
Hubert A. Klein Ikkink
// Document specific and general custom
// content files are used:
// Include general custom content files:
// Include document specific content files:
// In generated HTML this is transformed
// to 
:description: Sample document with custom header and footer parts.
// In generated HTML this is transformed
// to 
:keywords: Asciidoctor, header, footer, docinfo

Using the `docinfo` attributes we can include custom content
in the header and footer. Contents of the files 
named `docinfo.html` and `docinfo-footer.html` are included.

We can choose between general or document specific custom
header and footer content.

Our docinfo.html looks like this:

<!-- Change some CSS. -->
/* Change CSS overflow for table of contents. */
#toc.toc2, #toc { overflow: scroll; }

/* Change styling for footer text. */
.footer-text { color: rgba(255,255,255,.8); }

<!-- We could also include Javascript 
     for example in this document. -->

For the custom footer we create the file docinfo-footer.html:

<p class="footer-text">
<!-- We can use document attributes: -->
Generated with Asciidoctor v{asciidoctor-version}.

The following screenshot shows the generated HTML page:

And here is part of the generated head element:



<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="Asciidoctor 1.5.2">
<meta name="description" content="Sample document with custom header and footer parts.">
<meta name="keywords" content="Asciidoctor, header, footer, docinfo">
<meta name="author" content="Hubert A. Klein Ikkink">
<title>Asciidoctor custom header and footer</title>


<!-- Change some CSS. -->
/* Change CSS overflow for table of contents. */
#toc.toc2, #toc { overflow: scroll; }

/* Change styling for footer text. */
.footer-text { color: rgba(255,255,255,.8); }

<!-- We could also include Javascript
     for example in this document. -->

Written with Asciidoctor 1.5.2.

Sunday, April 19, 2015

Gradle Goodness: Alter Start Scripts from Application Plugin

For Java or Groovy projects we can use the application plugin in Gradle to run and package our application. The plugin adds for example the startScripts task which creates OS specific scripts to run the project as a JVM application. This task is then used again by the installDist that installs the application, and distZip and distTar tasks that create a distributable archive of the application. The startScripts tasks has the properties unixScript and windowsScript that are the actual OS specific script files to run the application. We can use these properties to change the contents of the files.

In the following sample we add the directory configuration to the CLASSPATH definition:

startScripts {

    // Support closures to add an additional element to 
    // CLASSPATH definition in the start script files.
    def configureClasspathVar = { findClasspath, pathSeparator, line ->

        // Looking for the line that starts with either CLASSPATH=
        // or set CLASSPATH=, defined by the findClasspath closure argument.
        line = line.replaceAll(~/^${findClasspath}=.*$/) { original ->

            // Get original line and append it 
            // with the configuration directory.
            // Use specified path separator, which is different
            // for Windows or Unix systems.
            original += "${pathSeparator}configuration"


    def configureUnixClasspath = configureClasspathVar.curry('CLASSPATH', ':')
    def configureWindowsClasspath = configureClasspathVar.curry('set CLASSPATH', ';')

    // The default script content is generated and
    // with the doLast method we can still alter
    // the contents before the complete task ends.
    doLast {

        // Alter the start script for Unix systems.
        unixScript.text = 

        // Alter the start script for Windows systems.
        windowsScript.text = 



This post was inspired by the Gradle build file I saw at the Gaiden project.

Written with Gradle 2.3.

Friday, April 17, 2015

Spring Sweets: Using @Value for Constructor Arguments

In Spring we can use the @Value annotation to set property or arguments values based on a SpEL expression. If we want to use the @Value annotation for a constructor argument we must not forget to add the @Autowired annotation on the constructor as well.

// File: sample/Message.groovy
package sample

import org.springframework.beans.factory.annotation.*
import org.springframework.stereotype.*

class Message {

    final String text

    // Use @Autowired to get @Value to work.
        // Refer to configuration property
        // app.message.text to set value for 
        // constructor argument text.
        @Value('${app.message.text}') final String text) {
        this.text = text


Written with Spring 4.1.6.

Thursday, April 16, 2015

Grails Goodness: Add Some Color to Our Logging

Grails 3 is based on Spring Boot. This means we can use a lot of the stuff that is available in Spring Boot now in our Grails application. If we look at the logging of a plain Spring Boot application we notice the logging has colors by default if our console supports ANSI. We can also configure our Grails logging so that we get colors.

First we need to change our logging configuration in the file grails-app/conf/logback.groovy:

// File: grails-app/conf/logback.groovy
import grails.util.BuildSettings
import grails.util.Environment
import org.springframework.boot.ApplicationPid

import java.nio.charset.Charset

// Get PID for Grails application.
// We use it in the logging output.
if (!System.getProperty("PID")) {
    System.setProperty("PID", (new ApplicationPid()).toString())

// Mimic Spring Boot logging configuration.
conversionRule 'clr', org.springframework.boot.logging.logback.ColorConverter
conversionRule 'wex', org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter

appender('STDOUT', ConsoleAppender) {
    encoder(PatternLayoutEncoder) {
        charset = Charset.forName('UTF-8')

        // Define pattern with clr converter to get colors.
        pattern =
                '%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} ' + // Date
                '%clr(%5p) ' + // Log level
                '%clr(%property{PID}){magenta} ' + // PID
                '%clr(---){faint} %clr([%15.15t]){faint} ' + // Thread
                '%clr(%-40.40logger{39}){cyan} %clr(:){faint} ' + // Logger
                '%m%n%wex' // Message

// Change root log level to INFO,
// so we get some more logging.
root(INFO, ['STDOUT'])

Normally when we would run our application Grails should check if the console support ANSI colors. If the console supports it the color logging is enabled, otherwise we still get non-colored logging. On my Mac OSX the check doesn't work correctly, but we can set an environment property spring.output.ansi.enabled to the value always to force colors in our logging output. The default value is detect to auto detect the support for colors. We can set this property in different ways. For example we could add it to our application configuration or we could add it as a Java system property to the JVM arguments of the bootRun task. In the following build file we use the JVM arguments for the bootRun task:

// File: build.gradle
bootRun {
    // If System.console() return non null instance,
    // we force ANSI color support with 'always', 
    // otherwise use default 'detect'.
    jvmArgs = ['-Dspring.output.ansi.enabled=' + (System.console() ? 'always' : 'detect')]

When we run the Grails application using bootRun we get for example the following output:

Written with Grails 3.0.1.

Wednesday, April 15, 2015

Grails Goodness: Set Log Level for Grails Artifacts

A good thing in Grails is that in Grails artifacts like controllers and services we have a log property to add log statements in our code. If we want to have the output of these log statements we must use a special naming convention for the log names. Each logger is prefixed with grails.app followed by the Grails artifact. Valid artifact values are controllers, services, domain, filters, conf and taglib. This is followed by the actual class name. So for example we have a controller SampleController in the package mrhaki.grails then the complete logger name is grails.app.controllers.mrhaki.grails.SampleContoller.

The following sample configuration is for pre-Grails 3:

// File: grails-app/conf/Config.groovy
log4j = {
    info 'grails.app.controllers'
    debug 'grails.app.controllers.mrhaki.grails.SampleController'
    info 'grails.app.services'

In Grails 3 we can use a common Logback configuration file. In the following part of the configuration we set the log levels:

// File: grails-app/conf/logback.groovy
logger 'grails.app.controllers', INFO, ['STDOUT']
logger 'grails.app.controllers.mrhaki.grails.SampleController', DEBUG, ['STDOUT']
logger 'grails.app.services', INFO, ['STDOUT']

Written with Grails 2.5.0 and 3.0.1.

Grails Goodness: Add Banner to Grails Application

Grails 3 is based on Spring Boot. This means we get a lot of the functionality of Spring Boot into our Grails applications. A Spring Boot application has by default a banner that is shown when the application starts. The default Grails application overrides Spring Boot's behavior and disables the display of a banner. To add a banner again to our Grails application we have different options.

First we can add a file banner.txt to our classpath. If Grails finds the file it will display the contents when we start the application. Let's add a simple banner with Grails3 in Ascii art in the file src/main/resources/banner.txt. By placing the file in src/main/resources we can assure it is in the classpath as classpath:/banner.txt:

  ________             .__.__         ________
 /  _____/___________  |__|  |   _____\_____  \
/   \  __\_  __ \__  \ |  |  |  /  ___/ _(__  <
\    \_\  \  | \// __ \|  |  |__\___ \ /       \
 \______  /__|  (____  /__|____/____  >______  /
        \/           \/             \/       \/

Let's run our application with the bootRun task:

$ gradle bootRun
:compileJava UP-TO-DATE
:compileGroovy UP-TO-DATE

  ________             .__.__         ________
 /  _____/___________  |__|  |   _____\_____  \
/   \  __\_  __ \__  \ |  |  |  /  ___/ _(__  <
\    \_\  \  | \// __ \|  |  |__\___ \ /       \
 \______  /__|  (____  /__|____/____  >______  /
        \/           \/             \/       \/

Grails application running at http://localhost:8080

To have more information in the banner we can implement the org.springframework.boot.Banner interface. This interface has a printBanner method in which we can write the implementation for the banner. To use it we must create an instance of the GrailsApp class and set the banner property:

// File: grails-app/init/banner/Application.groovy
package banner

import grails.boot.GrailsApp
import grails.boot.config.GrailsAutoConfiguration
import grails.util.Environment
import org.springframework.boot.Banner

import static grails.util.Metadata.current as metaInfo

class Application extends GrailsAutoConfiguration {
    static void main(String[] args) {
        final GrailsApp app = new GrailsApp(Application)
        app.banner = new GrailsBanner()

 * Class that implements Spring Boot Banner
 * interface to show information on application startup.
class GrailsBanner implements Banner {

    private static final String BANNER = '''
  ________             .__.__         ________
 /  _____/___________  |__|  |   _____\\_____  \\
/   \\  __\\_  __ \\__  \\ |  |  |  /  ___/ _(__  <
\\    \\_\\  \\  | \\// __ \\|  |  |__\\___ \\ /       \\
 \\______  /__|  (____  /__|____/____  >______  /
        \\/           \\/             \\/       \\/'''

    void printBanner(
            org.springframework.core.env.Environment environment,
            Class sourceClass,
            PrintStream out) {

        out.println BANNER

        row 'App version', metaInfo.getApplicationVersion(), out
        row 'App name', metaInfo.getApplicationName(), out
        row 'Grails version', metaInfo.getGrailsVersion(), out
        row 'Groovy version', GroovySystem.version, out
        row 'JVM version', System.getProperty('java.version'), out
        row 'Reloading active', Environment.reloadingAgentEnabled, out
        row 'Environment', Environment.current.name, out


    private void row(final String description, final value, final PrintStream out) {
        out.print ':: '
        out.print description.padRight(16)
        out.print ' :: '
        out.println value


Now we run the bootRun task again:

$ gradle bootRun
:compileJava UP-TO-DATE

  ________             .__.__         ________
 /  _____/___________  |__|  |   _____\_____  \
/   \  __\_  __ \__  \ |  |  |  /  ___/ _(__  <
\    \_\  \  | \// __ \|  |  |__\___ \ /       \
 \______  /__|  (____  /__|____/____  >______  /
        \/           \/             \/       \/
:: App version      :: 0.1
:: App name         :: grails-banner-sample
:: Grails version   :: 3.0.1
:: Groovy version   :: 2.4.3
:: JVM version      :: 1.8.0_45
:: Reloading active :: true
:: Environment      :: development

Grails application running at http://localhost:8080

Written with Grails 3.0.1.

Ascii art is generated with this website.

Groovy Goodness: Use Closures as Java Lambda Expressions

Java 8 introduced lambda expressions we can use for example with the new Java Streams API. The Groovy syntax doesn't support the lambda expressions, but we can rely on closure coersion to use Groovy closures as Java lambda expressions in our code.

In the following sample we use the Java Streams API. Instead of lambda expressions for the filter and map methods we use Groovy closures. They are automatically transformed to lambda expressions, so it is very easy to use Java streams from Groovy code.

import groovy.transform.*

 * Simple class to describe
 * a Building.
class Building {
    String name
    int floors
    boolean officeSpace

// Create Building objects.
def officeSpace = new Building('Initech office', 3, true)
def theOffice = new Building('Wernham Hogg Paper Company', 4, true)
def coffeeShop = new Building('Hunter Green', 1, false)

// And add to a list.
def buildings = [officeSpace, theOffice, coffeeShop]

// Create a closure which we will use 
// later in our code.
def mapBuildingName = { building -> building.name }

// Invoke Java Streams API with lambda methods,
// but we use Groovy closures.
def officeBuildingNames = 
        .stream() // Get Java streams.
        .filter { building -> 
            building.officeSpace && building.floors > 2 
        } // 'anonymous' closure.
        .map(mapBuildingName) // Predefined closure.
assert officeBuildingNames == ['Initech office', 'Wernham Hogg Paper Company']

Code written with Groovy 2.4.3.

Tuesday, April 14, 2015

Greach 2015 Conference Report

So this year I got the opportunity to speak and visit Greach 2015 in Madrid, Spain. I've never been in Spain before, but after visiting I definitely want to go back. Although the trip to Madrid was more cumbersome than planned, because of the strikes in France, I arrived at the speaker's dinner on time. Just go to mention that the Madrid metro is a very pleasant way to go around in Madrid. It was good to see old and new faces and to catch up and just have fun. Friday April 10th was the first day of the conference. The conference is held at the university in the south of Madrid. Jochen Theodorou, one of the Groovy core developers, opened the day with the keynote about Groovy's past, present and future. He gave a very nice overview of how Groovy evolved over the years and Groovy has been around already for a long time. Of course the latest news this year is Pivotal's hands off of Groovy and Grails. Jochen explained he first gets a good vacation and then decides what to do himself. Groovy is now in the process of getting an Apache project so the continuity of the development of the language should be saved. Then the rest of the day two tracks were presented at the same time. And there were difficult choices to make. Fortunately all talks are recorded and they will be added to the Greach Youtube channel.

I went to the talk Groovy and Scala: Friends or Foes by Marco Vermeulen. He showed how we can use Spock with Groovy to test Scala code using a Gradle build. So both worlds can live together and we can intermingle where possible. The application written in Scala was pragmatic and that is something I missed when I looked at Scala for the first time. This talk really got me interested to learn more about Scala. Next up was the talk AST - Groovy Transformers: More than meets the eye! by one of the conference organizers Iván López. He showed a lot of the (local) AST transformation that are already available in Groovy and that we can use everyday in our programs. Each AST transformation was clearly explained and he showed samples on how to use them. After his talk it was my time to present Grails Goodness. In this talk I live coded a selection of the blog posts about Grails I did write. Somehow there is always to little time to show everything I wanted, but still I think I was able to show some nice features of Grails.

After a very good lunch it was time to attend Hacking the Grails Spring Security 2.0 Plugin by Burt Beckwith. It is always fun to attend a session by Burt Beckwith and this was no exception. The plugin is almost ready to be released and he showed us the components that make up the plugin and how to customize things in our applications. The plugin provides some defaults, but they can easily be overwritten or changed if we want to. The next talk was a discussion Gr8Workshop: A Guided Discussion about Teaching and Diversity in the Groovy Community by Jennifer Strater. She first showed some basic principles of teaching something, followed by experiences she had with Groovy workshops both for beginners and more advanced developers. It was interesting to hear to Groovy can of course also be the first programming language for a developer. Normally I am used that Java developers learn Groovy, but also developers from a different background or just new developers get used to Groovy quickly. Russel Winder told that in the UK programming is a mandatory subject at school for children starting from 5 years. I think it is great that kids learn more about programming and solving problems at a young age. He also said that children learn by playing and sometimes we forget that adults can learn the same way.

I went to Advanced Microservice Concerns by Steve Pember where he presented his real world experiences working with microservices. For example to have separate code repositories and that the DRY (Don't Repeat Yourself) principle doesn't need to apply among microservices, we want as less dependencies as possible between services. He also showed his preference for using a message broker to communicate between microservices in a flexible way. Other concerns like monitoring and logging were also covered, for example he showed the Elastic search, Logstash and Kibana (ELK) stack. The last session of the day was about The Groovy Ecosystem by Andres Almiray. He gave a good overview of all the projects related to Groovy that are out there. And there a lot of Groovy related and influenced things we can use, besides maybe the obvious Gradle, Grails and Groovy itself. He also gave GVM a special place, because GVM ties it all together and gives us very easy access to a lot of the tools and projects.

The second day of the conference was even more packed with now three tracks to choose from. I am glad the talks are recorded so I can still see what I missed afterwards. We could choose to follow a workshop or between two talks. I didn't attend the workshop, but followed the talks. The first one was Grooscript in Action by Jorge Franco. He created a Grooscript, which is a tool to convert Groovy code to Javascript. The tool is really impressive, it can already do so many things and I was amazed by how much of the Groovy syntax is supported. There is also a Gradle plugin for Grooscript. He showed a very nice working application with a Spring Boot backend and a Javascript fronted which was created with Grooscript. With this tool it is very easy to write Groovy code (we already know) and have Javascript application transformed for us. And it is not a small subset of Groovy we can use, we can use a lot already. The following talk was Documentation brought to life: Asciidoctor & Gradle by Markus Schlichting. He showed why we would want to have our documentation written in Asciidoctor, close to our sources and integrated with our build automation as compared to for example writing documentation in Word. He had some nice example on how to setup our Gradle builds to working Asciidoctor. I liked the watch plugin that he used, so every time the Asciidoc source file changes it is automatically transformed.

The next talk was DSL'ing your Groovy by Alonso Torres Ortiz. He gave a good overview of the different options we have to build a DSL in Groovy. For example using closures, builders, meta programming, AST and scripting. For each option he had some nice examples. I really liked how he wrote a AST transformation to mimic the data table syntax from Spock in his own DSL. Up next was Groovy enVironment Manager (2015) by the author of GVM Marco Vermeulen. He showed the components that make up GVM and his plans with the tool. GVM is now targeted to Groovy stuff, but he will create SDKenv that will support other SDK's as well. I also liked to hear about the components that make up GVM, like the Broadcast API we can use. Tools that are included in GVM can themselves add the tool or SDK to GVM and automatically it will be available for us to install.

After lunch Trisha Gee presented Is Groovy better for testing than Java?. She showed her real world experience of transforming JUnit tests to Spock. The different features of Spock and Groovy were shown like data tables and mocking and stubbing. It turned out that Java developers didn't have any real issues to use Groovy for their testing and still Java for the production code. The mental shift between Java and Groovy wasn't that big and the readability and terse syntax of the Spock specifications really added to better and more tests in the project. Burt Beckwith presented Little Did He Know... with non-related observations and tips about Groovy and Grails. The title of the presentation is based on a movie Stranger than fiction. He started with explaining some of the magic that happens with domain classes and constructors in Grails and Groovy. It turns out that Grails has an AST that will add a non-argument constructor to domain classes, but this intervenes with argument constructors we like to add ourselves. The talk was filled with nice examples and very useful tips.

Schalk W. Cronjé presented Idiomatic Gradle Plugin Writing. He is (co-)author of for example the JRuby and Asciidoctor Gradle plugins and had some very nice tips on writing plugin code. Especially to have some conventions on how the plugin and tasks need to be configured. I really liked the code that showed how to be flexible in accepting input files for your plugin to work with. With his example code of just a couple of lines it is possible to accept String, File and Closures to get files. He stressed it is important to be consist and prefer methods over property assignments. The last talk of the conference was Groovy on the Shell by Alexander (Sasha) Klein. Groovy is of course also a very good scripting language and why not use it in our shell as well. We know the syntax and he showed it is very easy to write shell scripts in Groovy. For example with Grab annotation and she bang operator we can write self contained scripts that can be executed by anyone as long they have Groovy.

The Greach conference is a great conference. The organizers did a very good job and presented a very good program. It was difficult to choose between tracks and therefore it is a good thing the talks are all video taped and will be available on Youtube. The attendees and speakers are all very passionate about their profession and working with Groovy and Groovy related tools and languages. It is a good place to catch up on the latest developments and speak with the people behind the projects and the users. Hopefully I will be back next year and enjoy another Greach.

Thursday, March 26, 2015

Groovy Goodness: New Methods to Sort and Remove Duplicates From Collection

In Groovy we can use the sort and unique methods to sort a collection or remove duplicates from a collection. These methods alter the collection on which they are invoked. This is a side effect we might want to avoid. Therefore the sort and unique methods where changed and we could pass a boolean argument to indicate if the original collection should be changed or that we must have a new collection as the result of the methods, leaving the original collection untouched. Since Groovy 2.4 we have two new methods which by default return a new collection: toSorted and toUnique.

In the following sample we see the new methods in action:

class User {
    String username, email

def mrhaki1 = new User(username: 'mrhaki', email: 'mrhaki@localhost')
def mrhaki2 = new User(username: 'mrhaki', email: 'user@localhost')
def hubert1 = new User(username: 'hubert', email: 'user@localhost')
def hubert2 = new User(username: 'hubert', email: 'hubert@localhost')

// We make the list immutable,
// so we check the toSorted and toUnique methods
// do not alter it.
def users = [mrhaki1, mrhaki2, hubert1, hubert2].asImmutable()

// toSorted 
def sortedUsers = users.toSorted()

// @Sortable adds a compareTo method 
// to User class to sort first by username
// and then email.
assert sortedUsers == [hubert2, hubert1, mrhaki1, mrhaki2]

// Original list is unchanged.
assert users == [mrhaki1, mrhaki2, hubert1, hubert2]

// Use toSorted with closure.
def sortedByEmail = users.toSorted { a, b -> a.email <=> b.email }
assert sortedByEmail == [hubert2, mrhaki1, mrhaki2, hubert1]

// Or use toSorted with Comparator.
// @Sortable added static comparatorByProperty
// methods.
def sortedByEmailComparator = users.toSorted(User.comparatorByEmail())
assert sortedByEmailComparator == [hubert2, mrhaki1, mrhaki2, hubert1]

// toUnique with Comparator.
def uniqueUsers = users.toUnique(User.comparatorByUsername())
assert uniqueUsers == [mrhaki1, hubert1]
assert users == [mrhaki1, mrhaki2, hubert1, hubert2]

// toUnique with Closure.
def uniqueByEmail = users.toUnique { a, b -> a.email <=> b.email }
assert uniqueByEmail == [mrhaki1, mrhaki2, hubert2]

Written with Groovy 2.4.3.

Monday, March 23, 2015

Groovy Goodness: Combine Elements Iterable with Index

Since Groovy 2.4.0 we can get the indices from the elements in a collection with the indices method. In addition to this method we can also use the withIndex to combine an Iterable with the indices directly. The output is a List of tuples where the first item is the value of the Iterable and the second the index value. We can pass an optional argument to the withIndex which is the starting point for the index values.
Another alternative is the indexed method. The indexed method returns a Map, where the key of the entry is the index value and the entry value is the Iterable value.

In the following example we use the withIndex method. The sample of the alphabet is the same as in the blog post about indices, but rewritten with the withIndex method:

def list = [3, 20, 10, 2, 1]
assert list.withIndex() == [[3, 0], [20, 1], [10, 2], [2, 3], [1, 4]]

def alphabet = 'a'..'z'

// Combine letters in alphabet
// with position and start at 1.
def alphabetIndices = alphabet.withIndex(1)

// alphabetIndices = [['a', 1], ['b', 2], ...]
assert alphabetIndices[0..2] == [['a', 1], ['b', 2], ['c', 3]]

// Find position of each letter
// from 'groovy' in alphabet.
def positionInAlphabet = 'groovy'.inject([]) { result, value ->
    result << alphabetIndices.find { it[0] == value }[1]

assert positionInAlphabet == [7, 18, 15, 15, 22, 25]

In the next example we use the indexed method:

def list = [3, 20, 10, 2, 1]
assert list.indexed() == [0: 3, 1: 20, 2: 10, 3: 2, 4: 1]

def alphabet = 'a'..'z'

// Combine letters in alphabet
// with position and start at 1.
def alphabetIndices = alphabet.indexed(1)

// alphabetIndices = [1: 'a', 2: 'b', ...]
assert alphabetIndices.findAll { key, value -> key < 4} == [1: 'a', 2: 'b', 3: 'c']

// Find position of each letter
// from 'groovy' in alphabet.
def positionInAlphabet = 'groovy'.inject([]) { result, value ->
    result << alphabetIndices.find { it.value == value }.key

assert positionInAlphabet == [7, 18, 15, 15, 22, 25]

Written with Groovy 2.4.1.