Skip to main content
RSS feed Subscribe to feed

 

How to Create an Information Link Tool

An information link is a configured request to a database. Information link configuring and opening can be automated. The API provides methods to find a link, to get and set its parameters, and launch the browse information link user interface. This tutorial describes a tool populating parameters on an informaton link.

Overview

From Spotfire 2.2 custom tool developers can open Information Links via the API in a controlled manner.

About this Tutorial

The SDK provides the tool discussed below. It enables the user to browse for an information link, populating and displaying its parameters, and enabling the user to alter them before opening it:

Tool handling information link parameters
Prerequisites
  • Spotfire SDK\Examples\Extensions\SpotfireDeveloper.InformationLinkToolExample

Additional Examples

Concepts and Classes

This small information link API provides a small but powerful set of classes and methods corresponding to clearly delimited tasks.

Finding Links

The FindAll method returns an InformationLinkDescriptorCollection. This collection holds a list of all identifiers for information links matching a search expression.

Metadata for matching information links is accessed by enumerating the collection, or using the First property returning the first value of the enumeration. The metadata is represented by the an InformationLinkDescriptor.

Displaying the UI to Browse for Information Link

If allowed, the BrowseForInformationLink method launches the browsing user interface otherwise accessed from the File > Open From > InformationLink... menu. This UI is also launched, if allowed, when no information link is found corresponding to the given identifier when performing Connect on the InformationLinkDataSource.

Determining Parameters to Set on an Information Link

The InformationLinkDescriptor has properties for the different types of information link parameters:

The GetReferencedElementDescriptor method is used to get an InformationModelElementDescriptor corresponding to the ElementId of the parameter. This way a custom tool can ensure that the correct values are set for the corresponding parameter.

Setting the parameters of an infomration link

If an information link identifier is known and its parameters should be set, the GetInformationLinkDescriptor method may be used. It only returns descriptors for information links or null, while the GetReferencedElementDescriptor method of InformationLinkDescriptor returns descriptors only for columns, filters and procedures referenced by the information link.

Implementation

The logic is provided in the OpenInformationLinkForm.cs file reads the parameters from the information link, populates the UI and, when the user clicks Open, creates new parameters:

namespace SpotfireDeveloper.InformationLinkToolExample
{

    /// <summary>
    /// This UI allows a user to browse for an InformationLink and populate all parameters (if any) for that InformationLink.
    /// </summary>
    public partial class OpenInformationLinkForm : Form
    {
        private OpenInformationLinkToolSettings settings;

        /// <summary>
        /// Constructor
        /// </summary>
        public OpenInformationLinkForm()
        {
            InitializeComponent();

            this.okButton.Enabled = false;
        }

        /// <summary>
        /// Constructor taking the prompt model.
        /// </summary>
        /// <param name="settings">The prompt model for this UI.</param>
        public OpenInformationLinkForm(OpenInformationLinkToolSettings settings)
            :this()
        {
            this.settings = settings;

            if (settings.Link != null)
            {
                fileTextBox.Text = settings.Link.Path;
            }
        }

        private void fileTextBox_TextChanged(object sender, EventArgs e)
        {
            // Enabling or disabling the Open button.
            this.okButton.Enabled = !string.IsNullOrEmpty(fileTextBox.Text);
        }

        private void browseButton_Click(object sender, EventArgs e)
        {
            // Launch a Browse UI for locating an Information Link.
            settings.Link = InformationLinkDataSource.BrowseForInformationLink();

            // Set the path (including name) of the selected InformationLink.
            fileTextBox.Text = settings.Link == null ? null : settings.Link.Path;
            PopulateParameterGrid();
        }

        /// <summary>
        /// Populate all three GridViews.
        /// </summary>
        private void PopulateParameterGrid()
        {
            // Clear all GridViews.
            referencedGridView.Rows.Clear();
            namedGridView.Rows.Clear();
            filterGridView.Rows.Clear();
            
            if (settings.Link != null)
            {
                try
                {

                    // Get referenced parameters (that is, parameters for procedures referenced by the InformationLink).
                    foreach (InformationLinkParameter parameter in settings.Link.ReferencedParameters)
                    {
                        referencedGridView.Rows.Add(parameter.ParameterId, GetTypeObject(parameter.DataType).DefaultValue);
                    }

                    // Get named parameters.
                    foreach (InformationLinkParameter parameter in settings.Link.NamedParameters)
                    {
                        namedGridView.Rows.Add(parameter.ParameterId, GetTypeObject(parameter.DataType).DefaultValue);
                    }

                    // Get filter parameters (that is, the column prompts on the InformationLink).
                    foreach (InformationLinkParameter parameter in settings.Link.FilterParameters)
                    {
                        filterGridView.Rows.Add(settings.Link.GetReferencedElementDescriptor(parameter.ElementId).Name, GetTypeObject(parameter.DataType).DefaultValue);
                    }
                }
                catch (ImportException ie)
                {
                    MessageBox.Show(ie.Message + "\n" + ie.StackTrace, Properties.Resources.ToolMenuTitle);
                }
            }
        }

