Esempio n. 1
0
  /**
   * Handles a call by first verifying the optional request conditions and continue the processing
   * if possible. Note that in order to evaluate those conditions, {@link #getInfo()} or {@link
   * #getInfo(Variant)} methods might be invoked.
   *
   * @return The response entity.
   * @throws ResourceException
   */
  protected Representation doConditionalHandle() throws ResourceException {
    Representation result = null;

    if (getConditions().hasSome()) {
      RepresentationInfo resultInfo = null;

      if (existing) {
        if (isNegotiated()) {
          resultInfo = doGetInfo(getPreferredVariant(getVariants(Method.GET)));
        } else {
          resultInfo = doGetInfo();
        }

        if (resultInfo == null) {
          if ((getStatus() == null)
              || (getStatus().isSuccess() && !Status.SUCCESS_NO_CONTENT.equals(getStatus()))) {
            setStatus(Status.CLIENT_ERROR_NOT_FOUND);
          } else {
            // Keep the current status as the developer might prefer
            // a special status like 'method not authorized'.
          }
        } else {
          Status status = getConditions().getStatus(getMethod(), resultInfo);

          if (status != null) {
            setStatus(status);
          }
        }
      } else {
        Status status = getConditions().getStatus(getMethod(), resultInfo);

        if (status != null) {
          setStatus(status);
        }
      }

      if ((Method.GET.equals(getMethod()) || Method.HEAD.equals(getMethod()))
          && resultInfo instanceof Representation) {
        result = (Representation) resultInfo;
      } else if ((getStatus() != null) && getStatus().isSuccess()) {
        // Conditions were passed successfully, continue the normal
        // processing.
        if (isNegotiated()) {
          // Reset the list of variants, as the method differs.
          getVariants().clear();
          result = doNegotiatedHandle();
        } else {
          result = doHandle();
        }
      }
    } else {
      if (isNegotiated()) {
        result = doNegotiatedHandle();
      } else {
        result = doHandle();
      }
    }

    return result;
  }
Esempio n. 2
0
  /**
   * Handles a GET call by automatically returning the best representation available. The content
   * negotiation is automatically supported based on the client's preferences available in the
   * request. This feature can be turned off using the "negotiateContent" property.<br>
   * <br>
   * If the resource's "available" property is set to false, the method immediately returns with a
   * {@link Status#CLIENT_ERROR_NOT_FOUND} status.<br>
   * <br>
   * The negotiated representation is obtained by calling the {@link #getPreferredVariant()}. If a
   * variant is sucessfully selected, then the {@link #represent(Variant)} method is called to get
   * the actual representation corresponding to the metadata in the variant.<br>
   * <br>
   * If no variant matching the client preferences is available, the response status is set to
   * {@link Status#CLIENT_ERROR_NOT_ACCEPTABLE} and the list of available representations is
   * returned in the response entity as a textual list of URIs (only if the variants have an
   * identifier properly set).<br>
   * <br>
   * If the content negotiation is turned off and only one variant is defined in the "variants"
   * property, then its representation is returned by calling the {@link #represent(Variant)}
   * method. If several variants are available, then the list of available representations is
   * returned in the response entity as a textual list of URIs (only if the variants have an
   * identifier properly set).<br>
   * <br>
   * If no variant is defined in the "variants" property, the response status is set to {@link
   * Status#CLIENT_ERROR_NOT_FOUND}. <br>
   * If it is disabled and multiple variants are available for the target resource, then a 300
   * (Multiple Choices) status will be returned with the list of variants URI if available.
   * Conditional GETs are also automatically supported.
   */
  @Override
  public void handleGet() {
    if (!isAvailable()) {
      // Resource not existing or not available to the current client
      getResponse().setStatus(Status.CLIENT_ERROR_NOT_FOUND);
    } else {
      // The variant that may need to meet the request conditions
      Representation selectedRepresentation = null;

      final List<Variant> variants = getVariants();
      if ((variants == null) || (variants.isEmpty())) {
        // Resource not found
        getResponse().setStatus(Status.CLIENT_ERROR_NOT_FOUND);
        getLogger()
            .warning(
                "A resource should normally have at least one variant added by calling getVariants().add() in the constructor. Check your resource \""
                    + getRequest().getResourceRef()
                    + "\".");
      } else if (isNegotiateContent()) {
        final Variant preferredVariant = getPreferredVariant();

        if (preferredVariant == null) {
          // No variant was found matching the client preferences
          getResponse().setStatus(Status.CLIENT_ERROR_NOT_ACCEPTABLE);

          // The list of all variants is transmitted to the client
          final ReferenceList refs = new ReferenceList(variants.size());
          for (final Variant variant : variants) {
            if (variant.getIdentifier() != null) {
              refs.add(variant.getIdentifier());
            }
          }

          getResponse().setEntity(refs.getTextRepresentation());
        } else {
          // Set the variant dimensions used for content negotiation
          getResponse().getDimensions().clear();
          getResponse().getDimensions().add(Dimension.CHARACTER_SET);
          getResponse().getDimensions().add(Dimension.ENCODING);
          getResponse().getDimensions().add(Dimension.LANGUAGE);
          getResponse().getDimensions().add(Dimension.MEDIA_TYPE);

          // Set the negotiated representation as response entity
          getResponse().setEntity(getRepresentation(preferredVariant));
        }

        selectedRepresentation = getResponse().getEntity();
      } else {
        if (variants.size() == 1) {
          getResponse().setEntity(getRepresentation(variants.get(0)));
          selectedRepresentation = getResponse().getEntity();
        } else {
          final ReferenceList variantRefs = new ReferenceList();

          for (final Variant variant : variants) {
            if (variant.getIdentifier() != null) {
              variantRefs.add(variant.getIdentifier());
            } else {
              getLogger()
                  .warning(
                      "A resource with multiple variants should provide an identifier for each variant when content negotiation is turned off");
            }
          }

          if (variantRefs.size() > 0) {
            // Return the list of variants
            getResponse().setStatus(Status.REDIRECTION_MULTIPLE_CHOICES);
            getResponse().setEntity(variantRefs.getTextRepresentation());
          } else {
            getResponse().setStatus(Status.CLIENT_ERROR_NOT_FOUND);
          }
        }
      }

      if (selectedRepresentation == null) {
        if ((getResponse().getStatus() == null)
            || (getResponse().getStatus().isSuccess()
                && !Status.SUCCESS_NO_CONTENT.equals(getResponse().getStatus()))) {
          getResponse().setStatus(Status.CLIENT_ERROR_NOT_FOUND);
        } else {
          // Keep the current status as the developer might prefer a
          // special status like 'method not authorized'.
        }
      } else {
        // The given representation (even if null) must meet the request
        // conditions (if any).
        if (getRequest().getConditions().hasSome()) {
          final Status status =
              getRequest()
                  .getConditions()
                  .getStatus(getRequest().getMethod(), selectedRepresentation);

          if (status != null) {
            getResponse().setStatus(status);
            getResponse().setEntity(null);
          }
        }
      }
    }
  }