Adds methods handling 'filter' and 'limit' expressions
authorNiels Erik G. Nielsen <nielserik@indexdata.com>
Mon, 3 Jun 2013 19:44:07 +0000 (15:44 -0400)
committerNiels Erik G. Nielsen <nielserik@indexdata.com>
Mon, 3 Jun 2013 19:44:07 +0000 (15:44 -0400)
src/main/java/com/indexdata/mkjsf/pazpar2/ServiceProxyClient.java
src/main/java/com/indexdata/mkjsf/pazpar2/commands/CommandParameter.java
src/main/java/com/indexdata/mkjsf/pazpar2/commands/Expression.java
src/main/java/com/indexdata/mkjsf/pazpar2/commands/FilterParameter.java [new file with mode: 0644]
src/main/java/com/indexdata/mkjsf/pazpar2/commands/LimitParameter.java [new file with mode: 0644]
src/main/java/com/indexdata/mkjsf/pazpar2/commands/Pazpar2Command.java
src/main/java/com/indexdata/mkjsf/pazpar2/commands/SearchCommand.java

index 67cc8ef..aa54403 100644 (file)
@@ -101,7 +101,7 @@ public class ServiceProxyClient implements SearchClient {
     try {\r
       response = client.execute(httpget, handler);\r
       if (handler.getStatusCode()==200 && (handler.getContentType().contains("xml") || handler.getContentType().contains("octet-stream"))) {\r
-        logger.debug("Creating command response holding content of type " + handler.getContentType());\r
+        logger.trace("Creating command response holding content of type " + handler.getContentType());\r
         commandResponse = new ClientCommandResponse(handler.getStatusCode(),response,handler.getContentType());\r
       } else {\r
         logger.error("Service Proxy status code: " + handler.getStatusCode());\r
index b22962e..d08cde1 100644 (file)
@@ -3,15 +3,13 @@ package com.indexdata.mkjsf.pazpar2.commands;
 import java.io.Serializable;\r
 import java.io.UnsupportedEncodingException;\r
 import java.net.URLEncoder;\r
+import java.util.ArrayList;\r
 import java.util.Arrays;\r
-import java.util.HashMap;\r
+import java.util.Iterator;\r
 import java.util.List;\r
-import java.util.Map;\r
 \r
 import org.apache.log4j.Logger;\r
 \r
-import com.indexdata.mkjsf.pazpar2.commands.CommandParameter;\r
-\r
 public class CommandParameter implements Serializable {\r
 \r
   private static Logger logger = Logger.getLogger(CommandParameter.class);\r
@@ -20,7 +18,7 @@ public class CommandParameter implements Serializable {
   String name = null;\r
   String operator = null;\r
   String value = null;\r
-  Map<String,Expression> expressions = new HashMap<String,Expression>();\r
+  List<Expression> expressions = new ArrayList<Expression>();\r
   private static List<String> nologparams = Arrays.asList("password");\r
   \r
   public CommandParameter (String name) {\r
@@ -29,14 +27,24 @@ public class CommandParameter implements Serializable {
   }\r
   \r
   public CommandParameter (String name, String operator, String value, Expression... expressions) {\r
-    logger.trace("Instantiating command parameter " + name + " with expressions: [" + expressions + "]");\r
+    logger.trace("Instantiating command parameter " + name + " with value [" + value + "] and expressions: [" + expressions + "]");\r
     this.name = name;\r
     this.operator = operator;\r
     this.value = value;\r
     for (Expression expr : expressions) {\r
-      this.expressions.put(expr.toString(), expr);\r
+      this.expressions.add(expr);\r
     }\r
   }\r
+  \r
+  public CommandParameter (String name, String operator, Expression... expressions) {\r
+    logger.trace("Instantiating command parameter " + name + " with expressions: [" + expressions + "]");\r
+    this.name = name;\r
+    this.operator = operator;    \r
+    for (Expression expr : expressions) {\r
+      this.expressions.add(expr);\r
+    }\r
+  }\r
+\r
 \r
   public CommandParameter (String name, String operator, String value) {\r
     if (!nologparams.contains(name)) logger.trace("Instantiating command parameter '" + name + "' with String: [" + value + "]");    \r
@@ -57,19 +65,66 @@ public class CommandParameter implements Serializable {
     return name;\r
   }\r
   \r
-  public Map<String,Expression> getExpressions () {\r
+  public List<Expression> getExpressions () {\r
     return expressions;\r
   }\r
   \r
+  public List<Expression> getExpressions(String... expressionFields) {\r
+    List<String> requestedFields = Arrays.asList(expressionFields);\r
+    List<Expression> exprs = new ArrayList<Expression>();\r
+    for (Expression expr : expressions) {\r
+      if (requestedFields.contains(expr.getField())) {\r
+        exprs.add(expr);\r
+      }\r
+    }\r
+    return exprs;\r
+  }\r
+  \r
   public void addExpression(Expression expression) {\r
     logger.debug("Adding expression [" + expression + "] to '" + name + "'");\r
-    this.expressions.put(expression.toString(),expression);\r
+    this.expressions.add(expression);\r
   }\r
   \r
   public void removeExpression(Expression expression) {\r
-    this.expressions.remove(expression.toString());\r
+    for (Expression expr : expressions) {\r
+      if (expr.toString().equals(expression.toString())) {\r
+        expressions.remove(expr);\r
+        break;\r
+      }\r
+    }    \r
+  }\r
+  \r
+  public void removeExpressionsAfter (Expression expression, String... expressionFields) {\r
+    List<String> exprFieldsToRemove = Arrays.asList(expressionFields);\r
+    int fromIdx = 0;    \r
+    for (Expression expr : expressions) {      \r
+      fromIdx++;\r
+      if (expr.toString().equals(expression.toString())) {        \r
+        break;\r
+      }      \r
+    }\r
+    if (fromIdx<expressions.size()) {      \r
+      Iterator<Expression> candidatesForRemoval = expressions.subList(fromIdx, expressions.size()).iterator();\r
+      while (candidatesForRemoval.hasNext()) {\r
+        Expression exp = candidatesForRemoval.next();\r
+        if (exprFieldsToRemove.contains(exp.getField())) {\r
+          expressions.remove(exp);\r
+        }\r
+      }\r
+    }\r
   }\r
   \r
+  public void removeExpressions (String... expressionFields) {\r
+    List<String> fieldsToRemove = Arrays.asList(expressionFields);\r
+    Iterator<Expression> i = expressions.iterator();\r
+    while (i.hasNext()) {\r
+       Expression expr = i.next(); \r
+       if (fieldsToRemove.contains(expr.getField())) {\r
+         logger.trace("Removing expression: " + expr.toString());\r
+         i.remove();\r
+       }\r
+    }\r
+  }\r
   \r
   public boolean hasOperator() {\r
     return operator != null;\r
@@ -79,6 +134,19 @@ public class CommandParameter implements Serializable {
     return value != null && value.length()>0;\r
   }\r
   \r
+  public boolean hasExpressions() {\r
+    return expressions.size()>0;\r
+  }\r
+  \r
+  public boolean hasExpressions(String expressionField) {    \r
+    for (Expression expr : expressions) {\r
+      if (expr.getField().equals(expressionField)) {\r
+        return true;\r
+      }\r
+    }     \r
+    return false;    \r
+  }\r
+  \r
   public String getEncodedQueryString () {\r
     try {\r
       return name + operator + URLEncoder.encode(getValueWithExpressions(),"UTF-8");\r
@@ -94,12 +162,11 @@ public class CommandParameter implements Serializable {
   \r
   public String getValueWithExpressions () {\r
     StringBuilder completeValue = new StringBuilder((value==null ? "" : value));    \r
-    for (String key : expressions.keySet()) {      \r
-      completeValue.append(" and " + expressions.get(key));\r
+    for (Expression expr : expressions) {      \r
+      completeValue.append(" and " + expr.toString());\r
     }\r
-    return completeValue.toString();\r
-    \r
-  }\r
+    return completeValue.toString();    \r
+  }  \r
   \r
   @Override\r
   public boolean equals (Object otherParameter) {\r
@@ -122,8 +189,8 @@ public class CommandParameter implements Serializable {
     CommandParameter newParam = new CommandParameter(name);\r
     newParam.value = this.value;\r
     newParam.operator = this.operator;\r
-    for (String key : expressions.keySet()) {\r
-      newParam.addExpression(expressions.get(key).copy());      \r
+    for (Expression expr : expressions) {\r
+      newParam.addExpression(expr.copy());      \r
     }\r
     return newParam;\r
   }\r
index 3e93e49..3c377e2 100644 (file)
@@ -1,28 +1,59 @@
 package com.indexdata.mkjsf.pazpar2.commands;\r
 \r
 import java.io.Serializable;\r
+import java.util.StringTokenizer;\r
+\r
+import org.apache.log4j.Logger;\r
 \r
 import com.indexdata.mkjsf.pazpar2.commands.Expression;\r
 \r
 public class Expression implements Serializable {\r
   \r
   private static final long serialVersionUID = -751704027842027769L;\r
+  private static Logger logger = Logger.getLogger(Expression.class);\r
   String leftEntity;\r
   String operator;\r
   String rightEntity;\r
-  public Expression (String leftEntity, String operator, String rightEntity) {\r
+  String label;  \r
+  \r
+  public Expression (String leftEntity, String operator, String rightEntity, String label) {\r
     this.leftEntity = leftEntity;\r
     this.operator = operator;\r
     this.rightEntity = rightEntity;    \r
+    this.label = label;\r
+  }\r
+  \r
+  public Expression (String expressionString) {\r
+    StringTokenizer tokenizer = new StringTokenizer(expressionString,"=");\r
+    this.leftEntity = tokenizer.nextToken();\r
+    this.operator = "=";\r
+    this.rightEntity = tokenizer.nextToken();\r
+    this.label=rightEntity;\r
   }\r
   \r
   public Expression copy() {\r
-    return new Expression(leftEntity,operator,rightEntity);\r
+    logger.trace("Copying " + this.toString());\r
+    return new Expression(leftEntity, operator, rightEntity, label);\r
   }\r
   \r
   public String toString() {\r
     return leftEntity + operator + rightEntity;\r
   }\r
   \r
-\r
+  public String getLabel() {\r
+    return label;\r
+  }\r
+  \r
+  public String getField () {\r
+    return leftEntity;\r
+  }\r
+  \r
+  public String getOperator() {\r
+    return operator;\r
+  }\r
+  \r
+  public String getValue() {\r
+    return rightEntity;\r
+  }\r
+  \r
 }\r
diff --git a/src/main/java/com/indexdata/mkjsf/pazpar2/commands/FilterParameter.java b/src/main/java/com/indexdata/mkjsf/pazpar2/commands/FilterParameter.java
new file mode 100644 (file)
index 0000000..0d540a2
--- /dev/null
@@ -0,0 +1,50 @@
+package com.indexdata.mkjsf.pazpar2.commands;\r
+\r
+import org.apache.log4j.Logger;\r
+\r
+public class FilterParameter extends CommandParameter {\r
+\r
+  private static final long serialVersionUID = -3697328835895528654L;\r
+  private static Logger logger = Logger.getLogger(FilterParameter.class);\r
+\r
+  public FilterParameter(String name) {\r
+    super(name);\r
+  }\r
+\r
+  public FilterParameter(Expression... expressions) {\r
+    super("filter", "=", expressions);\r
+  }\r
+\r
+  public String getValueWithExpressions () {\r
+    StringBuilder completeValue = new StringBuilder("");\r
+    boolean first = true;\r
+    for (Expression expr : expressions) {      \r
+      if (!first) \r
+        completeValue.append(",");\r
+      else \r
+        first=false;      \r
+      completeValue.append(pz2escape(expr.toString()));\r
+    }\r
+    return completeValue.toString();    \r
+  }  \r
+  \r
+  public String pz2escape (String expressionString) {\r
+    String escaped = expressionString.replaceAll("\\\\","\\\\\\\\");\r
+    escaped = escaped.replaceAll(",","\\\\,");\r
+    escaped = escaped.replaceAll("\\|", "\\\\|");\r
+    return escaped;\r
+  }\r
+  \r
+  public FilterParameter copy() {\r
+    logger.trace("Copying parameter '"+ name + "' for modification");\r
+    FilterParameter newParam = new FilterParameter(name);\r
+    newParam.value = this.value;\r
+    newParam.operator = this.operator;\r
+    for (Expression expr : expressions) {\r
+      newParam.addExpression(expr.copy());      \r
+    }\r
+    return newParam;\r
+  }\r
+\r
+\r
+}\r
diff --git a/src/main/java/com/indexdata/mkjsf/pazpar2/commands/LimitParameter.java b/src/main/java/com/indexdata/mkjsf/pazpar2/commands/LimitParameter.java
new file mode 100644 (file)
index 0000000..b86c27f
--- /dev/null
@@ -0,0 +1,52 @@
+package com.indexdata.mkjsf.pazpar2.commands;\r
+\r
+import org.apache.log4j.Logger;\r
+\r
+public class LimitParameter extends CommandParameter {\r
+\r
+  private static final long serialVersionUID = -1410691265213389826L;\r
+  private static Logger logger = Logger.getLogger(LimitParameter.class);\r
+\r
+  public LimitParameter(String name) {\r
+    super(name);\r
+  }\r
+\r
+  public LimitParameter(Expression... expressions) {\r
+    super("limit", "=", expressions);\r
+  }\r
+\r
+  public String getValueWithExpressions () {\r
+    StringBuilder completeValue = new StringBuilder("");\r
+    boolean first = true;\r
+    for (Expression expr : expressions) {      \r
+      if (!first) \r
+        completeValue.append(",");\r
+      else \r
+        first=false;      \r
+      completeValue.append(pz2escape(expr.toString()));\r
+      logger.trace("valueWithExpressions so far: [" + completeValue + "]");\r
+    }\r
+    return completeValue.toString();    \r
+  }\r
+  \r
+  public String pz2escape (String expressionString) {\r
+    String escaped = expressionString.replaceAll("\\\\","\\\\\\\\");\r
+    escaped = escaped.replaceAll(",","\\\\,");\r
+    escaped = escaped.replaceAll("\\|", "\\\\|");\r
+    return escaped;\r
+  }\r
+\r
+  \r
+  public LimitParameter copy() {\r
+    logger.trace("Copying parameter '"+ name + "' for modification");\r
+    LimitParameter newParam = new LimitParameter(name);\r
+    newParam.value = this.value;\r
+    newParam.operator = this.operator;\r
+    for (Expression expr : expressions) {\r
+      newParam.addExpression(expr.copy());      \r
+    }\r
+    return newParam;\r
+  }\r
+\r
+\r
+}\r
index c7bff40..7c0ec74 100644 (file)
@@ -124,20 +124,46 @@ public abstract class Pazpar2Command implements Serializable  {
   public void removeParametersInState() {\r
     parameters = new HashMap<String,CommandParameter>();    \r
   }\r
-\r
+  \r
+  public void addExpression(String parameterName, Expression expression) {\r
+    Pazpar2Command copy = this.copy();\r
+    copy.getParameter(parameterName).addExpression(expression);\r
+    checkInState(copy);\r
+  }\r
+  \r
+  public void removeExpression(String parameterName, Expression expression) {\r
+    Pazpar2Command copy = this.copy();\r
+    copy.getParameter(parameterName).removeExpression(expression);\r
+    checkInState(copy);    \r
+  }\r
+  \r
+  public void removeExpressionsAfter(String parameterName, Expression expression,String... expressionFields) {\r
+    Pazpar2Command copy = this.copy();\r
+    copy.getParameter(parameterName).removeExpressionsAfter(expression,expressionFields);\r
+    checkInState(copy);    \r
+  }\r
+  \r
+  public void removeExpressions(String parameterName, String... expressionFields) {\r
+    Pazpar2Command copy = this.copy();    \r
+    copy.getParameter(parameterName).removeExpressions(expressionFields);    \r
+    if (!getParameter(parameterName).hasValue() && !getParameter(parameterName).hasExpressions()) {\r
+      copy.parameters.remove(parameterName);\r
+    }\r
+    checkInState(copy);    \r
+  }\r
   \r
   public boolean hasParameters () {\r
     return (parameters.keySet().size()>0);\r
   }\r
   \r
   public boolean hasParameterValue(String parameterName) {\r
-    return (parameters.get(parameterName) != null && parameters.get(parameterName).hasValue());\r
+    return (parameters.get(parameterName) != null && (parameters.get(parameterName).hasValue()));\r
   }\r
-  \r
+    \r
   public String getEncodedQueryString () {\r
     StringBuilder queryString = new StringBuilder("command="+name);\r
     for (CommandParameter parameter : parameters.values()) {\r
-      if (parameter.hasValue()) {\r
+      if (parameter.hasValue() || parameter.hasExpressions()) {\r
         queryString.append("&"+parameter.getEncodedQueryString());\r
       }\r
     }\r
@@ -147,7 +173,7 @@ public abstract class Pazpar2Command implements Serializable  {
   public String getValueWithExpressions() {    \r
     StringBuilder value = new StringBuilder("");\r
     for (CommandParameter parameter : parameters.values()) {\r
-      if (parameter.hasValue()) {\r
+      if (parameter.hasValue() || parameter.hasExpressions()) {\r
         value.append("&" + parameter.getName() + parameter.operator + parameter.getValueWithExpressions());\r
       }\r
    }\r
@@ -156,6 +182,7 @@ public abstract class Pazpar2Command implements Serializable  {
   \r
   @Override\r
   public boolean equals (Object otherCommand) {\r
+    logger.trace("Comparing commands ["+this.toString()+"] and ["+otherCommand.toString() +"]");\r
     return\r
         ((otherCommand instanceof Pazpar2Command)\r
          && this.getValueWithExpressions().equals(((Pazpar2Command) otherCommand).getValueWithExpressions()));\r
index f2eb3be..c094d24 100644 (file)
@@ -1,5 +1,7 @@
 package com.indexdata.mkjsf.pazpar2.commands;\r
 \r
+import java.util.List;\r
+\r
 import javax.enterprise.context.SessionScoped;\r
 import javax.inject.Named;\r
 \r
@@ -29,7 +31,6 @@ public class SearchCommand extends Pazpar2Command implements ServiceProxyCommand
     Pz2Service.get().getSearchClient().setSearchCommand(this);\r
     return super.run();\r
   }\r
-\r
     \r
   public void setQuery(String query) {    \r
     setParameter(new CommandParameter("query","=",query));\r
@@ -40,44 +41,127 @@ public class SearchCommand extends Pazpar2Command implements ServiceProxyCommand
   }\r
   \r
   public void setFilter(String filterExpression) {\r
-    setParameter(new CommandParameter("filter","=",filterExpression));\r
+    if (filterExpression != null && filterExpression.length()>0) {\r
+      setParameter(new FilterParameter(new Expression(filterExpression)));\r
+    }\r
+  }\r
+  \r
+  public void setFilter(String field, String operator, String value, String label) {\r
+    setParameter(new FilterParameter(new Expression(field,operator,value,label)));\r
   }\r
   \r
   public String getFilter() {\r
-    return getParameter("filter") == null ? null : getParameter("filter").getValueWithExpressions();\r
+    return getParameter("filter") == null ? null : ((FilterParameter)getParameter("filter")).getValueWithExpressions();\r
   }\r
   \r
-  public void addFilter(String filterExpression) {\r
-    // TODO: implement\r
-    if (hasParameterValue("filter")) {\r
-      setFilter(filterExpression);\r
+  public List<Expression> getFilters() {\r
+    return getParameter("filter").getExpressions();\r
+  }\r
+  \r
+  public void addFilter(String field, String operator, String value, String label) {\r
+    if (getParameter("filter") == null) {\r
+      setFilter(field + operator + value);\r
     } else {\r
-      getParameter("filter");\r
+      getParameter("filter").addExpression(new Expression(field,operator,value,(label != null ? label : value)));\r
     }\r
-    throw new UnsupportedOperationException("removeFilter(filterExpression) yet to be implemented.");\r
   }\r
   \r
   public void removeFilters () {\r
     removeParameter("filter");\r
   }\r
   \r
-  public void removeFilter(String filterExpression) {\r
-    // TODO: implement\r
-    throw new UnsupportedOperationException("removeFilter(filterExpression) yet to be implemented.");\r
+  public void removeFilter(String field, String operator, String value) {\r
+    removeExpression("filter",new Expression(field, operator, value, null));\r
   }\r
-\r
+  \r
+  public void removeFiltersAfter(String field, String operator, String value) {\r
+    removeExpressionsAfter("filter",new Expression(field,operator,value,null));\r
+  }\r
+  \r
   public boolean hasFilter () {\r
     return getFilter().length()>0;\r
   }\r
   \r
-  public void setLimit (String limitExpression) {\r
-    setParameter(new CommandParameter("limit","=",limitExpression));\r
+  public void setLimit (String limitExpression) {   \r
+    if (limitExpression != null && limitExpression.length()>0) {\r
+      setParameter(new LimitParameter(new Expression(limitExpression)));\r
+    }\r
   }\r
   \r
+  public void setLimit(String field, String operator, String value, String label) {\r
+    setParameter(new LimitParameter(new Expression(field,operator,value,label)));\r
+  }\r
+      \r
   public String getLimit () {\r
-    return getParameterValue("limit");\r
+    return getParameter("limit") == null ? null : ((FilterParameter)getParameter("limit")).getValueWithExpressions();    \r
+  }\r
+  \r
+  public List<Expression> getLimitExpressions() {\r
+    return getParameter("limit").getExpressions();\r
+  }\r
+  \r
+  public boolean hasLimitExpression(String... expressionFields) {\r
+    logger.trace("Checking for limit expression for " + expressionFields);\r
+    for (String field : expressionFields) {\r
+      if (getLimitExpressions(field) != null && getLimitExpressions(field).size()>0) {\r
+        logger.trace("Limit expression found (" + field + ")");\r
+        return true;\r
+      }  \r
+    }\r
+    logger.trace("No limit expressions found");\r
+    return false;\r
+  }\r
+  \r
+  public Expression getOneLimitExpression(String expressionField) {\r
+    List<Expression> exprs = getLimitExpressions(expressionField);\r
+    if (exprs != null && exprs.size()>0) {\r
+      if (exprs.size()>1) {\r
+        logger.warn("More that one limit expression found for [" + expressionField + "] but only asked to return the first one");\r
+      }\r
+      return exprs.get(0);\r
+    } else {\r
+      return null;\r
+    }\r
+    \r
   }\r
+  \r
+  public List<Expression> getLimitExpressions(String... expressionFields) {\r
+    logger.trace("Checking for limit parameter");\r
+    if (parameters.get("limit")!=null) {\r
+      logger.trace("Found");\r
+      return getParameter("limit").getExpressions(expressionFields);\r
+    } else {\r
+      logger.trace("Not found");\r
+      return null;\r
+    }\r
+  }\r
+  \r
+  public void addLimit(String field, String operator, String value, String label) {\r
+    if (getParameter("limit") == null) {\r
+      setLimit(field, operator, value, label);\r
+    } else {\r
+      addExpression("limit",new Expression(field,operator,value,label));\r
       \r
+    }\r
+  }\r
+  \r
+  public void removeLimits() {\r
+    removeParameter("limit");\r
+  }\r
+  \r
+  public void removeLimits(String... fields) {    \r
+    removeExpressions("limit",fields);    \r
+  }\r
+  \r
+  public void removeLimit(String field, String operator, String value) {\r
+    removeExpression("limit",new Expression(field, operator, value, null));    \r
+  }\r
+  \r
+  public void removeLimitsAfter(String field, String operator, String value, String... fields) {     \r
+    removeExpressionsAfter("limit",new Expression(field,operator,value,null),fields);    \r
+  }\r
+\r
+        \r
   public void setStartrecs (String startrecs) {\r
     setParameter(new CommandParameter("startrecs","=",startrecs));\r
   }\r
@@ -120,15 +204,14 @@ public class SearchCommand extends Pazpar2Command implements ServiceProxyCommand
   \r
   \r
   /**\r
-   * Sets a facet, in CQL, to restrict the current results,\r
-   * then executes the search \r
+   * Sets a facet, in CQL, to restrict the current results\r
    * \r
    * @param facetKey  i.e.  'au' for author\r
    * @param term  i.e. 'Dickens, Charles'\r
    */\r
   public void setFacet(String facetKey, String term) {\r
     if (term != null && term.length()>0) {         \r
-      getParameter("query").addExpression(new Expression(facetKey,"=",term));            \r
+      getParameter("query").addExpression(new Expression(facetKey,"=",term,null));            \r
     }            \r
   }\r
   \r
@@ -151,8 +234,7 @@ public class SearchCommand extends Pazpar2Command implements ServiceProxyCommand
   }\r
       \r
   /**\r
-   * Removes a facet set by setFacet(...), then executes\r
-   * the search.\r
+   * Removes a facet set by setFacet(...)\r
    * \r
    * Will not remove facets set by setFacetOnQuery(...)\r
    *  \r
@@ -161,7 +243,7 @@ public class SearchCommand extends Pazpar2Command implements ServiceProxyCommand
    */\r
   public void removeFacet(String facetKey, String term) {\r
     if (getParameter("query") != null) {\r
-      getParameter("query").removeExpression(new Expression(facetKey,"=",term));\r
+      getParameter("query").removeExpression(new Expression(facetKey,"=",term,null));\r
     }\r
   }\r
   \r