Package org.eclipse.orion.server.cf.servlets

Source Code of org.eclipse.orion.server.cf.servlets.AbstractRESTHandler

/*******************************************************************************
* Copyright (c) 2013 IBM Corporation and others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.orion.server.cf.servlets;

import java.io.InputStreamReader;
import java.net.URLDecoder;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.orion.internal.server.servlets.ServletResourceHandler;
import org.eclipse.orion.internal.server.servlets.task.TaskJobHandler;
import org.eclipse.orion.server.cf.jobs.CFJob;
import org.eclipse.orion.server.cf.objects.CFObject;
import org.eclipse.orion.server.core.ServerStatus;
import org.eclipse.orion.server.servlets.JsonURIUnqualificationStrategy;
import org.eclipse.osgi.util.NLS;
import org.json.JSONObject;
import org.json.JSONTokener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* An abstract REST object handler. The class contains a set of default helper methods
* for common functions, e. g. resource extraction, error handing, etc.
*/
public abstract class AbstractRESTHandler<T extends CFObject> extends ServletResourceHandler<String> {

  private final Logger logger = LoggerFactory.getLogger("org.eclipse.orion.server.cf"); //$NON-NLS-1$

  protected ServletResourceHandler<IStatus> statusHandler;

  public AbstractRESTHandler(ServletResourceHandler<IStatus> statusHandler) {
    this.statusHandler = statusHandler;
  }

  /**
   * Builds the handled resource according to custom criteria.
   * @param request The request object used to build the resource.
   * @param path Path suffix required to handle the request.
   * @throws CoreException if the resource cannot be constructed due to an internal server error.
   * @return <code>null</code> if the resource cannot be constructed due to invalid request, the resource object otherwise.
   */
  protected abstract T buildResource(HttpServletRequest request, String path) throws CoreException;

  /**
   * Helper method for PUT data extraction.
   * @param request The PUT requested to be processed.
   * @return The extracted data JSON or null if none provided or invalid JSON format.
   */
  protected JSONObject extractJSONData(final HttpServletRequest request) {
    try {
      JSONTokener tokener = new JSONTokener(new InputStreamReader(request.getInputStream()));
      return new JSONObject(tokener);
    } catch (Exception ex) {
      return null;
    }
  }

  protected JSONObject extractJSONData(final String param) {
    try {
      return param != null ? new JSONObject(URLDecoder.decode(param, "UTF8")) : null;
    } catch (Exception e) {
      return null;
    }
  }

