
org.beangle.data.hibernate.udt.PersistentSeq.scala Maven / Gradle / Ivy
The newest version!
/*
* Beangle, Agile Development Scaffold and Toolkit
*
* Copyright (c) 2005-2015, Beangle Software.
*
* Beangle is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Beangle 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
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Beangle. If not, see .
*/
package org.beangle.data.hibernate.udt
import java.io.{ Serializable => JSerializable }
import java.sql.ResultSet
import java.{ util => ju }
import scala.Range
import scala.collection.JavaConversions.asJavaIterator
import scala.collection.mutable.{ Buffer, ListBuffer }
import org.hibernate.`type`.Type
import org.hibernate.collection.internal.AbstractPersistentCollection
import org.hibernate.collection.internal.AbstractPersistentCollection.{ DelayedOperation, UNKNOWN }
import org.hibernate.engine.spi.SessionImplementor
import org.hibernate.loader.CollectionAliases
import org.hibernate.persister.collection.CollectionPersister
class PersistentSeq(session: SessionImplementor, var list: Buffer[Object] = null)
extends AbstractPersistentCollection(session) with collection.mutable.Buffer[Object] {
if (null != list) {
setInitialized()
setDirectlyAccessible(true)
}
override def getSnapshot(persister: CollectionPersister): JSerializable = {
val clonedList = new ListBuffer[Object]
list.foreach { ele => clonedList += persister.getElementType().deepCopy(ele, persister.getFactory) }
clonedList
}
override def getOrphans(snapshot: JSerializable, entityName: String): ju.Collection[_] = {
SeqHelper.getOrphans(snapshot.asInstanceOf[ListBuffer[_]], list, entityName, getSession())
}
override def equalsSnapshot(persister: CollectionPersister): Boolean = {
val elementType = persister.getElementType()
val sn = getSnapshot().asInstanceOf[ListBuffer[_]]
val itr = list.iterator
(sn.size == list.size) && !sn.exists { ele => elementType.isDirty(itr.next(), ele, getSession()) }
}
override def isSnapshotEmpty(snapshot: JSerializable): Boolean = (snapshot.asInstanceOf[Seq[_]]).isEmpty
override def beforeInitialize(persister: CollectionPersister, anticipatedSize: Int) {
this.list = new ListBuffer[Object]
}
override def initializeFromCache(persister: CollectionPersister, disassembled: JSerializable, owner: Object) {
val array = disassembled.asInstanceOf[Array[JSerializable]]
val size = array.length
beforeInitialize(persister, size)
array foreach { ele => list += persister.getElementType().assemble(ele, getSession(), owner) }
}
override def isWrapper(collection: Object): Boolean = {
list eq collection
}
//FIXME
override def readFrom(rs: ResultSet, persister: CollectionPersister, descriptor: CollectionAliases, owner: Object): Object = {
val element = persister.readElement(rs, owner, descriptor.getSuffixedElementAliases(), getSession())
if (null == descriptor.getSuffixedIndexAliases()) {
list += element
} else {
val index = persister.readIndex(rs, descriptor.getSuffixedIndexAliases(), getSession()).asInstanceOf[Integer].intValue()
//pad with nulls from the current last element up to the new index
Range(list.size, index) foreach { i => list.insert(i, null) }
list.insert(index, element)
}
element
}
override def entries(persister: CollectionPersister): ju.Iterator[_] = {
asJavaIterator(list.iterator)
}
override def disassemble(persister: CollectionPersister): JSerializable = {
list.map(ele => persister.getElementType().disassemble(ele, getSession(), null)).toArray.asInstanceOf[Array[JSerializable]]
}
override def getDeletes(persister: CollectionPersister, indexIsFormula: Boolean): ju.Iterator[_] = {
val deletes = new ju.ArrayList[Object]()
val sn = getSnapshot().asInstanceOf[ListBuffer[Object]]
val end =
if (sn.size > list.size) {
Range(list.size, sn.size) foreach { i => deletes.add(if (indexIsFormula) sn(i) else Integer.valueOf(i)) }
list.size
} else sn.size
Range(0, end) foreach { i =>
val snapshotItem = sn(i)
if (list(i) == null && snapshotItem != null) deletes.add(if (indexIsFormula) snapshotItem else Integer.valueOf(i))
}
deletes.iterator()
}
override def needsInserting(entry: Object, i: Int, elemType: Type): Boolean = {
val sn = getSnapshot().asInstanceOf[ListBuffer[Object]]
list(i) != null && (i >= sn.size || sn(i) == null)
}
override def needsUpdating(entry: Object, i: Int, elemType: Type): Boolean = {
val sn = getSnapshot().asInstanceOf[ListBuffer[Object]]
i < sn.size && sn(i) != null && list(i) != null && elemType.isDirty(list(i), sn(i), getSession())
}
override def getIndex(entry: Object, i: Int, persister: CollectionPersister): Object = {
Integer.valueOf(i)
}
override def getElement(entry: Object): Object = entry
override def getSnapshotElement(entry: Object, i: Int): Object = {
getSnapshot().asInstanceOf[ListBuffer[Object]](i)
}
override def entryExists(entry: Object, i: Int): Boolean = {
entry != null
}
override def length: Int = {
if (readSize()) getCachedSize() else list.size
}
override def isEmpty(): Boolean = {
if (readSize()) getCachedSize() == 0 else list.isEmpty
}
override def iterator: Iterator[Object] = {
read(); list.iterator
}
override def +=(ele: Object): this.type = {
if (!isOperationQueueEnabled()) {
write()
list += ele
} else {
queueOperation(new Add(ele));
}
this
}
override def +=:(ele: Object): this.type = {
if (!isOperationQueueEnabled()) {
write()
ele +=: list
} else {
queueOperation(new Add(ele));
}
this
}
override def clear() {
if (isClearQueueEnabled()) {
queueOperation(new Clear())
} else {
initialize(true)
if (!list.isEmpty) {
list.clear()
dirty()
}
}
}
override def remove(n: Int): Object = {
val old = if (isPutQueueEnabled()) readElementByIndex(n) else UNKNOWN
if (old == UNKNOWN) {
write()
list.remove(n)
} else {
queueOperation(new Remove(n, old))
old
}
}
override def insertAll(n: Int, elems: Traversable[Object]) {
if (!elems.isEmpty) {
write()
list.insertAll(n, elems)
}
}
override def update(n: Int, elem: Object) {
val old = if (isPutQueueEnabled()) readElementByIndex(n) else UNKNOWN
if (old == UNKNOWN) {
write()
list.update(n, elem);
} else {
queueOperation(new Set(n, elem, old));
}
}
override def apply(index: Int): Object = {
val result = readElementByIndex(index)
if (result eq UNKNOWN) list(index) else result
}
override def isCollectionEmpty: Boolean = {
list.isEmpty
}
override def toString(): String = {
read(); list.toString()
}
override def equals(other: Any): Boolean = {
read(); list.equals(other)
}
override def hashCode(): Int = {
read(); list.hashCode()
}
final class Clear extends DelayedOperation {
override def operate() { list.clear() }
override def getAddedInstance(): Object = null
override def getOrphan(): Object = throw new UnsupportedOperationException("queued clear cannot be used with orphan delete")
}
final class Add(val value: Object) extends DelayedOperation {
override def operate() { list += value }
override def getAddedInstance(): Object = value
override def getOrphan(): Object = null
}
final class Set(index: Int, value: Object, old: Object) extends DelayedOperation {
override def operate() { list.insert(index, value) }
override def getAddedInstance(): Object = value
override def getOrphan(): Object = null
}
final class Remove(index: Int, old: Object) extends DelayedOperation {
override def operate() { list.remove(index) }
override def getAddedInstance(): Object = null
override def getOrphan(): Object = old
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy