Class EpicLinkCFType

java.lang.Object
com.atlassian.jira.issue.customfields.impl.AbstractCustomFieldType<com.atlassian.jira.issue.Issue,com.atlassian.jira.issue.Issue>
com.atlassian.greenhopper.customfield.epiclink.EpicLinkCFType
All Implemented Interfaces:
MetadataCFType, com.atlassian.jira.issue.customfields.CustomFieldType<com.atlassian.jira.issue.Issue,com.atlassian.jira.issue.Issue>, com.atlassian.jira.issue.fields.rest.RestCustomFieldTypeOperations

public class EpicLinkCFType extends com.atlassian.jira.issue.customfields.impl.AbstractCustomFieldType<com.atlassian.jira.issue.Issue,com.atlassian.jira.issue.Issue> implements MetadataCFType, com.atlassian.jira.issue.fields.rest.RestCustomFieldTypeOperations
A custom field type to allow GreenHopper to store extra information about the Epic-Issue relationship in the index.

Singular Object and Transport Object are both Issue, and in particular they are epics. (see CustomFieldType for more details on what these terms mean).

  • Nested Class Summary

    Nested classes/interfaces inherited from class com.atlassian.jira.issue.customfields.impl.AbstractCustomFieldType

    com.atlassian.jira.issue.customfields.impl.AbstractCustomFieldType.Visitor<X>, com.atlassian.jira.issue.customfields.impl.AbstractCustomFieldType.VisitorBase<X>
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    static final CustomFieldMetadata
    the metadata needed to define the custom field in Jira

    Fields inherited from interface com.atlassian.jira.issue.customfields.CustomFieldType

    DEFAULT_VALUE_TYPE, RESOURCE_PREVIEW
  • Constructor Summary

    Constructors
    Modifier
    Constructor
    Description
    protected
    EpicLinkCFType(EpicLinkManager epicLinkManager, com.atlassian.jira.issue.IssueManager issueManager, com.atlassian.jira.bc.issue.IssueService issueService, IssueTypeService issueTypeService, EpicCustomFieldService epicCustomFieldService, com.atlassian.jira.security.JiraAuthenticationContext authCtx, com.atlassian.jira.util.velocity.VelocityRequestContextFactory requestContextFactory, EpicLabelProvider epicLabelProvider, EpicLinkRestFieldOperationsHandler epicLinkRestFieldOperationsHandler, com.atlassian.jira.config.FeatureManager featureManager, com.atlassian.jira.security.PermissionManager permissionManager)
     
  • Method Summary

    Modifier and Type
    Method
    Description
    void
    createValue(com.atlassian.jira.issue.fields.CustomField field, com.atlassian.jira.issue.Issue issue, com.atlassian.jira.issue.Issue epic)
    Save the relationship that epic is the epic for issue to the database.
    getChangelogString(com.atlassian.jira.issue.fields.CustomField field, com.atlassian.jira.issue.Issue value)
     
    getChangelogValue(com.atlassian.jira.issue.fields.CustomField field, com.atlassian.jira.issue.Issue value)
    A changelog item can't be just created inside EpicLinkManager, as usual, as that could result in two separate events/webhooks being fired - one for the epic link change and another one for all of the remaining changed fields on an issue (if there were any other changes).
    com.atlassian.jira.issue.Issue
    getDefaultValue(com.atlassian.jira.issue.fields.config.FieldConfig fieldConfig)
    Return the default value for EpicLinkCFType, which is null.
    getEpicColor(com.atlassian.jira.issue.Issue epic)
    Get the display name for the epic issue.
    Get the color for the epic that corresponds to key.
    getEpicDisplayName(com.atlassian.jira.issue.Issue epic)
    Get the display name for the epic issue.
    Get the display name for the epic that corresponds to key.
    getEpicKey(com.atlassian.jira.issue.Issue epic)
    Get the key for an epic Issue.
    Get the key for the epic Issue corresponding to key.
    getEpicUrl(com.atlassian.jira.issue.Issue epicIssue)
    Get the url for the epic epicIssue.
    getEpicUrl(String epicKey)
    Get the url for the epic that corresponds to key.
    Get an error message signifying that an Issue is not an epic.
    com.atlassian.jira.issue.fields.rest.json.JsonData
    getJsonDefaultValue(com.atlassian.jira.issue.context.IssueContext issueCtx, com.atlassian.jira.issue.fields.CustomField field)
     
     
    com.atlassian.jira.issue.customfields.vdi.NonNullCustomFieldProvider
     
    com.atlassian.jira.issue.fields.rest.RestFieldOperationsHandler
    getRestFieldOperation(com.atlassian.jira.issue.fields.CustomField field)
     
    com.atlassian.jira.issue.Issue
    Use a String representation of an epic Issue (i.e. a String produced by getStringFromSingularObject(Issue)) to retrieve an actual epic Issue object.
    getStringFromSingularObject(com.atlassian.jira.issue.Issue issue)
    Get a String representation of an issue.
    getStringValueFromCustomFieldParams(com.atlassian.jira.issue.customfields.view.CustomFieldParams parameters)
    Get the String representation of the epic stored in parameters.
    Get an error message signifying that an Issue is a subtask.
    com.atlassian.jira.issue.Issue
    getValueFromCustomFieldParams(com.atlassian.jira.issue.customfields.view.CustomFieldParams parameters)
    Retrieve the epic Issue object that corresponds to the epic key stored in parameters if there is one.
    com.atlassian.jira.issue.Issue
    getValueFromIssue(com.atlassian.jira.issue.fields.CustomField field, com.atlassian.jira.issue.Issue issue)
    Get the epic Issue that is currently the epic for issue.
    boolean
    isIssueOfTypeEpic(com.atlassian.jira.issue.Issue issue)
    Check if issue is an epic.
    boolean
    isSubtask(com.atlassian.jira.issue.Issue issue)
    Check whether issue is a subtask.
    remove(com.atlassian.jira.issue.fields.CustomField field)
    This custom field type will never be removed since it is locked and under the control of Jira Agile, so no additional tasks need to performed and no issues would be affected by it.
    void
    setDefaultValue(com.atlassian.jira.issue.fields.config.FieldConfig fieldConfig, com.atlassian.jira.issue.Issue value)
    Set the default value to be used for EpicLinkCFType.
    void
    updateValue(com.atlassian.jira.issue.fields.CustomField field, com.atlassian.jira.issue.Issue issue, com.atlassian.jira.issue.Issue epic)
    Update epic link property for issue, so that it points to epic if epic is not null, or so that it points to nothing if epic is null.
    void
    validateFromParams(com.atlassian.jira.issue.customfields.view.CustomFieldParams relevantParams, com.atlassian.jira.util.ErrorCollection errorCollectionToAddTo, com.atlassian.jira.issue.fields.config.FieldConfig config)
     

    Methods inherited from class com.atlassian.jira.issue.customfields.impl.AbstractCustomFieldType

    accept, assertObjectImplementsType, availableForBulkEdit, getConfigurationItemTypes, getDescription, getDescriptor, getI18nBean, getKey, getName, getVelocityParameters, getVelocityParameters, init, isRenderable, valuesEqual

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

    Methods inherited from interface com.atlassian.jira.issue.customfields.CustomFieldType

    areAllRequiredParametersPresent, getCloneOptionConfiguration, getCloneValue, getIndexers, isUserInputRequiredForMove, requiresAdditionalParams
  • Field Details

    • CUSTOMFIELD_METADATA

      public static final CustomFieldMetadata CUSTOMFIELD_METADATA
      the metadata needed to define the custom field in Jira
  • Constructor Details

    • EpicLinkCFType

      protected EpicLinkCFType(EpicLinkManager epicLinkManager, com.atlassian.jira.issue.IssueManager issueManager, com.atlassian.jira.bc.issue.IssueService issueService, IssueTypeService issueTypeService, EpicCustomFieldService epicCustomFieldService, com.atlassian.jira.security.JiraAuthenticationContext authCtx, com.atlassian.jira.util.velocity.VelocityRequestContextFactory requestContextFactory, EpicLabelProvider epicLabelProvider, EpicLinkRestFieldOperationsHandler epicLinkRestFieldOperationsHandler, com.atlassian.jira.config.FeatureManager featureManager, com.atlassian.jira.security.PermissionManager permissionManager)
  • Method Details

    • getStringFromSingularObject

      public String getStringFromSingularObject(com.atlassian.jira.issue.Issue issue)
      Get a String representation of an issue.

      We use the the key of issue as the String representation. An empty String is returned if issue is null.

      Specified by:
      getStringFromSingularObject in interface com.atlassian.jira.issue.customfields.CustomFieldType<com.atlassian.jira.issue.Issue,com.atlassian.jira.issue.Issue>
      Parameters:
      issue - Issue object to get a String representation for
      Returns:
      String representation of issue

      TODO: should we be checking if Issue is an epic here?

    • getSingularObjectFromString

      @Nullable public com.atlassian.jira.issue.Issue getSingularObjectFromString(@Nullable String epicKey)
      Use a String representation of an epic Issue (i.e. a String produced by getStringFromSingularObject(Issue)) to retrieve an actual epic Issue object.
      Specified by:
      getSingularObjectFromString in interface com.atlassian.jira.issue.customfields.CustomFieldType<com.atlassian.jira.issue.Issue,com.atlassian.jira.issue.Issue>
      Parameters:
      epicKey - String representation of an epic Issue
      Returns:
      Issue object corresponding to epicKey if such an Issue is found, null if null/empty string passed
      Throws:
      com.atlassian.jira.issue.customfields.impl.FieldValidationException - if no corresponding object was found
    • remove

      public Set<Long> remove(com.atlassian.jira.issue.fields.CustomField field)
      This custom field type will never be removed since it is locked and under the control of Jira Agile, so no additional tasks need to performed and no issues would be affected by it.
      Specified by:
      remove in interface com.atlassian.jira.issue.customfields.CustomFieldType<com.atlassian.jira.issue.Issue,com.atlassian.jira.issue.Issue>
      Parameters:
      field - CustomField to be removed
      Returns:
      An empty Set as no issues will be affected by this operation.
    • validateFromParams

      public void validateFromParams(com.atlassian.jira.issue.customfields.view.CustomFieldParams relevantParams, com.atlassian.jira.util.ErrorCollection errorCollectionToAddTo, com.atlassian.jira.issue.fields.config.FieldConfig config)
      Specified by:
      validateFromParams in interface com.atlassian.jira.issue.customfields.CustomFieldType<com.atlassian.jira.issue.Issue,com.atlassian.jira.issue.Issue>
    • createValue

      public void createValue(com.atlassian.jira.issue.fields.CustomField field, @Nonnull com.atlassian.jira.issue.Issue issue, @Nonnull com.atlassian.jira.issue.Issue epic)
      Save the relationship that epic is the epic for issue to the database.
      Specified by:
      createValue in interface com.atlassian.jira.issue.customfields.CustomFieldType<com.atlassian.jira.issue.Issue,com.atlassian.jira.issue.Issue>
      Parameters:
      field - CustomField (not used here but necessary for overriding super class)
      issue - Issue to associate with epic with (should not be null)
      epic - Issue being linked to (should not be null)
    • updateValue

      public void updateValue(com.atlassian.jira.issue.fields.CustomField field, @Nonnull com.atlassian.jira.issue.Issue issue, com.atlassian.jira.issue.Issue epic)
      Update epic link property for issue, so that it points to epic if epic is not null, or so that it points to nothing if epic is null.
      Specified by:
      updateValue in interface com.atlassian.jira.issue.customfields.CustomFieldType<com.atlassian.jira.issue.Issue,com.atlassian.jira.issue.Issue>
      Parameters:
      field - CustomField (not used here but necessary for overriding super class)
      issue - Issue to associate epic with (should not be null)
      epic - Issue being linked to, or null to remove an existing epic value from the issue
    • getValueFromCustomFieldParams

      public com.atlassian.jira.issue.Issue getValueFromCustomFieldParams(com.atlassian.jira.issue.customfields.view.CustomFieldParams parameters)
      Retrieve the epic Issue object that corresponds to the epic key stored in parameters if there is one.
      Specified by:
      getValueFromCustomFieldParams in interface com.atlassian.jira.issue.customfields.CustomFieldType<com.atlassian.jira.issue.Issue,com.atlassian.jira.issue.Issue>
      Parameters:
      parameters - CustomFieldParams that contains the epic key
      Returns:
      Issue object corresponding to the epic key stored in parameters, null if null/empty string passed
      Throws:
      com.atlassian.jira.issue.customfields.impl.FieldValidationException - if we could find no such object
    • getStringValueFromCustomFieldParams

      public Object getStringValueFromCustomFieldParams(com.atlassian.jira.issue.customfields.view.CustomFieldParams parameters)
      Get the String representation of the epic stored in parameters.
      Specified by:
      getStringValueFromCustomFieldParams in interface com.atlassian.jira.issue.customfields.CustomFieldType<com.atlassian.jira.issue.Issue,com.atlassian.jira.issue.Issue>
      Parameters:
      parameters - CustomFieldParams storing the epic String representation
      Returns:
      String representation of epic
    • getValueFromIssue

      @Nullable public com.atlassian.jira.issue.Issue getValueFromIssue(com.atlassian.jira.issue.fields.CustomField field, com.atlassian.jira.issue.Issue issue)
      Get the epic Issue that is currently the epic for issue.
      Specified by:
      getValueFromIssue in interface com.atlassian.jira.issue.customfields.CustomFieldType<com.atlassian.jira.issue.Issue,com.atlassian.jira.issue.Issue>
      Parameters:
      field - CustomField (not used here but necessary for overriding super class)
      issue - Issue to retrieve the epic for
      Returns:
      the current epic of issue, or null if operation was unsuccessful
    • getNonNullCustomFieldProvider

      public com.atlassian.jira.issue.customfields.vdi.NonNullCustomFieldProvider getNonNullCustomFieldProvider()
      Specified by:
      getNonNullCustomFieldProvider in interface com.atlassian.jira.issue.customfields.CustomFieldType<com.atlassian.jira.issue.Issue,com.atlassian.jira.issue.Issue>
    • getDefaultValue

      public com.atlassian.jira.issue.Issue getDefaultValue(com.atlassian.jira.issue.fields.config.FieldConfig fieldConfig)
      Return the default value for EpicLinkCFType, which is null.
      Specified by:
      getDefaultValue in interface com.atlassian.jira.issue.customfields.CustomFieldType<com.atlassian.jira.issue.Issue,com.atlassian.jira.issue.Issue>
      Parameters:
      fieldConfig - FieldConfig (not used here but necessary for overriding super class)
      Returns:
      the default EpicLinkCFType val: null
    • setDefaultValue

      public void setDefaultValue(com.atlassian.jira.issue.fields.config.FieldConfig fieldConfig, com.atlassian.jira.issue.Issue value)
      Set the default value to be used for EpicLinkCFType. This is a no-op.
      Specified by:
      setDefaultValue in interface com.atlassian.jira.issue.customfields.CustomFieldType<com.atlassian.jira.issue.Issue,com.atlassian.jira.issue.Issue>
      Parameters:
      fieldConfig - FieldConfig (not used here but necessary for overriding super class)
      value - Issue (not used here but necessary for overriding super class)
    • getChangelogValue

      public String getChangelogValue(com.atlassian.jira.issue.fields.CustomField field, com.atlassian.jira.issue.Issue value)
      A changelog item can't be just created inside EpicLinkManager, as usual, as that could result in two separate events/webhooks being fired - one for the epic link change and another one for all of the remaining changed fields on an issue (if there were any other changes).
      Specified by:
      getChangelogValue in interface com.atlassian.jira.issue.customfields.CustomFieldType<com.atlassian.jira.issue.Issue,com.atlassian.jira.issue.Issue>
    • getChangelogString

      public String getChangelogString(com.atlassian.jira.issue.fields.CustomField field, com.atlassian.jira.issue.Issue value)
      Specified by:
      getChangelogString in interface com.atlassian.jira.issue.customfields.CustomFieldType<com.atlassian.jira.issue.Issue,com.atlassian.jira.issue.Issue>
      Overrides:
      getChangelogString in class com.atlassian.jira.issue.customfields.impl.AbstractCustomFieldType<com.atlassian.jira.issue.Issue,com.atlassian.jira.issue.Issue>
    • getMetadata

      public CustomFieldMetadata getMetadata()
      Specified by:
      getMetadata in interface MetadataCFType
    • getEpicKey

      public String getEpicKey(String key)
      Get the key for the epic Issue corresponding to key.

      NB: there are two methods called getEpicKey, since we aren't sure what sort of object will be passed to us from the velocity templates edit-epiclink.vm and view-epiclink.vm, which is where these methods are currently being called from. We might be passed a String or an actual Issue object, depending on what Jira injects into the templates.

      It seems like this could just be the Identity function. Despite this, we can't get rid of it, since we don't know whether the velocity template has a String or Issue as the value.

      Parameters:
      key - String that is the key for an epic Issue
      Returns:
      the key for the corresponding epic Issue
    • getEpicKey

      public String getEpicKey(@Nullable com.atlassian.jira.issue.Issue epic)
      Get the key for an epic Issue.

      NB: there are two methods called getEpicKey, since we aren't sure what sort of object will be passed to us from the velocity templates edit-epiclink.vm and view-epiclink.vm, which is where these methods are currently being called from. We might be passed a String or an actual Issue object, depending on what Jira injects into the templates.

      Parameters:
      epic - Issue that we want to get the key for
      Returns:
      the key for epic or null if epic is null
    • getEpicDisplayName

      public String getEpicDisplayName(String key)
      Get the display name for the epic that corresponds to key.

      NB: there are two methods called getEpicDisplayName, since we aren't sure what sort of object will be passed to us from the velocity templates edit-epiclink.vm and view-epiclink.vm, which is where these methods are currently being called from. We might be passed a String or an actual Issue object, depending on what Jira injects into the templates.

      Parameters:
      key - String that is the key for an epic Issue
      Returns:
      the display name for the corresponding epic Issue
    • getEpicDisplayName

      public String getEpicDisplayName(@Nullable com.atlassian.jira.issue.Issue epic)
      Get the display name for the epic issue.

      NB: there are two methods called getEpicDisplayName, since we aren't sure what sort of object will be passed to us from the velocity templates edit-epiclink.vm and view-epiclink.vm, which is where these methods are currently being called from. We might be passed a String or an actual Issue object, depending on what Jira injects into the templates.

      Parameters:
      epic - Issue that we want to get the displayName for
      Returns:
      the displayName for epic or null if epic is null
    • getEpicColor

      public String getEpicColor(String key)
      Get the color for the epic that corresponds to key.

      NB: there are two methods called getEpicColor, since we aren't sure what sort of object will be passed to us from the velocity templates edit-epiclink.vm and view-epiclink.vm, which is where these methods are currently being called from. We might be passed a String or an actual Issue object, depending on what Jira injects into the templates.

      Parameters:
      key - String that is the key for an epic Issue
      Returns:
      the color for the corresponding epic Issue
    • getEpicColor

      public String getEpicColor(@Nullable com.atlassian.jira.issue.Issue epic)
      Get the display name for the epic issue.

      NB: there are two methods called getEpicColor, since we aren't sure what sort of object will be passed to us from the velocity templates edit-epiclink.vm and view-epiclink.vm, which is where these methods are currently being called from. We might be passed a String or an actual Issue object, depending on what Jira injects into the templates.

      Parameters:
      epic - Issue that we want to get the color for
      Returns:
      the color for epic or null if epic is null
    • isIssueOfTypeEpic

      public boolean isIssueOfTypeEpic(@Nonnull com.atlassian.jira.issue.Issue issue)
      Check if issue is an epic.

      Note: this method needs to be public since it being used from within the velocity template edit-epiclink.vm.

      Parameters:
      issue - Issue to check (should not be null)
      Returns:
      true if issue is an epic and false otherwise
    • isSubtask

      public boolean isSubtask(@Nonnull com.atlassian.jira.issue.Issue issue)
      Check whether issue is a subtask.

      Note: this method needs to be public since it being used from within the velocity template edit-epiclink.vm.

      Parameters:
      issue - Issue to check (should not be null)
      Returns:
      true is issue is a subtask and false otherwise
    • getIssueOfTypeEpicErrorMessage

      public String getIssueOfTypeEpicErrorMessage()
      Get an error message signifying that an Issue is not an epic.

      Note: this is used by velocity templates such as edit-epiclink.vm.

      Returns:
      the error message
    • getSubtaskErrorMessage

      public String getSubtaskErrorMessage()
      Get an error message signifying that an Issue is a subtask.

      Note: this is used by velocity templates such as edit-epiclink.vm.

      Returns:
      the error message
    • getEpicUrl

      public String getEpicUrl(String epicKey)
      Get the url for the epic that corresponds to key.

      NB: there are two methods called getEpicUrl, since we aren't sure what sort of object will be passed to us from the velocity template view-epiclink.vm, which is where these methods are currently being called from. We might be passed a String or an actual Issue object, depending on what Jira injects into the template.

      Parameters:
      epicKey - String that is the key for an epic Issue
      Returns:
      the url for the corresponding epic Issue
    • getEpicUrl

      public String getEpicUrl(@Nullable com.atlassian.jira.issue.Issue epicIssue)
      Get the url for the epic epicIssue.

      NB: there are two methods called getEpicUrl, since we aren't sure what sort of object will be passed to us from the velocity template view-epiclink.vm, which is where these methods are currently being called from. We might be passed a String or an actual Issue object, depending on what Jira injects into the template.

      Parameters:
      epicIssue - Issue we want the url for
      Returns:
      the url for epicIssue or an empty string if epicIssue is null
    • getRestFieldOperation

      public com.atlassian.jira.issue.fields.rest.RestFieldOperationsHandler getRestFieldOperation(com.atlassian.jira.issue.fields.CustomField field)
      Specified by:
      getRestFieldOperation in interface com.atlassian.jira.issue.fields.rest.RestCustomFieldTypeOperations
    • getJsonDefaultValue

      public com.atlassian.jira.issue.fields.rest.json.JsonData getJsonDefaultValue(com.atlassian.jira.issue.context.IssueContext issueCtx, com.atlassian.jira.issue.fields.CustomField field)
      Specified by:
      getJsonDefaultValue in interface com.atlassian.jira.issue.fields.rest.RestCustomFieldTypeOperations