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

org.datanucleus.scala.ScalaOptionHandler.scala Maven / Gradle / Ivy

The newest version!
package org.datanucleus.scala

import org.datanucleus.ClassLoaderResolver
import org.datanucleus.metadata.AbstractMemberMetaData
import org.datanucleus.metadata.ColumnMetaData
import org.datanucleus.metadata.MetaDataManager
import org.datanucleus.store.types.containers.CollectionHandler
import org.datanucleus.enhancement.Persistable
import org.datanucleus.enhancer.EnhancementHelper
import javax.jdo.JDOHelper

class ScalaOptionHandler
    extends CollectionHandler[Option[Object]] {

  var _clr: ClassLoaderResolver = _
  var _prm: ClassLoader = _

  override def newContainer(mmd: AbstractMemberMetaData): Option[Object] = Option.empty
  override def newContainer(mmd: AbstractMemberMetaData, elements: Object*): Option[Object] = Option(elements.head)

  override def getAdapter(option: Option[Object]): OptionAdapter = new OptionAdapter(option)
  override def populateMetaData(clr: ClassLoaderResolver, primary: ClassLoader, mmgr: MetaDataManager, mmd: AbstractMemberMetaData) = {

    _prm = primary
    _clr = clr
    mmd.getCollection.setSingleElement(true)

    // Get columns defined metadata - not visible
    val columns = new AbstractMemberMetaData(mmd.getParent(), mmd) {
      def getColumns = columns;
    }.getColumns;

    if (columns == null || columns.size() == 0) {
      // Option should allow nullable by default
      val colmd = new ColumnMetaData()
      colmd.setAllowsNull(true)
      mmd.addColumn(colmd)
    }

    super.populateMetaData(clr, primary, mmgr, mmd)
  }

  /** Java reflection doesn't work in some scenarios such as using scala.Boolean
    * as a type parameter because they are boxed/unboxed by the compiler so the
    * type for Java reflection will be Object, hence we have to use Scala reflection
    * to determine the type. However Scala reflection API from scala.reflect will
    * cause the related classes to be loaded when building the reflection symbols,
    * which will cause the initialization of their metadata as well and that can
    * cause issues, specially when datanucleus.metadata.autoregistration is enabled.
    * To workaround this problem we read the type name straight from
    * the ScalaSignature using scalap API.
    */
  override protected def getElementType(mmd: AbstractMemberMetaData): String = {

    val clazz = mmd.getMemberRepresented.getDeclaringClass
    ScalaSigReader.readFieldTypeName(mmd.getName, clazz, 0)

  }

  override def isDefaultFetchGroup(clr: ClassLoaderResolver, mmgr: MetaDataManager, mmd: AbstractMemberMetaData) = {
    val elementTypeName = mmd.getCollection.getElementType
    val elementType = clr.classForName(elementTypeName);

    val typeMgr = mmgr.getNucleusContext.getTypeManager

    typeMgr.isDefaultFetchGroup(elementType)
  }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy