Package ca.uhn.fhir.rest.param

Source Code of ca.uhn.fhir.rest.param.DateRangeParam

package ca.uhn.fhir.rest.param;

/*
* #%L
* HAPI FHIR Library
* %%
* Copyright (C) 2014 University Health Network
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang3.StringUtils;

import ca.uhn.fhir.model.api.IQueryParameterAnd;
import ca.uhn.fhir.model.api.IQueryParameterOr;
import ca.uhn.fhir.model.dstu.valueset.QuantityCompararatorEnum;
import ca.uhn.fhir.parser.DataFormatException;
import ca.uhn.fhir.rest.method.QualifiedParamList;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;

public class DateRangeParam implements IQueryParameterAnd {

  private QualifiedDateParam myLowerBound;
  private QualifiedDateParam myUpperBound;

  /**
   * Basic constructor. Values must be supplied by calling {@link #setLowerBound(QualifiedDateParam)} and
   * {@link #setUpperBound(QualifiedDateParam)}
   */
  public DateRangeParam() {
    // nothing
  }

  /**
   * Constructor which takes two Dates representing the lower and upper bounds of the range (inclusive on both ends)
   *
   * @param theLowerBound
   *            A qualified date param representing the lower date bound (optionally may include time), e.g.
   *            "2011-02-22" or "2011-02-22T13:12:00". Will be treated inclusively.
   * @param theUpperBound
   *            A qualified date param representing the upper date bound (optionally may include time), e.g.
   *            "2011-02-22" or "2011-02-22T13:12:00". Will be treated inclusively.
   */
  public DateRangeParam(Date theLowerBound, Date theUpperBound) {
    setRangeFromDatesInclusive(theLowerBound, theUpperBound);
  }

  /**
   * Sets the range from a single date param. If theDateParam has no qualifier, treats it as the lower and upper bound
   * (e.g. 2011-01-02 would match any time on that day). If theDateParam has a qualifier, treats it as either the
   * lower or upper bound, with no opposite bound.
   */
  public DateRangeParam(QualifiedDateParam theDateParam) {
    if (theDateParam == null) {
      throw new NullPointerException("theDateParam can not be null");
    }
    if (theDateParam.isEmpty()) {
      throw new IllegalArgumentException("theDateParam can not be empty");
    }
    if (theDateParam.getComparator() == null) {
      setRangeFromDatesInclusive(theDateParam.getValueAsString(), theDateParam.getValueAsString());
    } else {
      switch (theDateParam.getComparator()) {
      case GREATERTHAN:
      case GREATERTHAN_OR_EQUALS:
        myLowerBound = theDateParam;
        myUpperBound = null;
        break;
      case LESSTHAN:
      case LESSTHAN_OR_EQUALS:
        myLowerBound = null;
        myUpperBound = theDateParam;
        break;
      default:
        // Should not happen
        throw new IllegalStateException("Unknown comparator:" + theDateParam.getComparator() + ". This is a bug.");
      }
    }
    validateAndThrowDataFormatExceptionIfInvalid();
  }

  /**
   * Constructor which takes two strings representing the lower and upper bounds of the range (inclusive on both ends)
   *
   * @param theLowerBound
   *            A qualified date param representing the lower date bound (optionally may include time), e.g.
   *            "2011-02-22" or "2011-02-22T13:12:00"
   * @param theUpperBound
   *            A qualified date param representing the upper date bound (optionally may include time), e.g.
   *            "2011-02-22" or "2011-02-22T13:12:00"
   */
  public DateRangeParam(String theLowerBound, String theUpperBound) {
    setRangeFromDatesInclusive(theLowerBound, theUpperBound);
  }

  public QualifiedDateParam getLowerBound() {
    return myLowerBound;
  }

  public Date getLowerBoundAsInstant() {
    if (myLowerBound == null) {
      return null;
    }
    Date retVal = myLowerBound.getValue();
    if (myLowerBound.getComparator() != null) {
      switch (myLowerBound.getComparator()) {
      case GREATERTHAN:
        retVal = myLowerBound.getPrecision().add(retVal, 1);
        break;
      case GREATERTHAN_OR_EQUALS:
        break;
      case LESSTHAN:
      case LESSTHAN_OR_EQUALS:
        throw new IllegalStateException("Unvalid lower bound comparator: " + myLowerBound.getComparator());
      }
    }
    return retVal;
  }

  public QualifiedDateParam getUpperBound() {
    return myUpperBound;
  }

  public Date getUpperBoundAsInstant() {
    if (myUpperBound == null) {
      return null;
    }
    Date retVal = myUpperBound.getValue();
    if (myUpperBound.getComparator() != null) {
      switch (myUpperBound.getComparator()) {
      case LESSTHAN:
        retVal = new Date(retVal.getTime() - 1L);
        break;
      case LESSTHAN_OR_EQUALS:
        retVal = myUpperBound.getPrecision().add(retVal, 1);
        retVal = new Date(retVal.getTime() - 1L);
        break;
      case GREATERTHAN_OR_EQUALS:
      case GREATERTHAN:
        throw new IllegalStateException("Unvalid upper bound comparator: " + myUpperBound.getComparator());
      }
    }
    return retVal;
  }

  @Override
  public List<IQueryParameterOr> getValuesAsQueryTokens() {
    ArrayList<IQueryParameterOr> retVal = new ArrayList<IQueryParameterOr>();
    if (myLowerBound != null) {
      retVal.add(ParameterUtil.singleton(myLowerBound));
    }
    if (myUpperBound != null) {
      retVal.add(ParameterUtil.singleton(myUpperBound));
    }
    return retVal;
  }

  public void setLowerBound(QualifiedDateParam theLowerBound) {
    myLowerBound = theLowerBound;
    validateAndThrowDataFormatExceptionIfInvalid();
  }

  /**
   * Sets the range from a pair of dates, inclusive on both ends
   *
   * @param theLowerBound
   *            A qualified date param representing the lower date bound (optionally may include time), e.g.
   *            "2011-02-22" or "2011-02-22T13:12:00". Will be treated inclusively.
   * @param theUpperBound
   *            A qualified date param representing the upper date bound (optionally may include time), e.g.
   *            "2011-02-22" or "2011-02-22T13:12:00". Will be treated inclusively.
   */
  public void setRangeFromDatesInclusive(Date theLowerBound, Date theUpperBound) {
    if (theLowerBound != null) {
      myLowerBound = new QualifiedDateParam(QuantityCompararatorEnum.GREATERTHAN_OR_EQUALS, theLowerBound);
    }
    if (theUpperBound != null) {
      myUpperBound = new QualifiedDateParam(QuantityCompararatorEnum.LESSTHAN_OR_EQUALS, theUpperBound);
    }
    validateAndThrowDataFormatExceptionIfInvalid();
  }

  /**
   * Sets the range from a pair of dates, inclusive on both ends
   *
   * @param theLowerBound
   *            A qualified date param representing the lower date bound (optionally may include time), e.g.
   *            "2011-02-22" or "2011-02-22T13:12:00". Will be treated inclusively.
   * @param theUpperBound
   *            A qualified date param representing the upper date bound (optionally may include time), e.g.
   *            "2011-02-22" or "2011-02-22T13:12:00". Will be treated inclusively.
   */
  public void setRangeFromDatesInclusive(String theLowerBound, String theUpperBound) {
    if (StringUtils.isNotBlank(theLowerBound)) {
      myLowerBound = new QualifiedDateParam(QuantityCompararatorEnum.GREATERTHAN_OR_EQUALS, theLowerBound);
    }
    if (StringUtils.isNotBlank(theUpperBound)) {
      myUpperBound = new QualifiedDateParam(QuantityCompararatorEnum.LESSTHAN_OR_EQUALS, theUpperBound);
    }
    validateAndThrowDataFormatExceptionIfInvalid();
  }

  public void setUpperBound(QualifiedDateParam theUpperBound) {
    myUpperBound = theUpperBound;
    validateAndThrowDataFormatExceptionIfInvalid();
  }

  @Override
  public void setValuesAsQueryTokens(List<QualifiedParamList> theParameters) throws InvalidRequestException {
    for (List<String> paramList : theParameters) {
      if (paramList.size() == 0) {
        continue;
      }
      if (paramList.size() > 1) {
        throw new InvalidRequestException("DateRange parameter does not suppport OR queries");
      }
      String param = paramList.get(0);
      QualifiedDateParam parsed = new QualifiedDateParam();
      parsed.setValueAsQueryToken(null, param);
      addParam(parsed);
    }
  }

  private void addParam(QualifiedDateParam theParsed) throws InvalidRequestException {
    if (theParsed.getComparator() == null) {
      if (myLowerBound != null || myUpperBound != null) {
        throw new InvalidRequestException("Can not have multiple date range parameters for the same param without a qualifier");
      }

      myLowerBound = theParsed;
      myUpperBound = theParsed;
      // TODO: in this case, should set lower and upper to exact moments
      // using specified precision
    } else {

      switch (theParsed.getComparator()) {
      case GREATERTHAN:
      case GREATERTHAN_OR_EQUALS:
        if (myLowerBound != null) {
          throw new InvalidRequestException("Can not have multiple date range parameters for the same param that specify a lower bound");
        }
        myLowerBound = theParsed;
        break;
      case LESSTHAN:
      case LESSTHAN_OR_EQUALS:
        if (myUpperBound != null) {
          throw new InvalidRequestException("Can not have multiple date range parameters for the same param that specify an upper bound");
        }
        myUpperBound = theParsed;
        break;
      default:
        throw new InvalidRequestException("Unknown comparator: " + theParsed.getComparator());
      }

    }
  }

  private void validateAndThrowDataFormatExceptionIfInvalid() {
    boolean haveLowerBound = myLowerBound != null && myLowerBound.isEmpty() == false;
    boolean haveUpperBound = myUpperBound != null && myUpperBound.isEmpty() == false;
    if (haveLowerBound && haveUpperBound) {
      if (myLowerBound.getValue().after(myUpperBound.getValue())) {
        throw new DataFormatException("Lower bound of " + myLowerBound.getValueAsString() + " is after upper bound of " + myUpperBound.getValueAsString());
      }
    }

    if (haveLowerBound) {
      if (myLowerBound.getComparator() == null) {
        myLowerBound.setComparator(QuantityCompararatorEnum.GREATERTHAN_OR_EQUALS);
      }
      switch (myLowerBound.getComparator()) {
      case GREATERTHAN:
      case GREATERTHAN_OR_EQUALS:
      default:
        break;
      case LESSTHAN:
      case LESSTHAN_OR_EQUALS:
        throw new DataFormatException("Lower bound comparator must be > or >=, can not be " + myLowerBound.getComparator().getCode());
      }
    }

    if (haveUpperBound) {
      if (myUpperBound.getComparator() == null) {
        myUpperBound.setComparator(QuantityCompararatorEnum.LESSTHAN_OR_EQUALS);
      }
      switch (myUpperBound.getComparator()) {
      case LESSTHAN:
      case LESSTHAN_OR_EQUALS:
      default:
        break;
      case GREATERTHAN:
      case GREATERTHAN_OR_EQUALS:
        throw new DataFormatException("Upper bound comparator must be < or <=, can not be " + myUpperBound.getComparator().getCode());
      }
    }

  }

}
TOP

Related Classes of ca.uhn.fhir.rest.param.DateRangeParam

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.