com.atlassian.greenhopper.customfield.backlog
Class BacklogJqlOperandResolverWrapper

java.lang.Object
  extended by com.atlassian.greenhopper.customfield.backlog.BacklogJqlOperandResolverWrapper
All Implemented Interfaces:
com.atlassian.jira.jql.operand.JqlOperandResolver

public class BacklogJqlOperandResolverWrapper
extends java.lang.Object
implements com.atlassian.jira.jql.operand.JqlOperandResolver

Searching for Backlogs in JQL is using implicit inclusion: When the user looks for one backlog, all children are considered to be automatically included. Since the relation between issue and backlog is 1-n (unlike n-m against fixVersions), this implicit inclusion has to be done in the JQL logic.

The inversion of that is called "pending" (as in "issues that are still in the 'parent/product' backlog and not yet scheduled into a sprint"). PendingJqlFunction is used to disable the implicit inclusion.

Now in order to make the whole thing work, we have to modify the query. A good place might have been BacklogIndexInfoResolver, but it operates on plain String/Long values and has no notion of QueryLiterals or any other object that could carry the logic around that the function was involved, so it wouldn't have worked for the function.

What we're doing instead is wrapping the JqlOperandResolver that constructs the QueryLiterals in the first place. Since the JIRA-generated instance is final, we'll wrap it here. Only one instance of the wrapper will be created by BacklogSearcher.

Author:
ahennecke

Constructor Summary
BacklogJqlOperandResolverWrapper(com.atlassian.jira.jql.operand.JqlOperandResolver wrappedResolver, BacklogIndexInfoResolver indexInfoResolver, BacklogHierarchyService backlogHierarchyService, BacklogService backlogService)
           
 
Method Summary
 com.atlassian.jira.jql.operand.QueryLiteral getSingleValue(com.atlassian.crowd.embedded.api.User user, com.atlassian.query.operand.Operand operand, com.atlassian.query.clause.TerminalClause clause)
           
 com.atlassian.jira.jql.operand.QueryLiteral getSingleValue(com.opensymphony.user.User user, com.atlassian.query.operand.Operand operand, com.atlassian.query.clause.TerminalClause clause)
           
 java.util.List<com.atlassian.jira.jql.operand.QueryLiteral> getValues(com.atlassian.jira.jql.query.QueryCreationContext queryCreationContext, com.atlassian.query.operand.Operand operand, com.atlassian.query.clause.TerminalClause terminalClause)
          Here goes the magic.
 java.util.List<com.atlassian.jira.jql.operand.QueryLiteral> getValues(com.atlassian.crowd.embedded.api.User searcher, com.atlassian.query.operand.Operand operand, com.atlassian.query.clause.TerminalClause terminalClause)
           
 java.util.List<com.atlassian.jira.jql.operand.QueryLiteral> getValues(com.opensymphony.user.User searcher, com.atlassian.query.operand.Operand operand, com.atlassian.query.clause.TerminalClause terminalClause)
           
 boolean isEmptyOperand(com.atlassian.query.operand.Operand operand)
           
 boolean isFunctionOperand(com.atlassian.query.operand.Operand operand)
           
 boolean isListOperand(com.atlassian.query.operand.Operand operand)
           
 boolean isValidOperand(com.atlassian.query.operand.Operand operand)
           
 com.atlassian.query.operand.FunctionOperand sanitiseFunctionOperand(com.atlassian.crowd.embedded.api.User searcher, com.atlassian.query.operand.FunctionOperand operand)
           
 com.atlassian.query.operand.FunctionOperand sanitiseFunctionOperand(com.opensymphony.user.User searcher, com.atlassian.query.operand.FunctionOperand operand)
           
 com.atlassian.jira.util.MessageSet validate(com.atlassian.crowd.embedded.api.User user, com.atlassian.query.operand.Operand operand, com.atlassian.query.clause.TerminalClause terminalClause)
          We don't really need to do something on validation, since we're generating the QueryLiterals ourselves, so we're pretty sure it's correct what we're doing.
 com.atlassian.jira.util.MessageSet validate(com.opensymphony.user.User user, com.atlassian.query.operand.Operand operand, com.atlassian.query.clause.TerminalClause terminalClause)
           
 com.atlassian.jira.util.MessageSet validate(com.atlassian.crowd.embedded.api.User searcher, com.atlassian.query.operand.Operand operand, com.atlassian.query.clause.WasClauseImpl clause)
           
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

BacklogJqlOperandResolverWrapper

public BacklogJqlOperandResolverWrapper(com.atlassian.jira.jql.operand.JqlOperandResolver wrappedResolver,
                                        BacklogIndexInfoResolver indexInfoResolver,
                                        BacklogHierarchyService backlogHierarchyService,
                                        BacklogService backlogService)
Method Detail

getValues

