Our new Appfire Documentation Space is now live!

Take a look here! If you have any questions please email support@appfire.com

Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 15 Current »

This document details the Shared Groovy scripts feature of JMWE. Using this you can define global Groovy scripts that will be available from any Groovy script written in the Groovy console, post-functions, conditions and validators. This is useful for reusing complex/lengthy scripts across multiple workflow transitions. It is available under JMWE administration pages

On this page:

Create a Shared Groovy Script

To create a shared Groovy script:

  1. Go to JMWE administration pages
  2. Click on Shared Groovy Scripts
  3. Click on New shared script
  4. Enter the name of this shared script in Shared script name. This name can be used as the name of the Class that will contain all methods and data members defined in the script.
  5. Enter an optional description in Description.
  6. Input a valid Groovy script in Groovy script(warning) It is strongly recommended to wrap any (static) method in a class.
  7. Click on Save.

Edit a Shared Groovy Script

To edit a Shared Groovy script:

  1. Go to JMWE administration pages
  2. Click on Shared Groovy Scripts
  3. Click on Edit for the specific Shared Groovy Script
  4. Modify the script.
  5. Click on Save.

Delete a Shared Groovy Script

To delete a Shared Groovy script:

  1. Go to JMWE administration pages
  2. Click on Shared Groovy Scripts
  3. Click on Delete for the specific Shared Groovy Script
  4. Confirm the action.
  5. The Shared Groovy Script gets deleted.

It is strongly recommended to remove the references to the Shared Groovy Script in any workflow extension before deleting it.

Creating Shared Groovy Scripts

Defining a static method

In this example, we will create a simple static method plusOne in the Class FunctionsCreate a shared script named Functions with this script. Note, the name of the shared script can be used as the class.

static int plusOne(int i) {
  return i+1;
}

You can use this in a Groovy script section of any workflow extension (e.g. a Scripted Groovy Operation post-function) like this:

return Functions.plusOne(1)

When you test this script in the Groovy editor against any issue the tester will return 2

Defining a whole class

In this example, we will create a shared script named GreetMe with the script:

class GreetMe{
 String aString = "Hello"
String sayIt() {
  return aString;
	} 
}

You can use this in a Groovy script section of any workflow extension (e.g. a Scripted Groovy Operation post-function) like this:

def obj = new GreetMe()
return obj.sayIt()

When you test this script in the Groovy editor against any issue the tester will return Hello

Defining another class inside the script

In this example, we will create a shared script named MyClasses with the script:

interface Animal {
  String getName()
}

class Cat implements Animal {
  String getName() {
    return "Cat"
  }
}

static String exec() {
  return new Cat().name
}

You can use this in a Groovy script section of any workflow extension (e.g. a Scripted Groovy Validator) like this:

return new Cat().name == MyClasses.exec()

When you test this script in the Groovy editor against any issue the tester will return true

Defining a service with all desired methods

Global variables and functions used in the Shared Groovy scripts are not available to the calling methods and hence should be passed as parameters. The easiest approach to this is to define a class that will contain all the desired methods but not static methods. This will be like a "Service". For example:

import com.atlassian.jira.issue.IssueManager

class MyService {
  private Script baseScript;
  
  public MyService(Script base) {
    this.baseScript = base;
  }
  
  public String getIssueKey() {
    return baseScript.issue.key;
  }

  public Issue getIssue(String key) {
    return baseScript.getComponent(IssueManager).getIssueObject(key)
  }
}

And you can then use this "Service" from the main script:

MyService utils = new MyService(this)

utils.issueKey
utils.getIssue("TEST-1")

Use cases for Shared Groovy scripts

Add Days to Date excluding weekends

Create a shared Groovy script that adds a certain number of days to a date excluding the weekends

  1. Create a shared groovy script, AddDaysExcludingWeekends, with the following script

    static Date addDays(Date from, int nod){
        Calendar c1 = GregorianCalendar.getInstance();
        c1.setTime(from);
      
        int weeks = nod/5;
        int remDays = nod%5;
      
        //Adding whole weeks
        c1.add(Calendar.WEEK_OF_YEAR, weeks);
      
        //Run a loop and check each day to skip a weekend
        for(int i=1;i<=remDays;i++){
          c1.add(Calendar.DAY_OF_MONTH, 1);
        if (c1.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY)
            c1.add(Calendar.DAY_OF_MONTH, 1);
        if (c1.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY)
            c1.add(Calendar.DAY_OF_MONTH, 1);
            }
      
        //Skip ending weekend
        if (c1.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY)
            c1.add(Calendar.DAY_OF_MONTH, 1);
        if (c1.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY)
            c1.add(Calendar.DAY_OF_MONTH, 1);
         
      
        //move to 0:00
        c1.clearTime();
          
        return c1.getTime();
    }
  2. Save it.

You can use this in a post-function to set a Date-time picker field. For example Set a Date time picker field to the Due date plus 5 days, excluding weekends. The script in the post-function will be:

return AddDaysExcludingWeekends.addDays(issue.duedate,5)

Check for attachments with a specific extension during a transition

Create a shared validator that checks for attachments of a specific extension were added to the transition screen

  1. Create a shared groovy script, AttachmentValidator, with the following script:

    import com.atlassian.jira.issue.IssueFieldConstants
    import com.atlassian.jira.issue.attachment.Attachment
    import com.atlassian.jira.issue.attachment.TemporaryWebAttachment
    import com.atlassian.jira.issue.attachment.TemporaryWebAttachmentManager
    class AttachmentValidator{
      static fetchAttachments(issue,ext){
        TemporaryWebAttachmentManager attachmentManager = ComponentAccessor.getComponent(TemporaryWebAttachmentManager)
    try {
        List<Long> ids = issue.getModifiedFields().get(IssueFieldConstants.ATTACHMENT).getNewValue();
        if (ids)
            return ids.any { id ->
                def attachment = attachmentManager.getTemporaryWebAttachment(id).getOrNull()
                return attachment?.filename?.endsWith(ext)
            }
    } catch (Exception e) {
    }
        return false
      }
    }
  2. Save it.

Now you can use this in Scripted Groovy validator across transitions to validate the attachments added on the transition screen. Add the Scripted Groovy validator and call the method passing the issue variable and extension as parameters.

AttachmentValidator.fetchAttachments(issue,".pdf")
  • No labels