        private void okButton_Click(object sender, EventArgs args)
        {
            // Set combined parameter list from this UI on the prompt model.
            try
            {
                settings.Parameters = SetParameters();
                DialogResult = DialogResult.OK;
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message + "\n" + e.StackTrace, Properties.Resources.ToolMenuTitle);
                DialogResult = DialogResult.None;
            }
        }

        /// <summary>
        /// Parse the values from the UI and create parameter objects.
        /// </summary>
        /// <returns>A list of parameters to use in the <see cref="InformationLinkDataSource"/> constructor.</returns>
        private IList<InformationLinkParameter> SetParameters()
        {
            // Create a result list.
            IList<InformationLinkParameter> parameters = new List<InformationLinkParameter>();

            // Create referenced parameters (that is, parameters for procedures referenced by the InformationLink).
            for(int i = 0; i < settings.Link.ReferencedParameters.Count; ++i)
            {
                // Get the parameter from the InformationLink.
                InformationLinkParameter parameter = settings.Link.ReferencedParameters[i];

                // Read value from UI, convert it to right type and store it in an object array.
                Object[] values = CreateObjectArray(parameter.DataType, referencedGridView.Rows[i].Cells[1].Value);

                // Create a new parameter with the values using elementId and parameterId from the parameter of the InformationLink.
                // Only include those parameters that the user has assigned values to.
                if (values != null)
                {
                    InformationLinkParameter newParameter =
                        InformationLinkParameter.CreateReferencedParameter(parameter.ElementId, parameter.ParameterId, values);

                    // Add it to the result list.
                    parameters.Add(newParameter);
                }
            }

            for(int i = 0; i < settings.Link.FilterParameters.Count; ++i)
            {

                // Get the parameter from the InformationLink.
                InformationLinkParameter parameter = settings.Link.FilterParameters[i];

                // Read value from UI, convert it to the correct type and store it in an object array.
                Object[] values = CreateObjectArray(parameter.DataType, filterGridView.Rows[i].Cells[1].Value);

                // Create a new parameter with the values using elementId from the parameter of the InformationLink.
                // Only include those parameters that the user has assigned values to.
                if (values != null)
                {
                    InformationLinkParameter newParameter =
                        InformationLinkParameter.CreateFilterParameter(parameter.ElementId, "%Column% in (%Values%)", values);

                    // Add it to the result list.
                    parameters.Add(newParameter);
                }
            }

            for (int i = 0; i < settings.Link.NamedParameters.Count; ++i)
            {

                // Get the parameter from the InformationLink.
                InformationLinkParameter parameter = settings.Link.NamedParameters[i];

                // Read value from UI, convert it to correct type and store it in an object array.
                Object[] values = CreateObjectArray(parameter.DataType, namedGridView.Rows[i].Cells[1].Value);

                // Create a new parameter with the values using ParameterId from the parameter of the InformationLink.
                // Only include those parameters that the user has assigned values to.
                if (values != null)
                {
                    InformationLinkParameter newParameter = InformationLinkParameter.CreateNamedParameter(parameter.ParameterId, values);

                    // Add it to the result list.
                    parameters.Add(newParameter);
                }
            }

            return parameters;

        }

        /// <summary>
        /// Create an array only containing the value (parsed to given datatype).
        /// </summary>
        /// <param name="dataType">string representation of the datasource data type.</param>
        /// <param name="value">value that may have the correct type, but most likely is string.</param>
        /// <returns></returns>
        private Object[] CreateObjectArray(string dataType, object value)
        {
            // Get DataType corresponding to given dataType string.
            DataType type = GetTypeObject(dataType);
            
            // Put result into an array if not null.
            return value == null ? null : new Object[] {type.Formatter.Parse(value.ToString())};

        }

        /// <summary>
        /// Get corresponding <see cref="DataType"/> to given string (DataType.Undefined if not found).
        /// </summary>
        /// <param name="dataType">string representation of datasource data type.</param>
        /// <returns></returns>
        private DataType GetTypeObject(string dataType)
        {
            switch(dataType.ToLower())
            {
                case("string") : return DataType.String;
                case("integer") : return DataType.Integer;
                case("real") : return DataType.Real;
                case("date") : return DataType.Date;
                case("time") : return DataType.Time;
                case("datetime") : return DataType.DateTime;
                case("clob") : return DataType.String;
                case("blob") : return DataType.Binary;
                default : return DataType.Undefined;
            }
        }
    }
}