Skip to end of banner
Go to start of banner

Kepler SIL support for nFeed plugin

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

 

Kepler is not affiliated or in commercial relation(s) with the provider of the nFeed plugin (Valiantys), other than those imposed by the general terms at Atlassian (we're both plugin providers). In other words, this is totally unsupported, wacky (tongue)tweak, can harm you nFeed plugin if not used properly (values on set need to really exist in the DB!), may change in the future (we do not plan support for that).

In fact, you should insert here all the possible warnings you can think of. Just don't blame us.

 

Introduction

This plugin is used to offer SIL support for the SQL Feed Custom Field offered by the nFeed Jira plugin. The nFeed plugin connect your data to JIRA issues by creating custom fields with data from remote files, web services and databases, multi-selecting values from your data sources, creating infinite cascading selections, integrating the notion of conditional requests within JIRA's custom fields. This page show you how this custom field is handled by our Kepler plugins and especially by SIL.

Solution

First of all we needed to create a CF Descriptor that allow us to handle the values that the nFeed Custom Field accepts and returns:

NFeedCFDescriptor
/* 
 * File: NFeedCFDescriptor.java
 */
package com.keplerrominfo.jira.plugins.keplernfeed.nfeedcf;

import java.util.Collection;
import java.util.List;

import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.issue.fields.CustomField;
import com.keplerrominfo.common.util.MutableString;
import com.keplerrominfo.jira.commons.ivm.AbstractCustomFieldDescriptor;
import com.keplerrominfo.sil.lang.*;
import com.keplerrominfo.sil.lang.type.TypeInst;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * The nFeed CF descriptor for nFeed plugin
 *
 * @author Paul Talpiga (paul.talpiga@kepler-rominfo.com)
 * @author Florin Manaila (florin.manaila@kepler-rominfo.com)
 * @author Alexandru Iacob (alexandru.iacob@kepler-rominfo.com)
	* @author Ana-Maria Gologan (ana.gologan@kepler-rominfo.com)
 * @since 1.0
 * @version 4.0.0
 */
public class NFeedCFDescriptor extends AbstractCustomFieldDescriptor<Object, KeyableArraySILObject<MutableString>> {
   
   private static final Log LOG = LogFactory.getLog(NFeedCFDescriptor.class);
   
   /**
    * Constructor
    * @param issue
    * @param customField
    */
   public NFeedCFDescriptor(Issue issue, CustomField customField) {
      super(issue, customField);
   }

   /**
    * @see com.keplerrominfo.jira.commons.ivm.FieldDescriptor#getType()
    */
   @Override
   public SILType<KeyableArraySILObject<MutableString>> getType() {
      return TypeInst.STRING_ARR;
   }
   
   /**
    * @see com.keplerrominfo.jira.commons.ivm.FieldDescriptor
    * #toJiraValue(com.keplerrominfo.sil.lang.value.SILValue)
    */
   @Override
   public Object toJiraValue(SILContext ctx, SILValue<KeyableArraySILObject<MutableString>> value) {
      ClassLoader nfCl = getCustomField().getCustomFieldType().getClass().getClassLoader();
      Object ret;
      try {
         Class clazz = nfCl.loadClass("com.valiantys.jira.plugins.sql.customfield.SQLFeedContent");
         ret = clazz.getConstructor().newInstance();
         clazz.getDeclaredMethod("setValues", List.class).invoke(ret, value.toStringArray());
      } catch (Exception e) {
         String msg = String.format("Could not convert %s to nFeed value", 
                              value.toString());
         LOG.error(msg, e);
         throw new SILException(msg, e);
      }
      return ret;
   }
   
   /**
    * @see com.keplerrominfo.jira.commons.ivm.FieldDescriptor
    * #toSILValue(java.lang.Object)
    */
   @Override
   public SILValue<KeyableArraySILObject<MutableString>> toSILValue(SILContext ctx, Object value) {
        SILValue<KeyableArraySILObject<MutableString>> ret = SILValueFactory.stringArray((Collection<String>)value);
      if(LOG.isDebugEnabled()){
         LOG.debug(String.format("Translated (JIRA) %s to (SIL) %s", 
                           value, ret.toString()));
      }
      return ret;
   }
   
}

 

This class extends the abstract class AbstractCustomFieldDescriptor form Katl-commons plugin. Due to the fact that the nFeed CF accepts only SQLFeedContent objects in order to set the value of this custom field we needed to get this type through Java Reflection. The method toJiraValue() is overridden in order to provide a converter from the SIL Value to the objects that the nFeed CF supports.

The values returned by the nFeed CFs are in fact Collection<String> and this is why we are able to create the SIL value for this CF type in a simple manner only by calling the SILValue constructor.

 

Second, we need to register CF Descriptor. For that, we need our own launcher.:

KeplerNFeedLauncher
/*
 * File: KeplerNFeedLauncher
 */
package com.keplerrominfo.jira.plugins.keplernfeed.admin;


import com.atlassian.event.api.EventPublisher;
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.issue.fields.CustomField;
import com.atlassian.plugin.spring.scanner.annotation.component.ClasspathComponent;
import com.atlassian.plugin.spring.scanner.annotation.export.ExportAsService;
import com.atlassian.plugin.spring.scanner.annotation.imports.ComponentImport;
import com.atlassian.sal.api.lifecycle.LifecycleAware;
import com.keplerrominfo.common.util.MutableString;
import com.keplerrominfo.jira.commons.hostapp.JMUserServices;
import com.keplerrominfo.jira.commons.ivm.*;
import com.keplerrominfo.jira.plugins.keplernfeed.nfeedcf.NFeedCFDescriptor;
import com.keplerrominfo.refapp.config.*;
import com.keplerrominfo.refapp.config.impl.PluginConfigurationServiceImpl;
import com.keplerrominfo.refapp.launcher.AbstractPluginLauncher;
import com.keplerrominfo.sil.lang.KeyableArraySILObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * The launcher for Kepler nFeed plugin
 *
 * @author Ana-Maria Gologan (ana.gologan@kepler-rominfo.com)
 * @version 1.0
 * @since 4.0.0
 */
@Component
@ExportAsService(LifecycleAware.class)
public class KeplerNFeedLauncher extends AbstractPluginLauncher {
    
    private static final String NFEED_CF_KEY =
            "com.valiantys.jira.plugins.SQLFeed:com.valiantys.jira.plugins.sqlfeed.customfield.type";

    private final CustomFieldDescriptorRegistry customFieldDescriptorRegistry;
    
    @Autowired
    public KeplerNFeedLauncher(PluginInfoService pluginInfoService,
                               @ClasspathComponent PluginConfigurationServiceImpl pluginConfigurationService,
                               @ComponentImport EventPublisher eventPublisher,
                               @ComponentImport HostConfigurationProvider hostConfigurationProvider,
                               // needed by UserIsAdministratorCondition from commons. DON'T REMOVE
                               @ComponentImport JMUserServices userServices,
                               // needed by PluginConfigurationServiceImpl above. DON'T REMOVE
                               @ComponentImport CommonPluginConfigurationService commonPluginConfigurationService,
                               @ComponentImport final CustomFieldDescriptorRegistry customFieldDescriptorRegistry) {
        super(eventPublisher, pluginInfoService, hostConfigurationProvider, pluginConfigurationService);
        this.customFieldDescriptorRegistry = customFieldDescriptorRegistry;
    }
    
    @Override
    public void doAtLaunch() {
        super.doAtLaunch();
        customFieldDescriptorRegistry.register(NFEED_CF_KEY, NFEED_CFDF);
    }
    
    @Override
    public void doAtStop() {
        customFieldDescriptorRegistry.unregister(NFEED_CF_KEY);
        super.doAtStop();
    }
    
    private static final CustomFieldDescriptorFactory<Object, KeyableArraySILObject<MutableString>> NFEED_CFDF =
            new AbstractCustomFieldDescriptorFactory<Object, KeyableArraySILObject<MutableString>>(
                    "sil.adapters.cf.nfeed",
                    "nFeed -> string[]",
                    "Translates to an array of string values") {
                @Override
                public FieldDescriptor<Object, KeyableArraySILObject<MutableString>> createDescriptor(Issue issue,
                                                                                                      CustomField cf) {
                    return new NFeedCFDescriptor(issue, cf);
                }
            };
}

The line 58 registers the nFeed CF into our CF translators map.

 

Also, we need to declare some basic information about what we bring to SIL.

KeplerNFeedPluginInfoService
 /*
 * File: KeplerNFeedPluginInfoService
 */
package com.keplerrominfo.jira.plugins.keplernfeed.admin;

import javax.annotation.Nonnull;

import com.keplerrominfo.refapp.config.PluginInfoService;
import org.springframework.stereotype.Component;

/**
 * The Info Service for Kepler nFeed plugin
 *
 * @author Ana-Maria Gologan (ana.gologan@kepler-rominfo.com)
 * @version 1.0
 * @since 4.0.0
 */
@Component
public class KeplerNFeedPluginInfoService implements PluginInfoService {
    
    public static final String PLUGIN_NAME = "Kepler SIL nFeed Support";
    public static final String PLUGIN_KEY = "com.keplerrominfo.jira.plugins.keplernfeed";
    
    @Nonnull
    public String getKey() {
        return PLUGIN_KEY;
    }
    
    @Nonnull
    public String getName() {
        return PLUGIN_NAME;
    }
}

 

 

That is all. You can use this CF in your SIL programs by typing the name of your nFeed custom field - like any other JIRA CF accepted by SIL.

Example
string[] array = nFeed; //where nFeed is your CF name !
return array[0];

Binaries and Sources

Ok, now that you read it through, here they are: the binary (jar) and the sources, packed as zip

  • No labels