Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVDelegatingEcoreEList.java')
-rw-r--r--hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVDelegatingEcoreEList.java388
1 files changed, 388 insertions, 0 deletions
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVDelegatingEcoreEList.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVDelegatingEcoreEList.java
new file mode 100644
index 000000000..9772195c9
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/eav/EAVDelegatingEcoreEList.java
@@ -0,0 +1,388 @@
+/**
+ * Copyright (c) 2009 Martin Taal and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Martin Taal - initial api
+ */
+package org.eclipse.emf.teneo.hibernate.mapping.eav;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.ecore.util.DelegatingEcoreEList;
+import org.eclipse.emf.teneo.hibernate.LazyCollectionUtils;
+import org.eclipse.emf.teneo.mapping.elist.PersistableDelegateList;
+import org.hibernate.collection.AbstractPersistentCollection;
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.collection.PersistentList;
+import org.hibernate.engine.SessionImplementor;
+
+/**
+ * The list used in instances mapped using the EAV schema. The persistentList is
+ * the Hibernate list present as the referenceValues in the
+ * EAVMulti*ContainmentEReferenceValueHolder.
+ */
+public class EAVDelegatingEcoreEList<E> extends DelegatingEcoreEList<E>
+ implements EAVDelegatingList, PersistableDelegateList<E> {
+
+ private static final long serialVersionUID = 1L;
+ private EStructuralFeature eStructuralFeature;
+ private List<E> delegate;
+ private List<EAVValueHolder> persistentList;
+ private EAVMultiValueHolder valueHolderOwner;
+
+ public EAVDelegatingEcoreEList(InternalEObject owner) {
+ super(owner);
+ }
+
+ protected void initialize() {
+ if (isDelegateInitialized()) {
+ return;
+ }
+ doInitialize();
+ }
+
+ public boolean isDelegateInitialized() {
+ return delegate != null;
+ }
+
+ protected void doInitialize() {
+ delegate = new ArrayList<E>();
+ int index = 0;
+ for (Object eavValueObj : persistentList) {
+ final EAVValueHolder eavValueHolder = (EAVValueHolder) eavValueObj;
+ eavValueHolder.setListIndex(index++);
+ eavValueHolder.setValueOwner(getValueHolderOwner());
+ delegate.add(getConvertedValue(eavValueObj));
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ protected E getConvertedValue(Object value) {
+ return (E) ((EAVValueHolder) value).getValue();
+ }
+
+ @Override
+ protected List<E> delegateList() {
+ initialize();
+ return delegate;
+ }
+
+ public List<?> getDelegate() {
+ return persistentList;
+ }
+
+ public void setDelegate(List<E> delegate) {
+ this.delegate = delegate;
+ }
+
+ public EStructuralFeature getEStructuralFeature() {
+ return eStructuralFeature;
+ }
+
+ public void setEStructuralFeature(EStructuralFeature eStructuralFeature) {
+ this.eStructuralFeature = eStructuralFeature;
+ }
+
+ public List<EAVValueHolder> getPersistentList() {
+ return persistentList;
+ }
+
+ @SuppressWarnings("unchecked")
+ public void setPersistentList(List<?> persistentList) {
+ this.persistentList = (List<EAVValueHolder>) persistentList;
+ if (isHibernateListPresent()
+ && getHibernatePersistentList().wasInitialized()) {
+ doInitialize();
+ } else if (persistentList instanceof ArrayList<?>) {
+ // newly persisted
+ doInitialize();
+ }
+ }
+
+ public boolean isInitialized() {
+ return isDelegateInitialized();
+ }
+
+ public boolean isLoaded() {
+ return isDelegateInitialized();
+ }
+
+ @Override
+ /**
+ * Will always return false, means that the unique check is not performed
+ * for the eav list. This is a small price to pay for increased performance.
+ */
+ public boolean isUnique() {
+ return false;
+ }
+
+ private boolean isHibernateListPresent() {
+ return (persistentList instanceof AbstractPersistentCollection);
+ }
+
+ private PersistentList getHibernatePersistentList() {
+ return (PersistentList) persistentList;
+ }
+
+ protected final boolean isConnectedToSession() {
+ if (!(getDelegate() instanceof AbstractPersistentCollection)) {
+ return false;
+ }
+ final AbstractPersistentCollection persistentCollection = (AbstractPersistentCollection) getDelegate();
+ final SessionImplementor session = ((AbstractPersistentCollection) persistentCollection)
+ .getSession();
+ return isConnectedToSession(session);
+ }
+
+ private final boolean isConnectedToSession(SessionImplementor session) {
+ final PersistentCollection persistentCollection = (PersistentCollection) getDelegate();
+ return session != null
+ && session.isOpen()
+ && session.getPersistenceContext().containsCollection(
+ persistentCollection);
+ }
+
+ @Override
+ protected void delegateAdd(E object) {
+ final EAVValueHolder valueHolder = (EAVValueHolder) getValueHolderOwner()
+ .getElement(object);
+ valueHolder.setListIndex(getHibernatePersistentList().size());
+ persistentList.add(valueHolder);
+
+ if (isDelegateInitialized()) {
+ super.delegateAdd(object);
+ }
+ }
+
+ @Override
+ protected void delegateAdd(int index, E object) {
+ if (index == size() && !isDelegateInitialized()) {
+ delegateAdd(object);
+ // stop here as the delegate is not yet set
+ return;
+ }
+
+ // insert in the middle, load the whole list
+ delegateList();
+
+ final EAVValueHolder valueHolder = (EAVValueHolder) getValueHolderOwner()
+ .getElement(object);
+
+ persistentList.add(index, valueHolder);
+
+ int newIndex = index;
+ // note, can not use the size() call, must do persistentList.size()
+ for (EAVValueHolder element : persistentList.subList(index,
+ persistentList.size())) {
+ element.setListIndex(newIndex++);
+ }
+
+ super.delegateAdd(index, object);
+ }
+
+ @Override
+ protected List<E> delegateBasicList() {
+ return super.delegateBasicList();
+ }
+
+ @Override
+ protected void delegateClear() {
+ for (EAVValueHolder valueHolder : persistentList) {
+ valueHolder.setOwner(null);
+ valueHolder.setValueOwner(null);
+ }
+
+ super.delegateClear();
+ }
+
+ @Override
+ protected boolean delegateContains(Object object) {
+ // TODO: consider building a query to support lazy contains
+ return super.delegateContains(object);
+ }
+
+ @Override
+ protected boolean delegateContainsAll(Collection<?> collection) {
+ // will read the persistent list anyway
+ return super.delegateContainsAll(collection);
+ }
+
+ @Override
+ protected boolean delegateEquals(Object object) {
+ // will read the persistent list anyway
+ return super.delegateEquals(object);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ protected E delegateGet(int index) {
+ final EAVValueHolder valueHolder = persistentList.get(index);
+ return (E) valueHolder.getValue();
+ }
+
+ @Override
+ protected int delegateHashCode() {
+ // hashcode will read the persistentlist always anyway
+ return super.delegateHashCode();
+ }
+
+ @Override
+ protected int delegateIndexOf(Object object) {
+ // indexof will read the persistentlist always anyway
+ return super.delegateIndexOf(object);
+ }
+
+ @Override
+ protected boolean delegateIsEmpty() {
+ return delegateSize() == 0;
+ }
+
+ @Override
+ public Iterator<E> delegateIterator() {
+ return iterator();
+ }
+
+ @Override
+ public Iterator<E> iterator() {
+ if (!isDelegateInitialized() && isHibernateListPresent()
+ && isConnectedToSession()) {
+ boolean extraLazyLoaded = getValueHolderOwner() instanceof EAVExtraMultiContainmentEReferenceValueHolder;
+ extraLazyLoaded |= getValueHolderOwner() instanceof EAVExtraMultiNonContainmentEReferenceValueHolder;
+ extraLazyLoaded |= getValueHolderOwner() instanceof EAVExtraMultiEAttributeValueHolder;
+ if (extraLazyLoaded) {
+ // return a paging iterator
+ return LazyCollectionUtils.getPagedLoadingIterator(this,
+ LazyCollectionUtils.DEFAULT_PAGE_SIZE);
+ }
+ }
+ return super.iterator();
+ }
+
+ @Override
+ protected int delegateLastIndexOf(Object object) {
+ // will read the persistentlist always anyway
+ return super.delegateLastIndexOf(object);
+ }
+
+ @Override
+ protected ListIterator<E> delegateListIterator() {
+ // will read the persistentlist always anyway
+ return super.delegateListIterator();
+ }
+
+ @Override
+ protected E delegateMove(int targetIndex, int sourceIndex) {
+ final EAVValueHolder result = persistentList.remove(sourceIndex);
+
+ int newIndex = sourceIndex;
+ for (EAVValueHolder element : persistentList.subList(sourceIndex,
+ size())) {
+ element.setListIndex(newIndex++);
+ }
+
+ persistentList.add(targetIndex, result);
+
+ newIndex = targetIndex;
+ for (EAVValueHolder element : persistentList.subList(sourceIndex,
+ size())) {
+ element.setListIndex(newIndex++);
+ }
+ return super.delegateMove(targetIndex, sourceIndex);
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ protected E delegateRemove(int index) {
+ final boolean reallyLazy = index == (size() - 1)
+ && !isDelegateInitialized();
+ if (!reallyLazy) {
+ // force a load before removing
+ delegateList();
+ }
+ final EAVValueHolder result = persistentList.remove(index);
+ result.setOwner(null);
+ result.setValueOwner(null);
+
+ if (reallyLazy) {
+ // no need to update other things
+ return (E) result.getValue();
+ }
+
+ int newIndex = index;
+ // must use persistentList.size() as the delegate size has not yet been
+ // updated!
+ for (EAVValueHolder element : persistentList.subList(index,
+ persistentList.size())) {
+ element.setListIndex(newIndex++);
+ }
+ return super.delegateRemove(index);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ protected E delegateSet(int index, E object) {
+ final EAVValueHolder newValueHolder = (EAVValueHolder) getValueHolderOwner()
+ .getElement(object);
+ newValueHolder.setListIndex(index);
+ final EAVValueHolder oldValueHolder = persistentList.set(index,
+ newValueHolder);
+
+ // clear old object
+ if (oldValueHolder != null) {
+ oldValueHolder.setOwner(null);
+ oldValueHolder.setValueOwner(null);
+ }
+ if (isDelegateInitialized()) {
+ return super.delegateSet(index, object);
+ }
+ if (oldValueHolder != null) {
+ return (E) oldValueHolder.getValue();
+ }
+ return null;
+ }
+
+ @Override
+ protected int delegateSize() {
+ if (!isDelegateInitialized()) {
+ return persistentList.size();
+ }
+ return delegate.size();
+ }
+
+ @Override
+ protected Object[] delegateToArray() {
+ // will load list anyway
+ return super.delegateToArray();
+ }
+
+ @Override
+ protected <T> T[] delegateToArray(T[] array) {
+ // will load list anyway
+ return super.delegateToArray(array);
+ }
+
+ @Override
+ protected String delegateToString() {
+ // will load list anyway
+ return super.delegateToString();
+ }
+
+ public void setValueHolderOwner(EAVMultiValueHolder valueHolderOwner) {
+ this.valueHolderOwner = valueHolderOwner;
+ }
+
+ private EAVMultiValueHolder getValueHolderOwner() {
+ return valueHolderOwner;
+ }
+
+}

Back to the top