Tag Archives: groovy

Vortragsreihe Dortmund 15.03.2010: Spring 3 – Der dritte Frühling

»Spring 3« ist da. Vieles ist geblieben, manches verschwunden, manches neu. Spring 3 verspricht eine verbesserte und dynamischere  Konfiguration, einen leistungsfähigen und mächtigen REST-Support und viele kleine Verbesserungen. Parallel zu dem Spring 3-Release wurden auch andere Tools und Projekte aktualisiert, auf die wir ebenfalls einen Blick werfen wollen:

  • Wichtige Änderungen
  • Java Configuration
  • Spring Expression Language
  • Spring MVC und Rest
  • Embedded Database
  • SpringSource Toolsuite
  • Spring Roo
  • Grails

Translate JIRA Transitions

If you are using the famous Issue tracker JIRA by Atlassian you are able to change the workflow. Workflows are used to define the status an issue can get. Between the 2 statuses there are a transition. In JIRA you can translate the statuses (Administration | Status | Translate).

Translate statuses in JIRA
Translate statuses in JIRA

But for transitions there is not such a dialog. But there is an solution for this. You can modify the language property file. If you use an script you can do this automatically. But one step after another :)

1. Locate the language library

In JIRA all language files are bundled in a library. This library you find in WEB-INF/lib in your JIRA installation.For the german translation the library is named language_de_DE.jar.

2. Extract the JAR and edit the JiraWebActionSupport_de_DE.properties

The JiraWebActionSupport_de_DE.properties is in the package com/atlassian/jira/web/action. You can edit this file with a simple editor. For every transititon you must add one or two properties:

  • for the title
  • for the submit button, if you transition needs a dialog (e.g. the reopen issue has a dialog where you can leave a comment)

For instance you have a transition Test Issue. This transition doesn’t need a dialog. So you need only one property:

testissue.title=Testen

As an exteded example you have a transition named Issue tested. For this you need a dialog the user can leave a comment. In this case you need 2 properties:

issuetested.title=Getested
issuetested.submit=Test abschliessen

After you finished the modification you can repackage the JAR.

3. Restart JIRA

This you should really do before you start with the next steps.

4. Add the needed properties to the transitions

The next step is to create a relation between JIRA and the properties. This can be done in the panel for modifying transitions (Administration | Workflows | Steps (of the workflow you want to change) |  Click on the transition | Properties of the transition). In the page loaded then you can add the needed properties.

Add properties to transitions
Add properties to transitions

What you need to add is a key-value pair. The key is for JIRA. With this key JIRA knows what kind of i18n text this property represents. The both relevant key are:

  • jira.i18n.title (for the title)
  • jira.i18n.submit (for the submit button)

As value you can add the properties you add to the language file (JiraWebActionSupport_de_DE.properties). After you are done you can close every dialog and activate the workflow.

As a result you see something similar to this:

Translated Transition
Translated Transition

Hmm…there are many steps…is there a chance to simplify this?

Yes, of course. You can create a script to do this automatically. For example I have one written in Groovy doing all steps automatically:

//Points to the language_de_DE.jar
def langPack = new File("...")

//Points to the folder the modified JAR should be copied to
def targetDir = new File("...")

//Points to the folder the langPack should be extracted to
def tempDir = new File(System.properties["java.io.tmpdir"]+"/language_pack")

def langFile = new File(tempDir, "com/atlassian/jira/web/action/JiraWebActionSupport_de_DE.properties")

//Create the antbuild for some common tasks
def ant = new AntBuilder()

if (tempDir.exists()){
    ant.delete(dir:tempDir)
}

ant.mkdir(dir:tempDir)
ant.unzip(src:langPack, dest:tempDir)

//Using Groovy's multiline strings
def t = """
issuetested.title=Getested
issuetested.submit=Getested
"""

//Append the existing content with our extended properties
langFile.text = langFile.text + t
ant.zip(basedir:tempDir, destfile:new File(targetDir, "language_de_DE.jar"))
ant.delete(dir:tempDir)

//Build JIRA
"cd /opt/jira".execute()
"build.bat".execute()

//Restart Tomcat
"cd /opt/tomcat/bin".execute()
"catalina.sh start".execute()

With this simple script you can do all steps automatically. One thing isn’t really nice. The properties you append to the original languagge file are saved in the script. This should be changed if there are more than a handful properties.

Groovy's Elvis and Safe-Navigation Operator in Java 7

Both operators are implemented in Groovy to shorten the code.
The Elvis Operator shorten your if-conditions. You know the common ternary expression:

def gender = user.male ? "male": "female"

This you can shorten with the Elvis operator:

def gender = user.male ?: "female"

Only if the expression evaluates to false or null the default value (here: female) will be used.

The other operator is the Safe-Navigation Operator. If you are working with Java Beans and their getter methods you have often a chain of calls:

customer.getAddress().getCity();

This works fine until one of the getters return null. Then you get a NullPointerException. To avoid this you can surround this call with a try-catch block:

try{
   customer.getAddress().getCity();
}catch (NullPointerException npe){
   //what can I do here???
}

This are at least 5 lines of code for catching the NullPointerException. But what can you do with this exception? Commonly you do nothing. You can log this or redirect this exception to the next tier. In Groovy there is the Safe-Navigation Operator:

customer?.address?.city

At first in Groovy you can use the properties instead of accessing the getter methods. The ?. operator checks if the expression on the left hand is null. If true the complete expession evaluates to null.

For this both operators there is an proposal for a change in the Java Programming language. For now this proposal is not accepted…but we hope so :)