/**
   * Creates a Jackson object mapper based on a media type. It supports JSON, JSON Smile, XML, YAML
   * and CSV.
   *
   * @return The Jackson object mapper.
   */
  protected ObjectMapper createObjectMapper() {
    ObjectMapper result = null;

    if (MediaType.APPLICATION_JSON.isCompatible(getMediaType())) {
      JsonFactory jsonFactory = new JsonFactory();
      jsonFactory.configure(Feature.AUTO_CLOSE_TARGET, false);
      result = new ObjectMapper(jsonFactory);
    } else if (MediaType.APPLICATION_JSON_SMILE.isCompatible(getMediaType())) {
      SmileFactory smileFactory = new SmileFactory();
      smileFactory.configure(Feature.AUTO_CLOSE_TARGET, false);
      result = new ObjectMapper(smileFactory);
    } else if (MediaType.APPLICATION_XML.isCompatible(getMediaType())
        || MediaType.TEXT_XML.isCompatible(getMediaType())) {
      XmlFactory xmlFactory = new XmlFactory();
      xmlFactory.configure(Feature.AUTO_CLOSE_TARGET, false);
      result = new XmlMapper(xmlFactory);
    } else if (MediaType.APPLICATION_YAML.isCompatible(getMediaType())) {
      YAMLFactory yamlFactory = new YAMLFactory();
      yamlFactory.configure(Feature.AUTO_CLOSE_TARGET, false);
      result = new ObjectMapper(yamlFactory);
    } else if (MediaType.TEXT_CSV.isCompatible(getMediaType())) {
      CsvFactory csvFactory = new CsvFactory();
      csvFactory.configure(Feature.AUTO_CLOSE_TARGET, false);
      result = new CsvMapper(csvFactory);
    } else {
      JsonFactory jsonFactory = new JsonFactory();
      jsonFactory.configure(Feature.AUTO_CLOSE_TARGET, false);
      result = new ObjectMapper(jsonFactory);
    }

    return result;
  }
  /**
   * Update / Validate existing OpenSearch
   *
   * @param representation OpenSearch configuration
   * @param variant client preferred media type
   * @return Representation
   */
  @Post
  public Representation newOpensearch(Representation representation, Variant variant) {
    if (representation == null) {
      throw new ResourceException(
          Status.CLIENT_ERROR_BAD_REQUEST, "OPENSEARCH_REPRESENTATION_REQUIRED");
    }
    try {
      Opensearch osearchInput = null;
      if (MediaType.APPLICATION_XML.isCompatible(representation.getMediaType())) {
        // Parse the XML representation to get the bean
        osearchInput = new XstreamRepresentation<Opensearch>(representation).getObject();

      } else if (MediaType.APPLICATION_JSON.isCompatible(representation.getMediaType())) {
        // Parse the JSON representation to get the bean
        osearchInput =
            new JacksonRepresentation<Opensearch>(representation, Opensearch.class).getObject();
      }

      // Business service
      osearchInput.setStatus("INACTIVE");
      Opensearch osearchOutput = getStore().create(osearchInput);

      // Response
      Response response = new Response(true, osearchOutput, Opensearch.class, "opensearch");
      return getRepresentation(response, variant);

    } catch (ResourceException e) {
      getLogger().log(Level.INFO, null, e);
      throw e;
    } catch (Exception e) {
      getLogger().log(Level.SEVERE, null, e);
      throw new ResourceException(Status.SERVER_ERROR_INTERNAL, e);
    }
  }
  protected Representation formatJSON(JSON json, Variant variant) {
    Representation r = null;
    // TODO: Firefox 2 seems to not send the specified application/json header
    //       (especially after a redirect)
    //       so we will send application/json always for now
    //       (as we don't support this API any other way right now)
    if (true /* TODO:  This is a hack */) {
      r = new StringRepresentation(json.toString(), MediaType.APPLICATION_JSON);
    } else if (MediaType.APPLICATION_JSON.equals(variant.getMediaType())
        || MediaType.APPLICATION_JAVASCRIPT.equals(variant.getMediaType())
        || MediaType.TEXT_JAVASCRIPT.equals(variant.getMediaType())) {
      r = new StringRepresentation(json.toString(), variant.getMediaType());
      // TODO: make this output streaming! (this library does not support it, which is fairly
      // crazy!)
    } else if (MediaType.APPLICATION_XML.equals(variant.getMediaType())
        || MediaType.TEXT_XML.equals(variant.getMediaType())) {
      r = new StringRepresentation(new XMLSerializer().write(json), variant.getMediaType());
    } else if (MediaType.TEXT_PLAIN.equals(variant.getMediaType())
        || MediaType.TEXT_HTML.equals(variant.getMediaType())) {
      r = new StringRepresentation(json.toString(4), variant.getMediaType());
    } else {
      getResponse().setStatus(Status.CLIENT_ERROR_UNSUPPORTED_MEDIA_TYPE);
    }

    r.setCharacterSet(CharacterSet.UTF_8);
    return r;
  }
  protected XStreamRepresentation createRepresentation(Variant variant) throws ResourceException {
    XStreamRepresentation representation = null;

    try {
      // check is this variant a supported one, to avoid calling getText() on potentially huge
      // representations
      if (MediaType.APPLICATION_JSON.equals(variant.getMediaType(), true)
          || MediaType.APPLICATION_XML.equals(variant.getMediaType(), true)
          || MediaType.TEXT_HTML.equals(variant.getMediaType(), true)) {
        String text =
            (variant instanceof Representation) ? ((Representation) variant).getText() : "";

        XStream xstream;
        if (MediaType.APPLICATION_JSON.equals(variant.getMediaType(), true)
            || MediaType.TEXT_HTML.equals(variant.getMediaType(), true)) {
          xstream =
              (XStream)
                  getContext().getAttributes().get(PlexusRestletApplicationBridge.JSON_XSTREAM);
        } else if (MediaType.APPLICATION_XML.equals(variant.getMediaType(), true)) {
          xstream =
              (XStream)
                  getContext().getAttributes().get(PlexusRestletApplicationBridge.XML_XSTREAM);
        } else {
          return null;
        }

        if (text != null) {
          CharacterSet charset = variant.getCharacterSet();
          if (charset == null) {
            charset = CharacterSet.ISO_8859_1;
          }
          if (!CharacterSet.UTF_8.equals(charset)) {
            // must fix text encoding NXCM-2494
            text = new String(new String(text.getBytes(), "UTF-8").getBytes(charset.getName()));
          }
        }

        representation = new XStreamRepresentation(xstream, text, variant.getMediaType());
        return representation;
      } else {
        return null;
      }
    } catch (IOException e) {
      throw new ResourceException(
          Status.SERVER_ERROR_INTERNAL, "Cannot get the representation!", e);
    }
  }
  public boolean write(final Object result, final Response response) throws ResourceException {
    MediaType type = getVariant(response.getRequest(), ENGLISH, supportedMediaTypes).getMediaType();
    if (MediaType.APPLICATION_JSON.equals(type)) {
      if (result instanceof String || result instanceof Number || result instanceof Boolean) {
        StringRepresentation representation =
            new StringRepresentation(result.toString(), MediaType.APPLICATION_JSON);

        response.setEntity(representation);

        return true;
      }
    }

    return false;
  }
  @Override
  public void handlePOST(CoapExchange exchange) {

    Response response = new Response(CoAP.ResponseCode.CONTENT);

    int contentType = exchange.getRequestOptions().getContentFormat();
    int acceptTypeVal = exchange.getRequestOptions().getAccept();
    String acceptType = "";
    switch (acceptTypeVal) {
      case MediaTypeRegistry.APPLICATION_EXI:
        break;
      case MediaTypeRegistry.APPLICATION_XML:
        acceptType = MediaType.APPLICATION_XML.getSubType();
        break;
      case MediaTypeRegistry.APPLICATION_JSON:
        acceptType = MediaType.APPLICATION_JSON.getSubType();
        break;
    }

    Resource02_Discovery rd = new Resource02_Discovery();
    byte[] message = exchange.getRequestPayload();
    InputStream isMsg = new ByteArrayInputStream(message);
    StringRepresentation sr = new StringRepresentation("");

    try {
      switch (contentType) {
        case MediaTypeRegistry.APPLICATION_EXI:
          //              decode first! TODO
          //                 sr = rc.registerXmlHandler(isMsg, acceptType);
          //                 byte[] exiMessage = codeSchemaLess(message);
          //                 response.setPayload(exiMessage);
          break;
        case MediaTypeRegistry.APPLICATION_JSON:
          sr = rd.discoveryJsonHandler(isMsg, acceptType);
          response.setPayload(sr.getText());
          break;
        default:
          response.setPayload(
              "accept types supported: application/exi; application/xml; application/json");
      }

    } catch (ResourceException ex) {
      Logger.getLogger(CoapR02_Discovery.class.getName()).log(Level.SEVERE, null, ex);
    }

    exchange.respond(response);
  }