All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.fasterxml.jackson.module.scala.ScalaObjectMapper.scala Maven / Gradle / Ivy

The newest version!
package com.fasterxml.jackson.module.scala

import com.fasterxml.jackson.core.{JsonParser, TreeNode}
import com.fasterxml.jackson.databind._
import com.fasterxml.jackson.databind.json.JsonMapper
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper
import com.fasterxml.jackson.databind.jsonschema.JsonSchema

import java.io.{File, InputStream, Reader}
import java.net.URL

object ScalaObjectMapper {
  def ::(o: JsonMapper): JsonMapper with ScalaObjectMapper = new Mixin(o)
  def ::(o: ObjectMapper): ObjectMapper with ScalaObjectMapper = new ObjectMapperMixin(o)

  final class Mixin private[ScalaObjectMapper](mapper: JsonMapper)
    extends JsonMapper(mapper) with ScalaObjectMapper

  final class ObjectMapperMixin private[ScalaObjectMapper](mapper: ObjectMapper)
    extends ObjectMapper(mapper) with ScalaObjectMapper
}

@deprecated("ScalaObjectMapper is deprecated because Manifests are not supported in Scala3, you might want to use ClassTagExtensions as a replacement", "2.12.1")
trait ScalaObjectMapper {
  self: ObjectMapper =>

  /*
   **********************************************************
   * Configuration: mix-in annotations
   **********************************************************
   */

  /**
   * Method to use for adding mix-in annotations to use for augmenting
   * specified class or interface. All annotations from
   * mixinSource are taken to override annotations
   * that target (or its supertypes) has.
   *
   * @tparam Target Class (or interface) whose annotations to effectively override
   * @tparam MixinSource Class (or interface) whose annotations are to
   *                     be "added" to target's annotations, overriding as necessary
   */
  @deprecated("this support in jackson-databind is moving to the MapperBuilder", "2.12.2")
  final def addMixin[Target: Manifest, MixinSource: Manifest]() = {
    addMixIn(manifest[Target].runtimeClass, manifest[MixinSource].runtimeClass)
  }

  /**
   * @deprecated Since 2.5: replaced by a fluent form of the method; [[addMixIn(Class, Class)]].
   */
  @deprecated("use addMixIn", "2.5")
  final def addMixInAnnotations[Target: Manifest, MixinSource: Manifest]() = {
    addMixIn(manifest[Target].runtimeClass, manifest[MixinSource].runtimeClass)
  }

  @deprecated("this support in jackson-databind is moving to the MapperBuilder", "2.12.2")
  final def findMixInClassFor[T: Manifest]: Class[_] = {
    findMixInClassFor(manifest[T].runtimeClass)
  }

  /*
   **********************************************************
   * Configuration, basic type handling
   **********************************************************
   */

  /**
   * Convenience method for constructing [[com.fasterxml.jackson.databind.JavaType]] out of given
   * type (typically java.lang.Class), but without explicit
   * context.
   */
  def constructType[T](implicit m: Manifest[T]): JavaType = {
    val clazz = m.runtimeClass
    if (isArray(clazz)) {
      val typeArguments = m.typeArguments.map(constructType(_)).toArray
      if (typeArguments.length != 1) {
        throw new IllegalArgumentException("Need exactly 1 type parameter for array like types ("+clazz.getName+")")
      }
      getTypeFactory.constructArrayType(typeArguments(0))
    } else if (isMapLike(clazz)) {
      val typeArguments = m.typeArguments.map(constructType(_)).toArray
      if (typeArguments.length != 2) {
        throw new IllegalArgumentException("Need exactly 2 type parameters for map like types ("+clazz.getName+")")
      }
      getTypeFactory.constructMapLikeType(clazz, typeArguments(0), typeArguments(1))
    } else if (isReference(clazz)) { // Option is a subclass of IterableOnce, so check it first
      val typeArguments = m.typeArguments.map(constructType(_)).toArray
      if (typeArguments.length != 1) {
        throw new IllegalArgumentException("Need exactly 1 type parameter for reference types ("+clazz.getName+")")
      }
      getTypeFactory.constructReferenceType(clazz, typeArguments(0))
    } else if (isCollectionLike(clazz)) {
      val typeArguments = m.typeArguments.map(constructType(_)).toArray
      if (typeArguments.length != 1) {
        throw new IllegalArgumentException("Need exactly 1 type parameter for collection like types ("+clazz.getName+")")
      }
      getTypeFactory.constructCollectionLikeType(clazz, typeArguments(0))
    } else {
      val typeArguments = m.typeArguments.map(constructType(_)).toArray
      getTypeFactory.constructParametricType(clazz, typeArguments: _*)
    }
  }

  /*
   **********************************************************
   * Public API (from ObjectCodec): deserialization
   * (mapping from JSON to Java types);
   * main methods
   **********************************************************
   */

  /**
   * Method to deserialize JSON content into a Java type, reference
   * to which is passed as argument. Type is passed using so-called
   * "super type token" (see )
   * and specifically needs to be used if the root type is a
   * parameterized (generic) container type.
   */
  def readValue[T: Manifest](jp: JsonParser): T = {
    readValue(jp, constructType[T])
  }

  /**
   * Method for reading sequence of Objects from parser stream.
   * Sequence can be either root-level "unwrapped" sequence (without surrounding
   * JSON array), or a sequence contained in a JSON Array.
   * In either case [[com.fasterxml.jackson.core.JsonParser]] must point to the first token of
   * the first element, OR not point to any token (in which case it is advanced
   * to the next token). This means, specifically, that for wrapped sequences,
   * parser MUST NOT point to the surrounding START_ARRAY but rather
   * to the token following it.
   * 

* Note that [[com.fasterxml.jackson.databind.ObjectReader]] has more complete set of variants. */ def readValues[T: Manifest](jp: JsonParser): MappingIterator[T] = { readValues(jp, constructType[T]) } /* ********************************************************** * Public API (from ObjectCodec): Tree Model support ********************************************************** */ /** * Convenience conversion method that will bind data given JSON tree * contains into specific value (usually bean) type. *

* Equivalent to: *

   * objectMapper.convertValue(n, valueClass);
   * 
*/ def treeToValue[T: Manifest](n: TreeNode): T = { treeToValue(n, manifest[T].runtimeClass).asInstanceOf[T] } /* ********************************************************** * Extended Public API, accessors ********************************************************** */ /** * Method that can be called to check whether mapper thinks * it could serialize an instance of given Class. * Check is done * by checking whether a serializer can be found for the type. * * @return True if mapper can find a serializer for instances of * given class (potentially serializable), false otherwise (not * serializable) * @deprecated jackson-databind will not implement this in v3.0.0 */ @deprecated("jackson-databind will not implement this in v3.0.0", "2.12.1") def canSerialize[T: Manifest]: Boolean = { canSerialize(manifest[T].runtimeClass) } /** * Method that can be called to check whether mapper thinks * it could deserialize an Object of given type. * Check is done * by checking whether a deserializer can be found for the type. * * @return True if mapper can find a serializer for instances of * given class (potentially serializable), false otherwise (not * serializable) * @deprecated jackson-databind will not implement this in v3.0.0 */ @deprecated("jackson-databind will not implement this in v3.0.0", "2.12.1") def canDeserialize[T: Manifest]: Boolean = { canDeserialize(constructType[T]) } /* ********************************************************** * Extended Public API, deserialization, * convenience methods ********************************************************** */ def readValue[T: Manifest](src: File): T = { readValue(src, constructType[T]) } def readValue[T: Manifest](src: URL): T = { readValue(src, constructType[T]) } def readValue[T: Manifest](content: String): T = { readValue(content, constructType[T]) } def readValue[T: Manifest](src: Reader): T = { readValue(src, constructType[T]) } def readValue[T: Manifest](src: InputStream): T = { readValue(src, constructType[T]) } def readValue[T: Manifest](src: Array[Byte]): T = { readValue(src, constructType[T]) } def readValue[T: Manifest](src: Array[Byte], offset: Int, len: Int): T = { readValue(src, offset, len, constructType[T]) } def updateValue[T: Manifest](valueToUpdate: T, src: File): T = { objectReaderFor(valueToUpdate).readValue(src) } def updateValue[T: Manifest](valueToUpdate: T, src: URL): T = { objectReaderFor(valueToUpdate).readValue(src) } def updateValue[T: Manifest](valueToUpdate: T, content: String): T = { objectReaderFor(valueToUpdate).readValue(content) } def updateValue[T: Manifest](valueToUpdate: T, src: Reader): T = { objectReaderFor(valueToUpdate).readValue(src) } def updateValue[T: Manifest](valueToUpdate: T, src: InputStream): T = { objectReaderFor(valueToUpdate).readValue(src) } def updateValue[T: Manifest](valueToUpdate: T, src: Array[Byte]): T = { objectReaderFor(valueToUpdate).readValue(src) } def updateValue[T: Manifest](valueToUpdate: T, src: Array[Byte], offset: Int, len: Int): T = { objectReaderFor(valueToUpdate).readValue(src, offset, len) } private def objectReaderFor[T: Manifest](valueToUpdate: T): ObjectReader = { readerForUpdating(valueToUpdate).forType(constructType[T]) } /* ********************************************************** * Extended Public API: constructing ObjectWriters * for more advanced configuration ********************************************************** */ /** * Factory method for constructing [[com.fasterxml.jackson.databind.ObjectWriter]] that will * serialize objects using specified JSON View (filter). */ def writerWithView[T: Manifest]: ObjectWriter = { writerWithView(manifest[T].runtimeClass) } /** * @deprecated Since 2.5, use [[writerFor(Class)]] instead */ @deprecated(message = "Replaced with writerFor", since = "2.5") def writerWithType[T: Manifest]: ObjectWriter = { writerFor[T] } /** * Factory method for constructing [[com.fasterxml.jackson.databind.ObjectWriter]] that will * serialize objects using specified root type, instead of actual * runtime type of value. Type must be a super-type of runtime type. *

* Main reason for using this method is performance, as writer is able * to pre-fetch serializer to use before write, and if writer is used * more than once this avoids addition per-value serializer lookups. * * @since 2.5 */ def writerFor[T: Manifest]: ObjectWriter = { writerFor(constructType[T]) } /* ********************************************************** * Extended Public API: constructing ObjectReaders * for more advanced configuration ********************************************************** */ /** * Factory method for constructing [[com.fasterxml.jackson.databind.ObjectReader]] that will * read or update instances of specified type */ @deprecated(message = "Replaced with readerFor", since = "2.6") def reader[T: Manifest]: ObjectReader = { reader(constructType[T]) } /** * Factory method for constructing [[com.fasterxml.jackson.databind.ObjectReader]] that will * read or update instances of specified type */ def readerFor[T: Manifest]: ObjectReader = { readerFor(constructType[T]) } /** * Factory method for constructing [[com.fasterxml.jackson.databind.ObjectReader]] that will * deserialize objects using specified JSON View (filter). */ def readerWithView[T: Manifest]: ObjectReader = { readerWithView(manifest[T].runtimeClass) } /* ********************************************************** * Extended Public API: convenience type conversion ********************************************************** */ /** * Convenience method for doing two-step conversion from given value, into * instance of given value type. This is functionality equivalent to first * serializing given value into JSON, then binding JSON data into value * of given type, but may be executed without fully serializing into * JSON. Same converters (serializers, deserializers) will be used as for * data binding, meaning same object mapper configuration works. * * @throws java.lang.IllegalArgumentException If conversion fails due to incompatible type; * if so, root cause will contain underlying checked exception data * binding functionality threw */ def convertValue[T: Manifest](fromValue: Any): T = { convertValue(fromValue, constructType[T]) } /* ********************************************************** * Extended Public API: JSON Schema generation ********************************************************** */ /** * Generate Json-schema * instance for specified class. * * @tparam T The class to generate schema for * @return Constructed JSON schema. */ @deprecated("JsonSchema is deprecated in favor of JsonFormatVisitor", "2.2.2") def generateJsonSchema[T: Manifest]: JsonSchema = { generateJsonSchema(manifest[T].runtimeClass) } /** * Method for visiting type hierarchy for given type, using specified visitor. *

* This method can be used for things like * generating Json Schema * instance for specified type. * * @tparam T Type to generate schema for (possibly with generic signature) * * @since 2.1 */ def acceptJsonFormatVisitor[T: Manifest](visitor: JsonFormatVisitorWrapper): Unit = { acceptJsonFormatVisitor(manifest[T].runtimeClass, visitor) } private def isArray(c: Class[_]): Boolean = { c.isArray } private val MAP = classOf[collection.Map[_,_]] private def isMapLike(c: Class[_]): Boolean = { MAP.isAssignableFrom(c) } private val OPTION = classOf[Option[_]] private def isReference(c: Class[_]): Boolean = { OPTION.isAssignableFrom(c) } private val ITERABLE = classOf[collection.Iterable[_]] private def isCollectionLike(c: Class[_]): Boolean = { ITERABLE.isAssignableFrom(c) } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy