protected void doError(Request request, Response response, OAuthProblemException exception) {
    if (OAuth2Utils.ParameterLocation.HTTP_HEADER.equals(parameterLocation)) {
      if (!isOptional()) {
        if (isRechallenging()) {
          boolean loggable =
              response.getRequest().isLoggable() && getLogger().isLoggable(Level.FINE);

          if (loggable) {
            getLogger().log(Level.FINE, "An authentication challenge was requested.");
          }

          response.setStatus(Status.CLIENT_ERROR_UNAUTHORIZED);
          response
              .getChallengeRequests()
              .add(
                  getTokenVerifier()
                      .getTokenExtractor()
                      .createChallengeRequest(getRealm(), exception));
          response.setEntity(new JacksonRepresentation<Map>(exception.getErrorMessage()));
        } else {
          forbid(response);
        }
      }
    } else {
      response.setStatus(exception.getStatus());
      response.setEntity(new JacksonRepresentation<Map>(exception.getErrorMessage()));
    }
  }
  /**
   * Allows filtering before its handling by the target Restlet. By default it parses the template
   * variable, adjust the base reference, then extracts the attributes from form parameters (query,
   * cookies, entity) and finally tries to validate the variables as indicated by the {@link
   * #validate(String, boolean, String)} method.
   *
   * @param request The request to filter.
   * @param response The response to filter.
   * @return The {@link Filter#CONTINUE} status.
   */
  @Override
  protected int beforeHandle(Request request, Response response) {
    if (this.validations != null) {
      for (ValidateInfo validate : getValidations()) {
        if (validate.required && !request.getAttributes().containsKey(validate.attribute)) {
          response.setStatus(
              Status.CLIENT_ERROR_BAD_REQUEST,
              "Unable to find the \""
                  + validate.attribute
                  + "\" attribute in the request. Please check your request.");
        } else if (validate.format != null) {
          Object value = request.getAttributes().get(validate.attribute);

          if ((value != null) && !Pattern.matches(validate.format, value.toString())) {
            response.setStatus(
                Status.CLIENT_ERROR_BAD_REQUEST,
                "Unable to validate the value of the \""
                    + validate.attribute
                    + "\" attribute. The expected format is: "
                    + validate.format
                    + " (Java Regex). Please check your request.");
          }
        }
      }
    }

    return CONTINUE;
  }
Example #3
0
  /**
   * Handles a call for a local entity. By default, only GET and HEAD methods are implemented.
   *
   * @param request The request to handle.
   * @param response The response to update.
   * @param decodedPath The URL decoded entity path.
   */
  @Override
  protected void handleLocal(Request request, Response response, String decodedPath) {
    int spi = decodedPath.indexOf("!/");
    String fileUri;
    String entryName;
    if (spi != -1) {
      fileUri = decodedPath.substring(0, spi);
      entryName = decodedPath.substring(spi + 2);
    } else {
      fileUri = decodedPath;
      entryName = "";
    }

    LocalReference fileRef = new LocalReference(fileUri);
    if (Protocol.FILE.equals(fileRef.getSchemeProtocol())) {
      final File file = fileRef.getFile();
      if (Method.GET.equals(request.getMethod()) || Method.HEAD.equals(request.getMethod())) {
        handleGet(request, response, file, entryName, getMetadataService());
      } else if (Method.PUT.equals(request.getMethod())) {
        handlePut(request, response, file, entryName);
      } else {
        response.setStatus(Status.CLIENT_ERROR_METHOD_NOT_ALLOWED);
        response.getAllowedMethods().add(Method.GET);
        response.getAllowedMethods().add(Method.HEAD);
        response.getAllowedMethods().add(Method.PUT);
      }
    } else {
      response.setStatus(Status.SERVER_ERROR_NOT_IMPLEMENTED, "Only works on local files.");
    }
  }