public java.util.List<com.atlassian.jira.jql.operand.QueryLiteral> getValues(com.atlassian.crowd.embedded.api.User searcher,
                                                                             com.atlassian.query.operand.Operand operand,
                                                                             com.atlassian.query.clause.TerminalClause terminalClause)
Specified by:
getValues in interface com.atlassian.jira.jql.operand.JqlOperandResolver

getValues

public java.util.List<com.atlassian.jira.jql.operand.QueryLiteral> getValues(com.opensymphony.user.User searcher,
                                                                             com.atlassian.query.operand.Operand operand,
                                                                             com.atlassian.query.clause.TerminalClause terminalClause)
Specified by:
getValues in interface com.atlassian.jira.jql.operand.JqlOperandResolver

getValues

public java.util.List<com.atlassian.jira.jql.operand.QueryLiteral> getValues(com.atlassian.jira.jql.query.QueryCreationContext queryCreationContext,
                                                                             com.atlassian.query.operand.Operand operand,
                                                                             com.atlassian.query.clause.TerminalClause terminalClause)
Here goes the magic. What basically happens is that the user enters a backlog query operand, which can resolve to one or more (in case of name) or one (in case of ID) backlog. By default, we'll use the indexInfoResolver to extract the IDs from the default resolved literal and fetch the backlog tree under each given one. The query then is expanded with the children.

Specified by:
getValues in interface com.atlassian.jira.jql.operand.JqlOperandResolver

validate

public com.atlassian.jira.util.MessageSet validate(com.atlassian.crowd.embedded.api.User user,
                                                   com.atlassian.query.operand.Operand operand,
                                                   com.atlassian.query.clause.TerminalClause terminalClause)
We don't really need to do something on validation, since we're generating the QueryLiterals ourselves, so we're pretty sure it's correct what we're doing.

Specified by:
validate in interface com.atlassian.jira.jql.operand.JqlOperandResolver

validate

public com.atlassian.jira.util.MessageSet validate(com.opensymphony.user.User user,
                                                   com.atlassian.query.operand.Operand operand,
                                                   com.atlassian.query.clause.TerminalClause terminalClause)
Specified by:
validate in interface com.atlassian.jira.jql.operand.JqlOperandResolver

sanitiseFunctionOperand

public com.atlassian.query.operand.FunctionOperand sanitiseFunctionOperand(com.atlassian.crowd.embedded.api.User searcher,
                                                                           com.atlassian.query.operand.FunctionOperand operand)
Specified by:
sanitiseFunctionOperand in interface com.atlassian.jira.jql.operand.JqlOperandResolver

sanitiseFunctionOperand

public com.atlassian.query.operand.FunctionOperand sanitiseFunctionOperand(com.opensymphony.user.User searcher,
                                                                           com.atlassian.query.operand.FunctionOperand operand)
Specified by:
sanitiseFunctionOperand in interface com.atlassian.jira.jql.operand.JqlOperandResolver

getSingleValue

public com.atlassian.jira.jql.operand.QueryLiteral getSingleValue(com.atlassian.crowd.embedded.api.User user,
                                                                  com.atlassian.query.operand.Operand operand,
                                                                  com.atlassian.query.clause.TerminalClause clause)
Specified by:
getSingleValue in interface com.atlassian.jira.jql.operand.JqlOperandResolver

getSingleValue

public com.atlassian.jira.jql.operand.QueryLiteral getSingleValue(com.opensymphony.user.User user,
                                                                  com.atlassian.query.operand.Operand operand,
                                                                  com.atlassian.query.clause.TerminalClause clause)
Specified by:
getSingleValue in interface com.atlassian.jira.jql.operand.JqlOperandResolver

isEmptyOperand

public boolean isEmptyOperand(com.atlassian.query.operand.Operand operand)
Specified by:
isEmptyOperand in interface com.atlassian.jira.jql.operand.JqlOperandResolver

isFunctionOperand

public boolean isFunctionOperand(com.atlassian.query.operand.Operand operand)
Specified by:
isFunctionOperand in interface com.atlassian.jira.jql.operand.JqlOperandResolver

isListOperand

public boolean isListOperand(com.atlassian.query.operand.Operand operand)
Specified by:
isListOperand in interface com.atlassian.jira.jql.operand.JqlOperandResolver

isValidOperand

public boolean isValidOperand(com.atlassian.query.operand.Operand operand)
Specified by:
isValidOperand in interface com.atlassian.jira.jql.operand.JqlOperandResolver

validate

public com.atlassian.jira.util.MessageSet validate(com.atlassian.crowd.embedded.api.User searcher,
                                                   com.atlassian.query.operand.Operand operand,
                                                   com.atlassian.query.clause.WasClauseImpl clause)
Specified by:
validate in interface com.atlassian.jira.jql.operand.JqlOperandResolver


Copyright © 2007-2011 Atlassian. All Rights Reserved.