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

io.altoo.serialization.kryo.scala.serializer.ScalaObjectSerializer.scala Maven / Gradle / Ivy

/**
 * *****************************************************************************
 * Copyright 2014 Roman Levenstein
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ****************************************************************************
 */

package io.altoo.serialization.kryo.scala.serializer

import com.esotericsoftware.kryo.kryo5.io.{Input, Output}
import com.esotericsoftware.kryo.kryo5.{Kryo, Serializer}

import _root_.java.lang.reflect.Field
import scala.collection.mutable.Map as MMap
import scala.util.control.Exception.allCatch

// Stolen with pride from Chill ;-)
class ScalaObjectSerializer[T] extends Serializer[T] {
  private val cachedObj = MMap[Class[?], Option[T]]()

  // Does nothing
  override def write(kser: Kryo, out: Output, obj: T): Unit = ()

  protected def createSingleton(cls: Class[?]): Option[T] = {
    moduleField(cls).map { _.get(null).asInstanceOf[T] }
  }

  protected def cachedRead(cls: Class[?]): Option[T] = {
    cachedObj.synchronized { cachedObj.getOrElseUpdate(cls, createSingleton(cls)) }
  }

  override def read(kser: Kryo, in: Input, cls: Class[? <: T]): T = cachedRead(cls).get

  def accepts(cls: Class[?]): Boolean = cachedRead(cls).isDefined

  protected def moduleField(klass: Class[?]): Option[Field] =
    Some(klass)
      .filter { _.getName.last == '$' }
      .flatMap { k => allCatch.opt(k.getDeclaredField("MODULE$")) }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy