Skip to end of banner
Go to start of banner

Step 3: Creating a Custom Field Descriptor

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 3 Next »

Project Picker CF

Let's say you need to provide support for a certain custom field. Power Scripts for Jira does offer support for the project picker CF but for educational purposes, let's see how you could add the support if it didn't.


The task is to register a translator from SILValue to the native object type and the other way around.

The code is presented below:

ProjectCFDescriptor.java
/*
 * Created at: 3/28/13, 3:02 PM  
 * 
 * File: ProjectCFDescriptor.java
 */
package com.mycompany.silexample;

import com.atlassian.jira.project.Project;
import com.atlassian.jira.project.ProjectManager;
import com.keplerrominfo.sil.lang.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.ofbiz.core.entity.GenericValue;

import com.keplerrominfo.common.util.MutableString;
import com.keplerrominfo.common.util.StringUtils;
import com.keplerrominfo.jira.commons.ivm.FieldDescriptor;
import com.keplerrominfo.sil.lang.type.TypeInst;

/**
 * The project CF descriptor, com.atlassian.jira.plugin.system.customfieldtypes:project
 *
 * @author Radu Dumitriu (rdumitriu@gmail.com)
 */
public class ProjectCFDescriptor implements FieldDescriptor<GenericValue, MutableString> {
    //This template class tells us that the values exchanged are GenericValue (JIRA side) and MutableString (SIL)

    private static final Log LOG = LogFactory.getLog(ProjectCFDescriptor.class);
    
    private final ProjectManager projectManager;
    
    
    public ProjectCFDescriptor(ProjectManager projectManager) {
        this.projectManager = projectManager;
    }
    
    @Override
    public SILType<MutableString> getType() {
        return TypeInst.STRING;
    }


    @Override
    public GenericValue toJiraValue(SILContext ctx, SILValue<MutableString> value) {
        String projectKey = StringUtils.trim(value.toStringValue());
        if (projectKey == null) {
            return null;
        }
        Project project = projectManager.getProjectObjByKey(projectKey);
        if(project == null) {
            LOG.warn(String.format(">>%s<< is not a valid project key", projectKey));
            return null;
        }
        // Project picker CF stores the value as GenericValue. This is deprecated, but we need to call it
        return project.getGenericValue();
    }

    @Override
    public SILValue<MutableString> toSILValue(SILContext ctx, GenericValue value) {
        return value != null ? SILValueFactory.string(value.getString("key")) : SILValueFactory.string();
    }
}


Register a CF descriptor in the launcher:

BundleActivator.java
@Override
public void doAtLaunch() {
    super.doAtLaunch();

    //register the routine
    RoutineRegistry.register(new ReverseStringRoutine("myReverseString"));

    //register the CF descriptor
    customFieldDescriptorRegistry.register("com.atlassian.jira.plugin.system.customfieldtypes:project", //this is the real key of the CF
            new AbstractCustomFieldDescriptorFactory(
                    "example.project.cfdf", //internal identification. Must be unique in the SIL system
                    "Project Key to String", //short description, followed by a longer one
                    "Extract the project key using GenericValue or project") {

				// Descriptors are created when needed, and some of them might be contextual. This is why you register here a creator of a
			    // descriptor and not the real descriptor
			    @Override
                public FieldDescriptor createDescriptor(Issue issue, CustomField cf) {
                    return new ProjectCFDescriptor(projectManager);
                }
            }
    );
}

@Override
public void doAtStop() {
    //first, make sure that super is called, even if it has an exception here
    try {
        //unregister the routine
        RoutineRegistry.unregister("myReverseString");
        
        //unregister the CF descriptor
        customFieldDescriptorRegistry.unregister("com.atlassian.jira.plugin.system.customfieldtypes:project");  //this is the real key of the CF
    } catch(Exception e) {
        LOG.error("Failed to unregister!", e);
    }
    
    super.doAtStop();
}


Line 9 registers the CF into our CF translators map. Hooray!


That's all you need. You can now play with SIL like such:

something.sil
summary += " -- " + KProject; //where KProject is your CF name!
  • No labels