package com.qcadoo.model.internal;
import com.qcadoo.model.api.DataDefinition;
import com.qcadoo.model.api.Entity;
import com.qcadoo.model.api.FieldDefinition;
import com.qcadoo.model.api.search.JoinType;
import com.qcadoo.model.api.search.SearchCriteriaBuilder;
import com.qcadoo.model.api.search.SearchRestrictions;
import com.qcadoo.model.api.types.ManyToManyType;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.concurrent.atomic.AtomicReference;
import static com.google.common.base.Preconditions.checkNotNull;
public class ProxyList implements List<Entity> {
private final ManyToManyType manyToManyType;
private final DataDefinition referencedDataDefinition;
private final Long parentId;
private final FieldDefinition fieldDefinition;
private final Entity performer;
private AtomicReference<List<Entity>> list = new AtomicReference<List<Entity>>(null);
public ProxyList(final FieldDefinition fieldDefinition, Long parentId, final Entity performer) {
this.fieldDefinition = fieldDefinition;
this.parentId = parentId;
this.performer = performer;
this.manyToManyType = (ManyToManyType) fieldDefinition.getType();
this.referencedDataDefinition = manyToManyType.getDataDefinition();
}
private List<Entity> getList() {
if (list.get() == null) {
SearchCriteriaBuilder searchCriteriaBuilder = referencedDataDefinition.find().createAlias(manyToManyType.getJoinFieldName(), manyToManyType.getJoinFieldName(), JoinType.INNER).add(SearchRestrictions.eq(manyToManyType.getJoinFieldName()+".id", parentId));
List<Entity> entities = searchCriteriaBuilder.list().getEntities();
list.compareAndSet(null, entities);
checkNotNull(list.get(), "Proxy can't load list");
}
return list.get();
}
public int size() {
return getList().size();
}
public boolean isEmpty() {
return getList().isEmpty();
}
public boolean contains(Object o) {
return getList().contains(o);
}
public Iterator<Entity> iterator() {
return getList().iterator();
}
public Object[] toArray() {
return getList().toArray();
}
public <T> T[] toArray(T[] a) {
return getList().toArray(a);
}
public boolean add(Entity entity) {
return getList().add(entity);
}
public boolean remove(Object o) {
return getList().remove(o);
}
public boolean containsAll(Collection<?> c) {
return getList().containsAll(c);
}
public boolean addAll(Collection<? extends Entity> c) {
return getList().addAll(c);
}
public boolean addAll(int index, Collection<? extends Entity> c) {
return getList().addAll(index, c);
}
public boolean removeAll(Collection<?> c) {
return getList().removeAll(c);
}
public boolean retainAll(Collection<?> c) {
return getList().retainAll(c);
}
public void clear() {
getList().clear();
}
public Entity get(int index) {
return getList().get(index);
}
public Entity set(int index, Entity element) {
return getList().set(index, element);
}
public void add(int index, Entity element) {
getList().add(index, element);
}
public Entity remove(int index) {
return getList().remove(index);
}
public int indexOf(Object o) {
return getList().indexOf(o);
}
public int lastIndexOf(Object o) {
return getList().lastIndexOf(o);
}
public ListIterator<Entity> listIterator() {
return getList().listIterator();
}
public ListIterator<Entity> listIterator(int index) {
return getList().listIterator(index);
}
public List<Entity> subList(int fromIndex, int toIndex) {
return getList().subList(fromIndex, toIndex);
}
}