Package com.mockey.ui

Source Code of com.mockey.ui.JsonSchemaValidateServlet

/*
* Copyright (c) 2013, Francis Galiegue <fgaliegue@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the Lesser GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* Lesser GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

package com.mockey.ui;

import com.fasterxml.jackson.core.JsonLocation;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.github.fge.jsonschema.JsonValidators;
import com.github.fge.jsonschema.constants.ParseError;
import com.github.fge.jsonschema.constants.ValidateRequest;
import com.github.fge.jsonschema.constants.ValidateResponse;
import com.github.fge.jsonschema.main.JsonValidator;
import com.github.fge.jsonschema.report.ProcessingReport;
import com.github.fge.jsonschema.util.AsJson;
import com.github.fge.jsonschema.util.JsonLoader;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Sets;
import com.google.common.io.Closeables;
import com.google.common.net.MediaType;
import com.mockey.model.Scenario;
import com.mockey.model.Service;
import com.mockey.storage.IMockeyStorage;
import com.mockey.storage.StorageRegistry;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.Enumeration;
import java.util.Set;

/**
* Servlet responsible of validating a schema/data pair
*
* <p>
* It returns a JSON Object as a result with the appropriate media type (thanks
* Guava for providing {@link MediaType#JSON_UTF_8}!).
* </p>
*
* <p>
* This object has the following members:
* </p>
*
* <ul>
* <li>{@code invalidSchema}: boolean indicating whether the provided schema was
* valid JSON;</li>
* <li>{@code invalidData}: same, but for the data;</li>
* <li>{@code valid} (only if the schema and data are valid): whether the
* validation has succeeded;</li>
* <li>{@code results} (only if the schema and data are valid): the result of
* {@link ProcessingReport#getMessages()}.</li>
* </ul>
*/
public final class JsonSchemaValidateServlet extends HttpServlet {
  /**
   *
   */
  private static final long serialVersionUID = 2625630469996134777L;

  private static final Logger logger = LoggerFactory
      .getLogger(JsonSchemaValidateServlet.class);

  private static IMockeyStorage store = StorageRegistry.MockeyStorage;

  public void doGet(HttpServletRequest req, HttpServletResponse resp)
      throws ServletException, IOException {

    try {
      Long serviceId = new Long(req.getParameter("serviceId"));
      Long scenarioId = null;
      scenarioId = new Long(req.getParameter("scenarioId"));
      Service service = store.getServiceById(serviceId);
      Scenario scenario = service.getScenario(scenarioId);
      req.setAttribute("service", service);
      req.setAttribute("scenario", scenario);
    } catch (Exception e) {
      logger.debug("Unable to retrieve a Service of ID: "
          + req.getParameter("serviceId"));
    }

    // Get the service.
    RequestDispatcher dispatch = req
        .getRequestDispatcher("/jsonschemavalidate.jsp");
    dispatch.forward(req, resp);
  }