  /**
   * Handles a GET request. Note this method is meant to be overridden in descendant classes.
   * @param request The GET request being handled.
   * @param response The response associated with the request.
   * @param path Path suffix required to handle the request.
   * @return A {@link JazzJob} which returns the requested resource on completion.
   */
  protected CFJob handleGet(T resource, final HttpServletRequest request, final HttpServletResponse response, final String path) {
    return new CFJob(request, false) {
      @Override
      protected IStatus performJob() {
        String msg = NLS.bind("Failed to handle request for {0}", path); //$NON-NLS-1$
        return new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_NOT_IMPLEMENTED, msg, null);
      }
    };
  }

  /**
   * Handles an idempotent PUT request. Note this method is meant to be overridden in descendant classes.
   * @param request The PUT request being handled.
   * @param response The response associated with the request.
   * @param path Path suffix required to handle the request.
   * @return A {@link JazzJob} which returns the PUT request result on completion.
   */
  protected CFJob handlePut(T resource, final HttpServletRequest request, final HttpServletResponse response, final String path) {
    return new CFJob(request, false) {
      @Override
      protected IStatus performJob() {
        String msg = NLS.bind("Failed to handle request for {0}", path); //$NON-NLS-1$
        return new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_NOT_IMPLEMENTED, msg, null);
      }
    };
  }

  /**
   * Handles a POST request. Note this method is meant to be overridden in descendant classes.
   * The POST request is not idempotent as PUT, although it may handle similar operations.
   * @param request The POST request being handled.
   * @param response The response associated with the request.
   * @param path Path suffix required to handle the request.
   * @return A {@link JazzJob} which returns the POST request result on completion.
   */
  protected CFJob handlePost(final T resource, final HttpServletRequest request, final HttpServletResponse response, final String path) {
    return new CFJob(request, false) {
      @Override
      protected IStatus performJob() {
        String msg = NLS.bind("Failed to handle request for {0}", path); //$NON-NLS-1$
        return new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_NOT_IMPLEMENTED, msg, null);
      }
    };
  }

  /**
   * Handles a DELETE request. Note this method is meant to be overridden in descendant classes.
   * @param request The DELETE request being handled.
   * @param response The response associated with the request.
   * @param path Path suffix required to handle the request.
   * @return A {@link JazzJob} which returns the DELETE request result on completion.
   */
  protected CFJob handleDelete(T resource, final HttpServletRequest request, final HttpServletResponse response, final String path) {
    return new CFJob(request, false) {
      @Override
      protected IStatus performJob() {
        String msg = NLS.bind("Failed to handle request for {0}", path); //$NON-NLS-1$
        return new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_NOT_IMPLEMENTED, msg, null);
      }
    };
  }

  /**
   * A helper method which handles returning a 404 HTTP error status.
   * @param request The request being handled.
   * @param response The response associated with the request.
   * @param path Path mapped to the handled request. Used to display the error message.
   * @return <code>true</code> iff the 404 has been sent, <code>false</code> otherwise.
   */
  protected boolean handleNotExistingResource(HttpServletRequest request, HttpServletResponse response, String path) throws ServletException {
    String msg = NLS.bind("Failed to handle request for {0}", path); //$NON-NLS-1$
    ServerStatus status = new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_NOT_FOUND, msg, null);
    return statusHandler.handleRequest(request, response, status);
  }

  /**
   * A helper method which handles returning a 409 HTTP error status.
   * @param request The request being handled.
   * @param response The response associated with the request.
   * @param path Path mapped to the handled request. Used to display the error message.
   * @return <code>true</code> iff the 409 has been sent, <code>false</code> otherwise.
   */
  protected boolean handleConflictingResource(HttpServletRequest request, HttpServletResponse response, String path) throws ServletException {
    String msg = NLS.bind("Failed to handle request for {0}", path); //$NON-NLS-1$
    ServerStatus status = new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_CONFLICT, msg, null);
    return statusHandler.handleRequest(request, response, status);
  }

  @Override
  public boolean handleRequest(HttpServletRequest request, HttpServletResponse response, String path) throws ServletException {
    try {
      /* build the request resource */
      T resource = buildResource(request, path);

      switch (getMethod(request)) {
        case GET :
          CFJob getJob = handleGet(resource, request, response, path);
          return TaskJobHandler.handleTaskJob(request, response, getJob, statusHandler, JsonURIUnqualificationStrategy.LOCATION_ONLY);

        case PUT :
          CFJob putJob = handlePut(resource, request, response, path);
          return TaskJobHandler.handleTaskJob(request, response, putJob, statusHandler, JsonURIUnqualificationStrategy.LOCATION_ONLY);

        case POST :
          CFJob postJob = handlePost(resource, request, response, path);
          return TaskJobHandler.handleTaskJob(request, response, postJob, statusHandler, JsonURIUnqualificationStrategy.LOCATION_ONLY);

        case DELETE :
          CFJob deleteJob = handleDelete(resource, request, response, path);
          return TaskJobHandler.handleTaskJob(request, response, deleteJob, statusHandler, JsonURIUnqualificationStrategy.LOCATION_ONLY);

        default :
          /* we don't know how to handle this request */
          return false;
      }
    } catch (Exception e) {
      String msg = NLS.bind("Failed to handle request for {0}", path); //$NON-NLS-1$
      ServerStatus status = new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, msg, e);
      logger.error(msg, e);
      return statusHandler.handleRequest(request, response, status);
    }
  }
}
TOP

Related Classes of org.eclipse.orion.server.cf.servlets.AbstractRESTHandler

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.