Service for updating select-list values

Here is some sample code for a JIRA service which populates or updates the values of a custom field select list.

In this example, the service deletes any existing options, and repopulates the options with versions from all JIRA projects. It is written for JIRA 3.4.x.

package com.atlassian.jira.service.services;

import com.atlassian.configurable.ObjectConfiguration;
import com.atlassian.configurable.ObjectConfigurationException;
import com.atlassian.jira.service.AbstractService;
import com.atlassian.jira.issue.customfields.manager.OptionsManager;
import com.atlassian.jira.issue.customfields.option.Options;
import com.atlassian.jira.issue.fields.CustomField;
import com.atlassian.jira.issue.fields.config.FieldConfig;
import com.atlassian.jira.issue.CustomFieldManager;
import com.atlassian.jira.issue.context.IssueContextImpl;
import com.atlassian.jira.ManagerFactory;
import com.atlassian.jira.ComponentManager;
import com.atlassian.jira.config.ConstantsManager;
import com.atlassian.jira.project.ProjectManager;
import com.atlassian.jira.project.version.VersionManager;
import com.atlassian.jira.project.version.Version;

import java.util.Iterator;

import org.ofbiz.core.entity.GenericValue;

/**
 * A sample Service which updates the available options in a custom select-list field. In this example, we make the options
 * the available versions from all projects.
 */
public class UpdateCustomFieldOptionsService extends AbstractService {

    private static org.apache.log4j.Category log = org.apache.log4j.Category.getInstance(UpdateCustomFieldOptionsService.class);

    public void run() {
        log.debug(getClass() + " running");

        OptionsManager optionsManager = ManagerFactory.getOptionsManager();
        CustomFieldManager cfManager = ManagerFactory.getCustomFieldManager();
        ProjectManager projectManager = ManagerFactory.getProjectManager();
        ConstantsManager constantsManager = ManagerFactory.getConstantsManager();

        CustomField cf = null;
        try {
            cf = cfManager.getCustomFieldObjectByName(getProperty("customfieldname"));
        } catch (ObjectConfigurationException e) {
            log.error(e, e);
            return;
        }
        if (cf == null) {
            log.error("Unknown custom field");
            return;
        }

        GenericValue projectGV = null;
        try {
            String projectKey = getProperty("projectkey");
            projectGV = projectManager.getProjectByKey(projectKey);
        } catch (ObjectConfigurationException e) {
            log.error("Unknown project key: " + e);
        }
        GenericValue issueTypeGV = null;
        try {
            String issueTypeId = getProperty("issuetypeid");
            issueTypeGV = constantsManager.getIssueType(issueTypeId);
        } catch (ObjectConfigurationException e) {
            log.error("Unknown issue type: " + e);
        }

        // Since custom field options can be different for {project : issue type} pairs, we ask the
        // user for a project and issue type when configuring the service. The {project : issue type} scope object
        // is the 'issue context' object here.
        IssueContextImpl issueContext = new IssueContextImpl(projectGV, issueTypeGV);
        FieldConfig fieldConfig = cf.getRelevantConfig(issueContext);

        Options options = optionsManager.getOptions(fieldConfig);        setOptions(options);

        optionsManager.updateOptions(options);

        // retrieve options again, as after the update our copy ('options') will be stale.
        options = optionsManager.getOptions(fieldConfig);

        // Sort options
//        options.sortOptionsByValue(null);
    }

    private void setOptions(Options options)
    {
        options.removeAll(options);
        ProjectManager pm = ComponentManager.getInstance().getProjectManager();
        VersionManager vm = ComponentManager.getInstance().getVersionManager();
        Iterator iter = pm.getProjects().iterator();
        while (iter.hasNext()) {
            GenericValue proj = (GenericValue) iter.next();
            Iterator iter2 = vm.getVersions(proj).iterator();
            while (iter2.hasNext()) {
                Version version = (Version) iter2.next();
                System.out.println("Adding version "+version.getName()+" from project "+proj);
                options.addOption(null, version.getName());
            }
        }
    }


    public String getDescription() {
        return "Service which adds new options to a custom field";
    }

    public ObjectConfiguration getObjectConfiguration() throws ObjectConfigurationException {
        return getObjectConfiguration("UPDATECUSTOMFIELDOPTIONSSERVICE", "services/com/atlassian/jira/service/services/updatecustomfieldoptionsservice.xml", null);
    }
}

and updatecustomfieldoptionsservice.xml:

<debugservice id="updateCFoptionsservice">
    <description>
    </description>
    <properties>
        <property>
            <key>customfieldname</key>
            <name>Select list custom field name</name>
            <type>string</type>
        </property>
        <property>
            <key>projectkey</key>
            <name>Project (empty = all)</name>
            <type>string</type>
        </property>
        <property>
            <key>issuetypeid</key>
            <name>Issue Type Id (1=bug, 2=feature, etc. Empty = all)</name>
            <type>string</type>
        </property>
    </properties>
</debugservice>

Installation

In JIRA 3.4.x Standalone, this can be installed by:

  1.  downloading the updateselectlist_service.zipattachment
  2. unzip in JIRA Standalone root directory
  3. cd to 'external-sources'
  4. Run 'ant' to compile into JIRA Standalone (you'll need to download Apache Antif you don't already have it)
  5. Restart JIRA Standalone
  6. In JIRA, configure a new Service, with class name com.atlassian.jira.service.services.UpdateCustomFieldOptionsService. You will need to configure it  to point to a select-list custom field.
  7. Watch the logs for any problems.

Related documentation

Automating JIRA operations via wget - it's possible to automate the addition of custom field options from the command-line.
Issue fields - docs on how custom fields store select-list options.

Labels

 
(None)
  1. Nov 30, 2007

    Simone Ferrari says:

    Are you sure that the service delete the previous options in the field ??? I try...

    Are you sure that the service delete the previous options in the field ???

    I try but the option at the end of the second cycle are double ...