/** Tests redirection reference getting/setting. */
 public void testRedirectionRef() throws Exception {
   final Request request = getRequest();
   final Response response = getResponse(request);
   String uri = "http://www.restlet.org/";
   Reference reference = getReference(uri);
   response.setLocationRef(uri);
   assertEquals(reference, response.getLocationRef());
   uri = "http://www.restlet.org/something";
   reference = getReference(uri);
   response.setLocationRef(reference);
   assertEquals(reference, response.getLocationRef());
 }
  /**
   * Handles a call by redirecting using the selected redirection mode.
   *
   * @param request The request to handle.
   * @param response The response to update.
   */
  @Override
  public void handle(Request request, Response response) {
    // Generate the target reference
    Reference targetRef = getTargetRef(request, response);

    switch (this.mode) {
      case MODE_CLIENT_PERMANENT:
        if (request.isLoggable()) {
          getLogger().log(Level.INFO, "Permanently redirecting client to: " + targetRef);
        }

        response.redirectPermanent(targetRef);
        break;

      case MODE_CLIENT_FOUND:
        if (request.isLoggable()) {
          getLogger().log(Level.INFO, "Redirecting client to found location: " + targetRef);
        }

        response.setLocationRef(targetRef);
        response.setStatus(Status.REDIRECTION_FOUND);
        break;

      case MODE_CLIENT_SEE_OTHER:
        if (request.isLoggable()) {
          getLogger().log(Level.INFO, "Redirecting client to another location: " + targetRef);
        }

        response.redirectSeeOther(targetRef);
        break;

      case MODE_CLIENT_TEMPORARY:
        if (request.isLoggable()) {
          getLogger().log(Level.INFO, "Temporarily redirecting client to: " + targetRef);
        }

        response.redirectTemporary(targetRef);
        break;

      case MODE_SERVER_OUTBOUND:
        if (request.isLoggable()) {
          getLogger().log(Level.INFO, "Redirecting via client dispatcher to: " + targetRef);
        }

        outboundServerRedirect(targetRef, request, response);
        break;

      case MODE_SERVER_INBOUND:
        if (request.isLoggable()) {
          getLogger().log(Level.INFO, "Redirecting via server dispatcher to: " + targetRef);
        }

        inboundServerRedirect(targetRef, request, response);
        break;
    }
  }
  /**
   * Sets the reference that the client should follow for redirections or resource creations. If you
   * pass a relative location URI, it will be resolved with the current base reference of the
   * request's resource reference (see {@link Request#getResourceRef()} and {@link
   * Reference#getBaseRef()}.<br>
   * <br>
   * Note that when used with HTTP connectors, this property maps to the "Location" header.
   *
   * @param locationUri The URI to set.
   * @see #setLocationRef(Reference)
   */
  public void setLocationRef(String locationUri) {
    Reference baseRef = null;

    if (getRequest().getResourceRef() != null) {
      if (getRequest().getResourceRef().getBaseRef() != null) {
        baseRef = getRequest().getResourceRef().getBaseRef();
      } else {
        baseRef = getRequest().getResourceRef();
      }
    }

    setLocationRef(new Reference(baseRef, locationUri).getTargetRef());
  }
  /**
   * Redirects a given call on the server-side to a next Restlet with a given target reference. In
   * the default implementation, the request HTTP headers, stored in the request's attributes, are
   * removed before dispatching. After dispatching, the response HTTP headers are also removed to
   * prevent conflicts with the main call.
   *
   * @param next The next Restlet to forward the call to.
   * @param targetRef The target reference with URI variables resolved.
   * @param request The request to handle.
   * @param response The response to update.
   */
  protected void serverRedirect(
      Restlet next, Reference targetRef, Request request, Response response) {
    if (next == null) {
      getLogger().warning("No next Restlet provided for server redirection to " + targetRef);
    } else {
      // Save the base URI if it exists as we might need it for
      // redirections
      Reference resourceRef = request.getResourceRef();
      Reference baseRef = resourceRef.getBaseRef();

      // Reset the protocol and let the dispatcher handle the protocol
      request.setProtocol(null);

      // Update the request to cleanly go to the target URI
      request.setResourceRef(targetRef);
      request.getAttributes().remove(HeaderConstants.ATTRIBUTE_HEADERS);
      next.handle(request, response);

      // Allow for response rewriting and clean the headers
      response.setEntity(rewrite(response.getEntity()));
      response.getAttributes().remove(HeaderConstants.ATTRIBUTE_HEADERS);
      request.setResourceRef(resourceRef);

      // In case of redirection, we may have to rewrite the redirect URI
      if (response.getLocationRef() != null) {
        Template rt = new Template(this.targetTemplate);
        rt.setLogger(getLogger());
        int matched = rt.parse(response.getLocationRef().toString(), request);

        if (matched > 0) {
          String remainingPart = (String) request.getAttributes().get("rr");

          if (remainingPart != null) {
            response.setLocationRef(baseRef.toString() + remainingPart);
          }
        }
      }
    }
  }
 /**
  * Temporarily redirects the client to a target URI. The client is expected to reuse the same
  * method for the new request.<br>
  * <br>
  * If you pass a relative target URI, it will be resolved with the current base reference of the
  * request's resource reference (see {@link Request#getResourceRef()} and {@link
  * Reference#getBaseRef()}.
  *
  * @param targetUri The target URI.
  */
 public void redirectTemporary(String targetUri) {
   setLocationRef(targetUri);
   setStatus(Status.REDIRECTION_TEMPORARY);
 }
 /**
  * Temporarily redirects the client to a target URI. The client is expected to reuse the same
  * method for the new request.
  *
  * @param targetRef The target reference.
  */
 public void redirectTemporary(Reference targetRef) {
   setLocationRef(targetRef);
   setStatus(Status.REDIRECTION_TEMPORARY);
 }
 /**
  * Redirects the client to a different URI that SHOULD be retrieved using a GET method on that
  * resource. This method exists primarily to allow the output of a POST-activated script to
  * redirect the user agent to a selected resource. The new URI is not a substitute reference for
  * the originally requested resource.<br>
  * <br>
  * If you pass a relative target URI, it will be resolved with the current base reference of the
  * request's resource reference (see {@link Request#getResourceRef()} and {@link
  * Reference#getBaseRef()}.
  *
  * @param targetUri The target URI.
  */
 public void redirectSeeOther(String targetUri) {
   setLocationRef(targetUri);
   setStatus(Status.REDIRECTION_SEE_OTHER);
 }
 /**
  * Redirects the client to a different URI that SHOULD be retrieved using a GET method on that
  * resource. This method exists primarily to allow the output of a POST-activated script to
  * redirect the user agent to a selected resource. The new URI is not a substitute reference for
  * the originally requested resource.
  *
  * @param targetRef The target reference.
  */
 public void redirectSeeOther(Reference targetRef) {
   setLocationRef(targetRef);
   setStatus(Status.REDIRECTION_SEE_OTHER);
 }
 /**
  * Permanently redirects the client to a target URI. The client is expected to reuse the same
  * method for the new request.<br>
  * <br>
  * If you pass a relative target URI, it will be resolved with the current base reference of the
  * request's resource reference (see {@link Request#getResourceRef()} and {@link
  * Reference#getBaseRef()}.
  *
  * @param targetUri The target URI.
  */
 public void redirectPermanent(String targetUri) {
   setLocationRef(targetUri);
   setStatus(Status.REDIRECTION_PERMANENT);
 }
 /**
  * Permanently redirects the client to a target URI. The client is expected to reuse the same
  * method for the new request.
  *
  * @param targetRef The target URI reference.
  */
 public void redirectPermanent(Reference targetRef) {
   setLocationRef(targetRef);
   setStatus(Status.REDIRECTION_PERMANENT);
 }