jetbrains.buildServer.issueTracker
Class AbstractIssueProvider

java.lang.Object
  extended by jetbrains.buildServer.issueTracker.AbstractIssueProvider
All Implemented Interfaces:
IssueBatchProviderSupport, IssueProvider, SIssueProvider
Direct Known Subclasses:
AbstractPrefixBasedIssueProvider

public abstract class AbstractIssueProvider
extends java.lang.Object
implements SIssueProvider

Represents a default implementation of IssueProvider interface. This class resolves related issues using pattern matching, and fetches them using IssueFetcher.

Class doesn't use any cache (fetcher does).

Author:
Maxim Podkolzine (maxim.podkolzine@jetbrains.com)

Field Summary
protected static java.util.regex.Pattern EMPTY_PATTERN
           
protected  org.apache.commons.httpclient.Credentials myCredentials
           
protected  IssueFetcher myFetcher
           
protected  java.lang.String myHost
           
protected  java.util.regex.Pattern myPattern
           
protected  java.util.Map<java.lang.String,java.lang.String> myProperties
           
protected  java.lang.String myType
           
 
Fields inherited from interface jetbrains.buildServer.issueTracker.IssueProvider
SECURE_PROPERTY_PREFIX
 
Constructor Summary
protected AbstractIssueProvider(java.util.regex.Pattern pattern, IssueFetcher fetcher)
           
  AbstractIssueProvider(java.lang.String type, IssueFetcher fetcher)
           
 
Method Summary
protected  java.lang.String checkIssueIdBeforeTestConnection(java.lang.String issueId)
           
protected static java.util.regex.Pattern compileDisjunction(java.lang.String prefixes, java.lang.String suffix)
          Given a string containing the prefixes, composes the reg.exp pattern that accepts any of them plus suffix.
protected  java.util.regex.Pattern compilePattern(java.util.Map<java.lang.String,java.lang.String> properties)
           
 void dispose()
          Disposes the provider (releases all necessary resources, dumps caches on disk, etc).
protected  java.lang.String extractId(java.lang.String match)
           
 IssueData findIssueById(java.lang.String id)
          Returns the issue by the specified id.
 java.util.Map<java.lang.String,IssueData> findIssuesByIds(java.util.Collection<java.lang.String> ids)
          Finds and returns the specified collection of issue ids.
protected  java.util.Map<java.lang.String,IssueData> findIssuesByIdsImpl(java.util.Collection<java.lang.String> ids)
           
 IssueData findPossiblyExpiredIssue(java.lang.String id)
          Returns the issue data corresponding to the id.
 CommentTransformationHelper getCommentTransformationHelper()
          Returns the instance of helper class to support comment transformation (i.e.
 java.lang.String getConfigurationSummary()
          Returns the basic summary of current configuration, for instance, "Jira" provider might return: "Projects: P1, P2".
 java.util.Map<java.lang.String,java.lang.String> getProperties()
          Returns the map of provider properties.
 PropertiesProcessor getPropertiesProcessor()
          Returns the properties processor instance (validator).
 java.util.Collection<IssueMention> getRelatedIssues(java.lang.String comment)
          Returns the collection of issues related, or mentioned in the comment.
 java.util.Collection<IssueMention> getRelatedIssues(VcsModification modification)
          Returns the collection of issues related to a modification.
 IssueTestConnectionSupport getTestConnectionSupport()
          Returns the test connection support.
 java.lang.String getType()
          Returns the type of this provider (the type of the corresponding factory).
 boolean isBatchFetchSupported()
          Returns whether the issue provider supports fetching in batch.
 boolean isFailedToFetch(java.lang.String id)
          Returns whether the issue could not be fetched due to error.
 boolean isFetched(java.lang.String id)
          Returns whether the issue is fetched and can be efficiently returned using IssueProvider.findIssueById(String) method.
 boolean isHasRelatedIssues(java.lang.String comment)
          Returns whether there are related issues in the specified comment.
 boolean isHasRelatedIssues(VcsModification modification)
          Returns whether there are related issues in the specified modification.
protected  boolean quickCheck(java.lang.String comment)
          Helper methods.
protected static java.util.regex.Pattern safeCompile(java.lang.String pattern)
          The same as Pattern.compile(pattern), but returns an empty pattern if the provided pattern is incorrect.
protected  java.lang.String sanitizeHost(java.lang.String host)
           
 void setProperties(java.util.Map<java.lang.String,java.lang.String> map)
          Sets the provider properties (see IssueProvider.getProperties() method for the details).
 java.lang.String toString()
           
protected  boolean useIdPrefix()
           
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

EMPTY_PATTERN

protected static final java.util.regex.Pattern EMPTY_PATTERN

myType

protected final java.lang.String myType

myHost

protected java.lang.String myHost

myCredentials

protected org.apache.commons.httpclient.Credentials myCredentials

myPattern

protected java.util.regex.Pattern myPattern

myProperties

protected java.util.Map<java.lang.String,java.lang.String> myProperties

myFetcher

protected final IssueFetcher myFetcher
Constructor Detail

AbstractIssueProvider

public AbstractIssueProvider(@NotNull
                             java.lang.String type,
                             @NotNull
                             IssueFetcher fetcher)

AbstractIssueProvider

protected AbstractIssueProvider(@NotNull
                                java.util.regex.Pattern pattern,
                                @NotNull
                                IssueFetcher fetcher)
Method Detail

getType

@NotNull
public java.lang.String getType()
Description copied from interface: IssueProvider
Returns the type of this provider (the type of the corresponding factory). The type is immutable and consists of alpha-numeric characters.

Specified by:
getType in interface IssueProvider
Returns:
provider type

getRelatedIssues

@NotNull
public java.util.Collection<IssueMention> getRelatedIssues(@NotNull
                                                                   java.lang.String comment)
Description copied from interface: IssueProvider
Returns the collection of issues related, or mentioned in the comment. The relation can be defined by a mention in the text (a mention means that comment contains the substring that matches a certain pattern), or by any way the plugin chooses.

Specified by:
getRelatedIssues in interface IssueProvider
Parameters:
comment - the comment
Returns:
collection of related issues
See Also:
IssueProvider.isHasRelatedIssues(String)

isHasRelatedIssues

public boolean isHasRelatedIssues(@NotNull
                                  java.lang.String comment)
Description copied from interface: IssueProvider
Returns whether there are related issues in the specified comment. The relation can be defined by a mention in the text (a mention means that comment contains the substring that matches a certain pattern), or by any way the plugin chooses.

Specified by:
isHasRelatedIssues in interface IssueProvider
Parameters:
comment - the comment
Returns:
true if the comment has related issues
See Also:
IssueProvider.getRelatedIssues(String)

getRelatedIssues

@NotNull
public java.util.Collection<IssueMention> getRelatedIssues(@NotNull
                                                                   VcsModification modification)
Description copied from interface: IssueProvider
Returns the collection of issues related to a modification. In most cases the relation is defined via mentioning the issue id in the modification comment, but could also be some extra field in VCS commit.

Specified by:
getRelatedIssues in interface IssueProvider
Parameters:
modification - VCS modification
Returns:
collection of related issues
See Also:
IssueProvider.isHasRelatedIssues(jetbrains.buildServer.vcs.VcsModification)

isHasRelatedIssues

public boolean isHasRelatedIssues(@NotNull
                                  VcsModification modification)
Description copied from interface: IssueProvider
Returns whether there are related issues in the specified modification. In most cases the relation is defined via mentioning the issue id in the modification comment, but could also be some extra field in VCS commit.

Specified by:
isHasRelatedIssues in interface IssueProvider
Parameters:
modification - a VCS modification
Returns:
true if the modification has related issues
See Also:
IssueProvider.getRelatedIssues(jetbrains.buildServer.vcs.VcsModification)

isFetched

public boolean isFetched(@NotNull
                         java.lang.String id)
Description copied from interface: SIssueProvider
Returns whether the issue is fetched and can be efficiently returned using IssueProvider.findIssueById(String) method.

Specified by:
isFetched in interface SIssueProvider
Parameters:
id - the issue id
Returns:
true if the issue is fetched
See Also:
SIssueProvider.isFailedToFetch(String)

findPossiblyExpiredIssue

public IssueData findPossiblyExpiredIssue(@NotNull
                                          java.lang.String id)
Description copied from interface: SIssueProvider
Returns the issue data corresponding to the id.

The main difference from IssueProvider.findIssueById(String) method is that method must be always fast (should use only cached data) and the result data isn't expected to be up-to-date. So this method should return the issue data if by chance it can be retrieved fast, even if a provider consideres it out-dated and IssueProvider.findIssueById(String) method would make an extra call to the issue-tracking system.

The simpliest (100% legal) implementation of this method:

    public IssueData findPossiblyExpiredIssue(@NotNull String id) {
      return null;
    }
 
This way TeamCity will always show 'Retrieving...' message, when the issue isn't fetched (see SIssueProvider.isFetched(String)).

Specified by:
findPossiblyExpiredIssue in interface SIssueProvider
Parameters:
id - the issue id
Returns:
issue data, or null if the it cannot be returned efficiently

isFailedToFetch

public boolean isFailedToFetch(@NotNull
                               java.lang.String id)
Description copied from interface: SIssueProvider
Returns whether the issue could not be fetched due to error.

In case of true, the issue data isn't in a cache (i.e. isFetched(id) == false), but the error is.

Specified by:
isFailedToFetch in interface SIssueProvider
Parameters:
id - the issue id
Returns:
true if issue could not be fetched
See Also:
SIssueProvider.isFetched(String)

findIssueById

@Nullable
public IssueData findIssueById(@NotNull
                                        java.lang.String id)
Description copied from interface: IssueProvider
Returns the issue by the specified id. Returned data isn't expected to be up-to-date, i.e. fetched from the ITS at the moment of call.

The implementors are encouraged to report retrieving errors by throwing RetrieveIssueException, rather than simply return null: NotFoundException when the issue cannot be found, UnsupportedException when the issue tracker protocol is not supported, etc.

Specified by:
findIssueById in interface IssueProvider
Parameters:
id - issue id
Returns:
the corresponding issue, or null if the issue cannot be retrieved

isBatchFetchSupported

public boolean isBatchFetchSupported()
Description copied from interface: IssueBatchProviderSupport
Returns whether the issue provider supports fetching in batch.

Note: the method is always fast.

Specified by:
isBatchFetchSupported in interface IssueBatchProviderSupport
Returns:
true if the issue provider supports fetching in batch

findIssuesByIds

@Nullable
public java.util.Map<java.lang.String,IssueData> findIssuesByIds(@NotNull
                                                                          java.util.Collection<java.lang.String> ids)
Description copied from interface: IssueBatchProviderSupport
Finds and returns the specified collection of issue ids. If current provider does not support batch fetching, null is returned.

Note: the method is not necesserily fast, and should be called in a separate issue.

Specified by:
findIssuesByIds in interface IssueBatchProviderSupport
Parameters:
ids - the collection of issue ids to fetch
Returns:
the map issue id -> issue data, or null

getProperties

@NotNull
public java.util.Map<java.lang.String,java.lang.String> getProperties()
Description copied from interface: IssueProvider
Returns the map of provider properties. This map includes all fields that are configured in admin UI and stored in TeamCity config file (e.g. credentials used in all communications with remote server, server url, etc, but not the id or type).

The keys should consist of alphanumeric characters and start with a letter.

Specified by:
getProperties in interface IssueProvider
Returns:
the properties map

setProperties

public void setProperties(@NotNull
                          java.util.Map<java.lang.String,java.lang.String> map)
Description copied from interface: IssueProvider
Sets the provider properties (see IssueProvider.getProperties() method for the details).

Few words about thread-safety: properties can be changed from the admin UI, or in config file. By any of these events this method is called (synchronously). Hence this method should lock any other API method.

Specified by:
setProperties in interface IssueProvider
Parameters:
map - a properties map
See Also:
IssueProvider.getProperties()

dispose

public void dispose()
Description copied from interface: IssueProvider
Disposes the provider (releases all necessary resources, dumps caches on disk, etc). This method is called when the provider is deleted from the system, and on server shutdown.

Specified by:
dispose in interface IssueProvider

getCommentTransformationHelper

public CommentTransformationHelper getCommentTransformationHelper()
Description copied from interface: IssueProvider
Returns the instance of helper class to support comment transformation (i.e. automatic replacement of issues, mentioned in a comment, with a link and a popup).

Specified by:
getCommentTransformationHelper in interface IssueProvider
Returns:
a helper, or null

getPropertiesProcessor

@NotNull
public PropertiesProcessor getPropertiesProcessor()
Description copied from interface: SIssueProvider
Returns the properties processor instance (validator).

It is guaranteed that IssueProvider.setProperties(java.util.Map) method is called only if the processor finds no errors.

Specified by:
getPropertiesProcessor in interface SIssueProvider
Returns:
properties processor

getTestConnectionSupport

@NotNull
public IssueTestConnectionSupport getTestConnectionSupport()
Description copied from interface: SIssueProvider
Returns the test connection support.

Specified by:
getTestConnectionSupport in interface SIssueProvider
Returns:
test connection support

getConfigurationSummary

public java.lang.String getConfigurationSummary()
Description copied from interface: SIssueProvider
Returns the basic summary of current configuration, for instance, "Jira" provider might return: "Projects: P1, P2".

Specified by:
getConfigurationSummary in interface SIssueProvider
Returns:
provider configuration summary, or null

toString

public java.lang.String toString()
Overrides:
toString in class java.lang.Object

quickCheck

protected boolean quickCheck(@NotNull
                             java.lang.String comment)
Helper methods.


compilePattern

@NotNull
protected java.util.regex.Pattern compilePattern(@NotNull
                                                         java.util.Map<java.lang.String,java.lang.String> properties)

useIdPrefix

protected boolean useIdPrefix()

extractId

@NotNull
protected java.lang.String extractId(@NotNull
                                             java.lang.String match)

findIssuesByIdsImpl

@Nullable
protected java.util.Map<java.lang.String,IssueData> findIssuesByIdsImpl(@NotNull
                                                                                 java.util.Collection<java.lang.String> ids)

sanitizeHost

@NotNull
protected java.lang.String sanitizeHost(@NotNull
                                                java.lang.String host)

checkIssueIdBeforeTestConnection

@Nullable
protected java.lang.String checkIssueIdBeforeTestConnection(@NotNull
                                                                     java.lang.String issueId)

compileDisjunction

@NotNull
protected static java.util.regex.Pattern compileDisjunction(@NotNull
                                                                    java.lang.String prefixes,
                                                                    @NotNull
                                                                    java.lang.String suffix)
Given a string containing the prefixes, composes the reg.exp pattern that accepts any of them plus suffix. Example:
   prefixes = "foo bar";
   suffix = "-\\d+";
   result = "(foo|bar)-\\d+"
 

Prefixes are separated by ' ', '\t', '\n', '\r', ',', ';' characters.

Parameters:
prefixes - the prefixes (in one string)
suffix - the suffix
Returns:
disjunction pattern

safeCompile

@NotNull
protected static java.util.regex.Pattern safeCompile(@NotNull
                                                             java.lang.String pattern)
The same as Pattern.compile(pattern), but returns an empty pattern if the provided pattern is incorrect. In this case the issue provider will be disabled.

The pattern that matches empty string is considered incorrect.

Parameters:
pattern - the pattern to compile
Returns:
a compiled pattern