Example #4
0
  /**
   * Handles a call. The default behavior is to initialize the Restlet by setting the current
   * context using the {@link Context#setCurrent(Context)} method and by attempting to start it,
   * unless it was already started. If an exception is thrown during the start action, then the
   * response status is set to {@link Status#SERVER_ERROR_INTERNAL}.
   *
   * <p>Subclasses overriding this method should make sure that they call super.handle(request,
   * response) before adding their own logic.
   *
   * @param request The request to handle.
   * @param response The response to update.
   */
  public void handle(Request request, Response response) {
    // Associate the response to the current thread
    Response.setCurrent(response);

    // Associate the context to the current thread
    if (getContext() != null) {
      Context.setCurrent(getContext());
    }

    // Check if the Restlet was started
    if (isStopped()) {
      try {
        start();
      } catch (Exception e) {
        // Occurred while starting the Restlet
        getContext().getLogger().log(Level.WARNING, UNABLE_TO_START, e);
        response.setStatus(Status.SERVER_ERROR_INTERNAL);
      }

      if (!isStarted()) {
        // No exception raised but the Restlet somehow couldn't be
        // started
        getContext().getLogger().log(Level.WARNING, UNABLE_TO_START);
        response.setStatus(Status.SERVER_ERROR_INTERNAL);
      }
    }
  }
 /** Tests status getting/setting. */
 public void testStatus() throws Exception {
   final Request request = getRequest();
   final Response response = getResponse(request);
   response.setStatus(Status.SUCCESS_OK);
   assertEquals(Status.SUCCESS_OK, response.getStatus());
   response.setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
   assertEquals(Status.CLIENT_ERROR_BAD_REQUEST, response.getStatus());
 }
Example #6
0
  /**
   * Handles a GET call.
   *
   * @param request The request to answer.
   * @param response The response to update.
   * @param file The Zip archive file.
   * @param entryName The Zip archive entry name.
   * @param metadataService The metadata service.
   */
  protected void handleGet(
      Request request,
      Response response,
      File file,
      String entryName,
      final MetadataService metadataService) {

    if (!file.exists()) {
      response.setStatus(Status.CLIENT_ERROR_NOT_FOUND);
    } else {
      ZipFile zipFile;

      try {
        zipFile = new ZipFile(file);
      } catch (Exception e) {
        response.setStatus(Status.SERVER_ERROR_INTERNAL, e);
        return;
      }

      Entity entity = new ZipEntryEntity(zipFile, entryName, metadataService);
      if (!entity.exists()) {
        response.setStatus(Status.CLIENT_ERROR_NOT_FOUND);
      } else {
        final Representation output;

        if (entity.isDirectory()) {
          // Return the directory listing
          final Collection<Entity> children = entity.getChildren();
          final ReferenceList rl = new ReferenceList(children.size());
          String fileUri = LocalReference.createFileReference(file).toString();
          String scheme = request.getResourceRef().getScheme();
          String baseUri = scheme + ":" + fileUri + "!/";

          for (final Entity entry : children) {
            rl.add(baseUri + entry.getName());
          }

          output = rl.getTextRepresentation();

          try {
            zipFile.close();
          } catch (IOException e) {
            // Do something ???
          }
        } else {
          // Return the file content
          output = entity.getRepresentation(metadataService.getDefaultMediaType(), getTimeToLive());
          output.setLocationRef(request.getResourceRef());
          Entity.updateMetadata(entity.getName(), output, true, getMetadataService());
        }

        response.setStatus(Status.SUCCESS_OK);
        response.setEntity(output);
      }
    }
  }
  /**
   * 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;
    }
  }
  @Override
  public void handle(Request request, Response response) {
    super.handle(request, response);

    if (Method.GET.equals(request.getMethod())) {
      response.setEntity(getSwagger());
    } else {
      response.setStatus(Status.CLIENT_ERROR_METHOD_NOT_ALLOWED);
    }
  }
    @Override
    public void handle(Request request, Response response) {
      Form form = request.getResourceRef().getQueryAsForm();
      List<Range> ranges = request.getRanges();
      boolean match = false;

      for (Parameter parameter : form) {
        long index = 0;
        long length = 0;
        String value = parameter.getValue();
        if (value.startsWith("-")) {
          index = Range.INDEX_LAST;
          length = Long.parseLong(value.substring(1));
        } else if (value.endsWith("-")) {
          index = Long.parseLong(value.substring(0, value.length() - 1));
          length = Range.SIZE_MAX;
        } else {
          String[] tab = value.split("-");
          if (tab.length == 2) {
            index = Long.parseLong(tab[0]);
            length = Long.parseLong(tab[1]) - index;
          }
        }

        boolean found = false;
        for (Range range : ranges) {
          found = (index == range.getIndex()) && (length == range.getSize());
          if (found) {
            break;
          }
        }
        if (!found) {
          break;
        }
        match = true;
      }
      if (match) {
        response.setStatus(Status.SUCCESS_OK);
        response.setEntity(str1000, MediaType.TEXT_PLAIN);
      } else {
        response.setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
      }
    }
Example #10
0
  /**
   * Handles a call by invoking the next Restlet if it is available.
   *
   * @param request The request to handle.
   * @param response The response to update.
   */
  @Override
  public void handle(Request request, Response response) {
    super.handle(request, response);
    Restlet next = getNext(request, response);

    if (next != null) {
      doHandle(next, request, response);
    } else {
      response.setStatus(Status.CLIENT_ERROR_NOT_FOUND);
    }
  }
  @Override
  public void handle(Request request, Response response) {
    super.handle(request, response);

    try {
      if (request.getMethod().equals(Method.GET)) {

        try {
          if ("users".equalsIgnoreCase(request.getResourceRef().getLastSegment())) {
            UserListValue users = importer.users();
            StringRepresentation result =
                new StringRepresentation(
                    users.toJSON(),
                    MediaType.APPLICATION_JSON,
                    Language.DEFAULT,
                    CharacterSet.UTF_8);
            response.setStatus(Status.SUCCESS_OK);
            response.setEntity(result);
          } else if ("groups".equalsIgnoreCase(request.getResourceRef().getLastSegment())) {
            GroupListValue groups = importer.groups();
            StringRepresentation result =
                new StringRepresentation(
                    groups.toJSON(),
                    MediaType.APPLICATION_JSON,
                    Language.DEFAULT,
                    CharacterSet.UTF_8);
            response.setStatus(Status.SUCCESS_OK);
            response.setEntity(result);
          }
        } catch (ResourceException e) {
          response.setStatus(Status.CLIENT_ERROR_UNAUTHORIZED);
          response.setEntity(e.getStatus().getDescription(), MediaType.TEXT_PLAIN);
        }

      } else {
        response.setStatus(Status.CLIENT_ERROR_METHOD_NOT_ALLOWED);
      }
    } finally {
      request.release();
    }
  }
Example #12
0
  /** Pre-processing method testing if the client IP address is in the set of blocked addresses. */
  @Override
  protected int beforeHandle(Request request, Response response) {
    int result = STOP;

    if (getBlockedAddresses().contains(request.getClientInfo().getAddress())) {
      response.setStatus(Status.CLIENT_ERROR_FORBIDDEN, "Your IP address was blocked");
    } else {
      result = CONTINUE;
    }

    return result;
  }
  @Override
  public void challenge(Response response, boolean stale) {
    // Load the FreeMarker template
    Representation ftl =
        new ClientResource(
                LocalReference.createClapReference(getClass().getPackage()) + "/Login.ftl")
            .get();

    // Wraps the bean with a FreeMarker representation
    response.setEntity(
        new TemplateRepresentation(
            ftl, response.getRequest().getResourceRef(), MediaType.TEXT_HTML));
    response.setStatus(Status.CLIENT_ERROR_UNAUTHORIZED);
  }
Example #14
0
  /**
   * Invoked upon failed authentication. By default, it updates the request's clientInfo and
   * challengeResponse "authenticated" properties, and returns {@link Filter#STOP}.
   *
   * @param request The request sent.
   * @param response The response to update.
   * @return The filter continuation code.
   */
  @SuppressWarnings("deprecation")
  protected int unauthenticated(Request request, Response response) {
    if (isOptional()) {
      response.setStatus(Status.SUCCESS_OK);
      return CONTINUE;
    }

    // Update the challenge response accordingly
    if (request.getChallengeResponse() != null) {
      request.getChallengeResponse().setAuthenticated(false);
    }

    // Update the client info accordingly
    if (request.getClientInfo() != null) {
      request.getClientInfo().setAuthenticated(false);
    }

    // Stop the filtering chain
    return STOP;
  }
Example #15
0
 private void setStatusIntoResponse(final Status status, final Response response) {
   response.setStatus(status);
 }
Example #16
0
  /**
   * Returns the next Restlet if available.
   *
   * @param request The request to handle.
   * @param response The response to update.
   * @return The next Restlet if available or null.
   */
  public Restlet getNext(Request request, Response response) {
    Route result = null;

    for (int i = 0; (result == null) && (i < getMaxAttempts()); i++) {
      if (i > 0) {
        // Before attempting another time, let's
        // sleep during the "retryDelay" set.
        try {
          Thread.sleep(getRetryDelay());
        } catch (InterruptedException e) {
        }
      }

      if (this.routes != null) {
        // Select the routing mode
        switch (getRoutingMode()) {
          case MODE_BEST_MATCH:
            result = getRoutes().getBest(request, response, getRequiredScore());
            break;

          case MODE_FIRST_MATCH:
            result = getRoutes().getFirst(request, response, getRequiredScore());
            break;

          case MODE_LAST_MATCH:
            result = getRoutes().getLast(request, response, getRequiredScore());
            break;

          case MODE_NEXT_MATCH:
            result = getRoutes().getNext(request, response, getRequiredScore());
            break;

          case MODE_RANDOM_MATCH:
            result = getRoutes().getRandom(request, response, getRequiredScore());
            break;

          case MODE_CUSTOM:
            result = getCustom(request, response);
            break;
        }
      }
    }

    if (result == null) {
      // If nothing matched in the routes list,
      // check the default route
      if ((getDefaultRoute() != null)
          && (getDefaultRoute().score(request, response) >= getRequiredScore())) {
        result = getDefaultRoute();
      } else {
        // No route could be found
        response.setStatus(Status.CLIENT_ERROR_NOT_FOUND);
      }
    }

    if (request.isLoggable()) {
      logRoute(result);
    }

    return result;
  }
 /**
  * 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);
 }
 /**
  * Sets the status.
  *
  * @param status The status to set.
  * @param throwable The related error or exception.
  */
 public void setStatus(Status status, Throwable throwable) {
   setStatus(new Status(status, throwable));
 }
Example #19
0
  /**
   * Handles a PUT call.
   *
   * @param request The request to answer.
   * @param response The response to update.
   * @param file The Zip archive file.
   * @param entryName The Zip archive entry name.
   */
  protected void handlePut(Request request, Response response, File file, String entryName) {
    boolean zipExists = file.exists();
    ZipOutputStream zipOut = null;

    if ("".equals(entryName)
        && request.getEntity() != null
        && request.getEntity().getDisposition() != null) {
      entryName = request.getEntity().getDisposition().getFilename();
    }
    if (entryName == null) {
      response.setStatus(Status.CLIENT_ERROR_BAD_REQUEST, "Must specify an entry name.");
      return;
    }
    // boolean canAppend = true;
    boolean canAppend = !zipExists;
    boolean isDirectory = entryName.endsWith("/");
    boolean wrongReplace = false;
    try {
      if (zipExists) {
        ZipFile zipFile = new ZipFile(file);
        // Already exists ?
        canAppend &= null == zipFile.getEntry(entryName);
        // Directory with the same name ?
        if (isDirectory) {
          wrongReplace = null != zipFile.getEntry(entryName.substring(0, entryName.length() - 1));
        } else {
          wrongReplace = null != zipFile.getEntry(entryName + "/");
        }

        canAppend &= !wrongReplace;
        zipFile.close();
      }

      Representation entity;
      if (isDirectory) {
        entity = null;
      } else {
        entity = request.getEntity();
      }

      if (canAppend) {
        try {
          // zipOut = new ZipOutputStream(new BufferedOutputStream(new
          // FileOutputStream(file, true)));
          zipOut = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(file)));
          writeEntityStream(entity, zipOut, entryName);
          zipOut.close();
        } catch (Exception e) {
          response.setStatus(Status.SERVER_ERROR_INTERNAL, e);
          return;
        } finally {
          if (zipOut != null) zipOut.close();
        }
        response.setStatus(Status.SUCCESS_CREATED);
      } else {
        if (wrongReplace) {
          response.setStatus(
              Status.CLIENT_ERROR_BAD_REQUEST,
              "Directory cannot be replace by a file or file by a directory.");
        } else {
          File writeTo = null;
          ZipFile zipFile = null;
          try {
            writeTo = File.createTempFile("restlet_zip_", "zip");
            zipFile = new ZipFile(file);
            zipOut = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(writeTo)));
            Enumeration<? extends ZipEntry> entries = zipFile.entries();
            boolean replaced = false;
            while (entries.hasMoreElements()) {
              ZipEntry e = entries.nextElement();
              if (!replaced && entryName.equals(e.getName())) {
                writeEntityStream(entity, zipOut, entryName);
                replaced = true;
              } else {
                zipOut.putNextEntry(e);
                BioUtils.copy(new BufferedInputStream(zipFile.getInputStream(e)), zipOut);
                zipOut.closeEntry();
              }
            }
            if (!replaced) {
              writeEntityStream(entity, zipOut, entryName);
            }
            zipFile.close();
            zipOut.close();
          } finally {
            try {
              if (zipFile != null) zipFile.close();
            } finally {
              if (zipOut != null) zipOut.close();
            }
          }

          if (!(BioUtils.delete(file) && writeTo.renameTo(file))) {
            if (!file.exists()) file.createNewFile();
            FileInputStream fis = null;
            FileOutputStream fos = null;
            try {
              fis = new FileInputStream(writeTo);
              fos = new FileOutputStream(file);
              // ByteUtils.write(fis.getChannel(),
              // fos.getChannel());
              BioUtils.copy(fis, fos);
              response.setStatus(Status.SUCCESS_OK);
            } finally {
              try {
                if (fis != null) fis.close();
              } finally {
                if (fos != null) fos.close();
              }
            }
          } else {
            response.setStatus(Status.SUCCESS_OK);
          }
        }
      }
    } catch (Exception e) {
      response.setStatus(Status.SERVER_ERROR_INTERNAL, e);
      return;
    }
  }
  /**
   * Handles a call.
   *
   * @param request The request to handle.
   * @param response The response to update.
   */
  @Override
  public void handle(Request request, Response response) {
    Connection connection = null;

    if (request.getMethod().equals(Method.POST)) {
      try {
        // Parse the JDBC URI
        String connectionURI = request.getResourceRef().toString();

        // Parse the request to extract necessary info
        DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
        Document requestDoc = docBuilder.parse(new InputSource(request.getEntity().getReader()));

        Element rootElt = (Element) requestDoc.getElementsByTagName("request").item(0);
        Element headerElt = (Element) rootElt.getElementsByTagName("header").item(0);
        Element connectionElt = (Element) headerElt.getElementsByTagName("connection").item(0);

        // Read the connection pooling setting
        Node usePoolingNode = connectionElt.getElementsByTagName("usePooling").item(0);
        boolean usePooling = usePoolingNode.getTextContent().equals("true") ? true : false;

        // Read the paging setting
        Node startNode = headerElt.getElementsByTagName("start").item(0);
        int start =
            startNode != null && startNode.getTextContent().trim().length() > 0
                ? Integer.parseInt(startNode.getTextContent())
                : 0;

        Node limitNode = headerElt.getElementsByTagName("limit").item(0);
        int limit =
            limitNode != null && limitNode.getTextContent().trim().length() > 0
                ? Integer.parseInt(limitNode.getTextContent())
                : -1;

        // Read the connection properties
        NodeList propertyNodes = connectionElt.getElementsByTagName("property");
        Node propertyNode = null;
        Properties properties = null;
        String name = null;
        String value = null;
        for (int i = 0; i < propertyNodes.getLength(); i++) {
          propertyNode = propertyNodes.item(i);

          if (properties == null) {
            properties = new Properties();
          }
          name = propertyNode.getAttributes().getNamedItem("name").getTextContent();
          value = propertyNode.getTextContent();
          properties.setProperty(name, value);
        }

        Node returnGeneratedKeysNode =
            headerElt.getElementsByTagName("returnGeneratedKeys").item(0);
        boolean returnGeneratedKeys =
            returnGeneratedKeysNode.getTextContent().equals("true") ? true : false;

        // Read the SQL body and get the list of sql statements
        Element bodyElt = (Element) rootElt.getElementsByTagName("body").item(0);
        NodeList statementNodes = bodyElt.getElementsByTagName("statement");
        List<String> sqlRequests = new ArrayList<String>();
        for (int i = 0; i < statementNodes.getLength(); i++) {
          String sqlRequest = statementNodes.item(i).getTextContent();
          sqlRequests.add(sqlRequest);
        }

        // Execute the List of SQL requests
        connection = getConnection(connectionURI, properties, usePooling);
        JdbcResult result = handleSqlRequests(connection, returnGeneratedKeys, sqlRequests);
        response.setEntity(new RowSetRepresentation(result, start, limit));
      } catch (SQLException se) {
        getLogger().log(Level.WARNING, "Error while processing the SQL request", se);
        response.setStatus(Status.SERVER_ERROR_INTERNAL, se);
      } catch (ParserConfigurationException pce) {
        getLogger().log(Level.WARNING, "Error with XML parser configuration", pce);
        response.setStatus(Status.CLIENT_ERROR_BAD_REQUEST, pce);
      } catch (SAXException se) {
        getLogger().log(Level.WARNING, "Error while parsing the XML document", se);
        response.setStatus(Status.CLIENT_ERROR_BAD_REQUEST, se);
      } catch (IOException ioe) {
        getLogger().log(Level.WARNING, "Input/Output exception", ioe);
        response.setStatus(Status.SERVER_ERROR_INTERNAL, ioe);
      }
    } else {
      throw new IllegalArgumentException("Only the POST method is supported");
    }
  }
 /**
  * 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);
 }
 /**
  * Sets the status.
  *
  * @param status The status to set.
  * @param throwable The related error or exception.
  * @param message The status message.
  */
 public void setStatus(Status status, Throwable throwable, String message) {
   setStatus(new Status(status, throwable, message));
 }
 /**
  * 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);
 }
 /**
  * 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);
 }
 /**
  * Sets the status.
  *
  * @param status The status to set (code and reason phrase).
  * @param description The longer status description.
  */
 public void setStatus(Status status, String description) {
   setStatus(new Status(status, description));
 }