  @Override
  public void doPost(final HttpServletRequest req,
      final HttpServletResponse resp) throws ServletException,
      IOException {
    final Set<String> params = Sets.newHashSet();
    final Enumeration<String> enumeration = req.getParameterNames();

    // FIXME: no duplicates, it seems, but I cannot find the spec which
    // guarantees that
    while (enumeration.hasMoreElements())
      params.add(enumeration.nextElement());

    // We have required parameters
    if (!params.containsAll(ValidateRequest.REQUIRED_PARAMS)) {
      logger.warn("Missing parameters! Someone using me as a web service?");
      resp.sendError(HttpServletResponse.SC_BAD_REQUEST,
          "Missing parameters");
      return;
    }

    // We don't want extraneous parameters
    params.removeAll(ValidateRequest.VALID_PARAMS);

    if (!params.isEmpty()) {
      logger.warn("Invalid parameters! Someone using me as a web service?");
      resp.sendError(HttpServletResponse.SC_BAD_REQUEST,
          "Invalid parameters");
      return;
    }

    final String rawSchema = req.getParameter(ValidateRequest.SCHEMA);
    final String data = req.getParameter(ValidateRequest.DATA);

    // Set correct content type
    resp.setContentType(MediaType.JSON_UTF_8.toString());

    final boolean useV3 = Boolean.parseBoolean(req
        .getParameter(ValidateRequest.USE_V3));
    final boolean useId = Boolean.parseBoolean(req
        .getParameter(ValidateRequest.USE_ID));

    final JsonNode ret = JsonSchemaUtil.buildResult(rawSchema, data, useV3, useId);

    final OutputStream out = resp.getOutputStream();

    try {
      out.write(ret.toString().getBytes(Charset.forName("UTF-8")));
      out.flush();
    } finally {
      Closeables.closeQuietly(out);
    }
  }

//  /*
//   * Build the response. When we arrive here, we are guaranteed that we have
//   * the needed elements.
//   */
//  @VisibleForTesting
//  static JsonNode buildResult(final String rawSchema, final String rawData,
//      final boolean useV3, final boolean useId) throws IOException {
//    final ObjectNode ret = JsonNodeFactory.instance.objectNode();
//
//    final boolean invalidSchema = fillWithData(ret,
//        ValidateResponse.SCHEMA, ValidateResponse.INVALID_SCHEMA,
//        rawSchema);
//    final boolean invalidData = fillWithData(ret, ValidateResponse.DATA,
//        ValidateResponse.INVALID_DATA, rawData);
//
//    final JsonNode schemaNode = ret.remove(ValidateResponse.SCHEMA);
//    final JsonNode data = ret.remove(ValidateResponse.DATA);
//
//    if (invalidSchema || invalidData)
//      return ret;
//
//    final JsonValidator validator = JsonValidators
//        .withOptions(useV3, useId);
//    final ProcessingReport report = validator.validateUnchecked(schemaNode,
//        data);
//
//    final boolean success = report.isSuccess();
//    ret.put(ValidateResponse.VALID, success);
//    ret.put(ValidateResponse.RESULTS, ((AsJson) report).asJson());
//    return ret;
//  }
//
//  /*
//   * We have to use that since Java is not smart enough to detect that
//   * sometimes, a variable is initialized in all paths.
//   *
//   * This returns true if the data is invalid.
//   */
//  private static boolean fillWithData(final ObjectNode node,
//      final String onSuccess, final String onFailure, final String raw)
//      throws IOException {
//    try {
//      node.put(onSuccess, JsonLoader.fromString(raw));
//      return false;
//    } catch (JsonProcessingException e) {
//      node.put(onFailure, buildParsingError(e, raw.contains("\r\n")));
//      return true;
//    }
//  }
//
//  private static JsonNode buildParsingError(final JsonProcessingException e,
//      final boolean crlf) {
//    final JsonLocation location = e.getLocation();
//    final ObjectNode ret = JsonNodeFactory.instance.objectNode();
//
//    /*
//     * Unfortunately, for some reason, Jackson botches the column number in
//     * its JsonPosition -- I cannot figure out why exactly. However, it does
//     * have a correct offset into the buffer.
//     *
//     * The problem is that if the input has CR/LF line terminators, its
//     * offset will be "off" by the number of lines minus 1 with regards to
//     * what JavaScript sees as positions in text areas. Make the necessary
//     * adjustments so that the caret jumps at the correct position in this
//     * case.
//     */
//    final int lineNr = location.getLineNr();
//    int offset = (int) location.getCharOffset();
//    if (crlf)
//      offset = offset - lineNr + 1;
//    ret.put(ParseError.LINE, lineNr);
//    ret.put(ParseError.OFFSET, offset);
//
//    // Finally, put the message
//    ret.put(ParseError.MESSAGE, e.getOriginalMessage());
//    return ret;
//  }
}
TOP

Related Classes of com.mockey.ui.JsonSchemaValidateServlet

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.