blob: 0b23025d186888464ec1de3479f33c248a17584e [file] [log] [blame]
/*
* Copyright (c) 2008-2013, 2015 Eike Stepper (Berlin, Germany) 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
* Eike Stepper - maintenance
*/
package org.eclipse.emf.cdo.server.internal.hibernate.tuplizer;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOIDExternal;
import org.eclipse.emf.cdo.common.id.CDOIDUtil;
import org.eclipse.emf.cdo.common.revision.CDORevision;
import org.eclipse.emf.cdo.server.internal.hibernate.HibernateUtil;
import org.eclipse.net4j.util.collection.MoveableList;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
/**
* Wraps a moveable list so that hibernate always sees an object view while cdo always sees a cdoid view. The same for
* EEnum: cdo wants to see an int (the ordinal), hibernate the real eenum value. This to support querying with EENum
* parameters.
*
* @author Martin Taal
*/
public class HibernateMoveableListWrapper implements MoveableList<Object>
{
private List<Object> delegate;
private EStructuralFeature eFeature;
private boolean resolveCDOID;
public HibernateMoveableListWrapper()
{
}
public Object move(int targetIndex, int sourceIndex)
{
int size = size();
if (sourceIndex >= size)
{
throw new IndexOutOfBoundsException("sourceIndex=" + sourceIndex + ", size=" + size); //$NON-NLS-1$ //$NON-NLS-2$
}
if (targetIndex >= size)
{
throw new IndexOutOfBoundsException("targetIndex=" + targetIndex + ", size=" + size); //$NON-NLS-1$ //$NON-NLS-2$
}
Object object = get(sourceIndex);
if (targetIndex == sourceIndex)
{
return object;
}
if (targetIndex < sourceIndex)
{
moveUp1(targetIndex, sourceIndex - targetIndex);
}
else
{
moveDown1(targetIndex, targetIndex - sourceIndex);
}
set(targetIndex, object);
return object;
}
private void moveUp1(int index, int count)
{
for (int i = count; i > 0; i--)
{
set(index + i, get(index + i - 1));
}
}
private void moveDown1(int index, int count)
{
for (int i = count; i > 0; i--)
{
set(index - i, get(index - i + 1));
}
}
/**
* @return the delegate
*/
public List<Object> getDelegate()
{
return delegate;
}
/**
* @param delegate
* the delegate to set
*/
public void setDelegate(List<Object> delegate)
{
this.delegate = delegate;
}
protected Object getObject(Object o)
{
if (o == null)
{
return null;
}
if (o instanceof CDOID && CDOIDUtil.isNull((CDOID)o))
{
return null;
}
else if (o instanceof CDOIDExternal)
{
return o;
}
else if (resolveCDOID && o instanceof CDOID)
{
return HibernateUtil.getInstance().getCDORevision((CDOID)o);
}
return o;
}
protected List<Object> getObjects(List<?> ids)
{
List<Object> result = new ArrayList<Object>();
for (Object o : ids)
{
result.add(getObject(o));
}
return result;
}
protected Object getValue(Object o)
{
if (o instanceof CDOIDExternal)
{
return o;
}
// can happen for primitive typed lists
if (!(o instanceof CDORevision))
{
return o;
}
return HibernateUtil.getInstance().getCDOID(o);
}
protected List<Object> getValues(Collection<?> c)
{
List<Object> newC = new ArrayList<Object>();
for (Object o : c)
{
newC.add(getValue(o));
}
return newC;
}
public void add(int index, Object element)
{
getDelegate().add(index, getValue(element));
}
public boolean add(Object o)
{
return getDelegate().add(getValue(o));
}
public boolean addAll(Collection<? extends Object> c)
{
return getDelegate().addAll(getValues(c));
}
public boolean addAll(int index, Collection<? extends Object> c)
{
return getDelegate().addAll(index, getValues(c));
}
public void clear()
{
getDelegate().clear();
}
public boolean contains(Object o)
{
return getDelegate().contains(getValue(o));
}
public boolean containsAll(Collection<?> c)
{
return getDelegate().containsAll(getValues(c));
}
public Object get(int index)
{
return getObject(getDelegate().get(index));
}
public int indexOf(Object o)
{
return getDelegate().indexOf(getValue(o));
}
public boolean isEmpty()
{
return getDelegate().isEmpty();
}
public Iterator<Object> iterator()
{
return new CDOHibernateIterator(getDelegate().iterator(), resolveCDOID);
}
public int lastIndexOf(Object o)
{
return getDelegate().lastIndexOf(getValue(o));
}
public ListIterator<Object> listIterator()
{
return new CDOHibernateListIterator(getDelegate().listIterator(), resolveCDOID);
}
public ListIterator<Object> listIterator(int index)
{
return new CDOHibernateListIterator(getDelegate().listIterator(index), resolveCDOID);
}
public Object remove(int index)
{
return getDelegate().remove(index);
}
public boolean remove(Object o)
{
return getDelegate().remove(getValue(o));
}
public boolean removeAll(Collection<?> c)
{
return getDelegate().removeAll(getValues(c));
}
public boolean retainAll(Collection<?> c)
{
return getDelegate().retainAll(getValues(c));
}
public Object set(int index, Object element)
{
return getDelegate().set(index, getValue(element));
}
public int size()
{
return getDelegate().size();
}
public List<Object> subList(int fromIndex, int toIndex)
{
return getObjects(getDelegate().subList(fromIndex, toIndex));
}
public Object[] toArray()
{
Object[] result = new Object[size()];
int i = 0;
for (Object o : this)
{
result[i++] = o;
}
return result;
}
@SuppressWarnings("unchecked")
public <T> T[] toArray(T[] a)
{
int i = 0;
for (Object o : this)
{
a[i++] = (T)o;
}
return a;
}
EStructuralFeature getEFeature()
{
return eFeature;
}
void setEFeature(EStructuralFeature eFeature)
{
this.eFeature = eFeature;
resolveCDOID = !HibernateUtil.getInstance().isCDOResourceContents(eFeature) && eFeature instanceof EReference;
}
private static final class CDOHibernateIterator implements Iterator<Object>
{
private final Iterator<?> delegate;
private final boolean resolveCDOID;
public CDOHibernateIterator(Iterator<?> delegate, boolean resolveCDOID)
{
this.delegate = delegate;
this.resolveCDOID = resolveCDOID;
}
public boolean hasNext()
{
return delegate.hasNext();
}
public Object next()
{
Object o = delegate.next();
if (o instanceof CDOIDExternal)
{
return o;
}
else if (resolveCDOID && o instanceof CDOID)
{
return HibernateUtil.getInstance().getCDORevision((CDOID)o);
}
return o;
}
public void remove()
{
delegate.remove();
}
}
private static final class CDOHibernateListIterator implements ListIterator<Object>
{
private final ListIterator<Object> delegate;
private final boolean resolveCDOID;
public CDOHibernateListIterator(ListIterator<Object> delegate, boolean resolveCDOID)
{
this.delegate = delegate;
this.resolveCDOID = resolveCDOID;
}
public void add(Object o)
{
delegate.add(HibernateUtil.getInstance().getCDOID(o));
}
public boolean hasNext()
{
return delegate.hasNext();
}
public boolean hasPrevious()
{
return delegate.hasPrevious();
}
public Object next()
{
Object o = delegate.next();
if (resolveCDOID && o instanceof CDOID)
{
return HibernateUtil.getInstance().getCDORevision((CDOID)delegate.next());
}
return o;
}
public int nextIndex()
{
return delegate.nextIndex();
}
public Object previous()
{
Object o = delegate.previous();
if (o instanceof CDOID)
{
return HibernateUtil.getInstance().getCDORevision((CDOID)delegate.next());
}
return o;
}
public int previousIndex()
{
return delegate.previousIndex();
}
public void remove()
{
delegate.remove();
}
public void set(Object o)
{
delegate.set(HibernateUtil.getInstance().getCDOID(o));
}
}
}