Java tutorial
/* * Copyright 2007-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package ae; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.ListIterator; import com.google.appengine.api.datastore.Entity; import com.google.common.base.Function; import com.google.common.collect.Iterators; import com.google.common.collect.ObjectArrays; public class MappedList<E> implements List<E> { protected final List<Entity> entities; protected final Function<Entity, E> mapper; protected final Function<E, Entity> unmapper; protected final Class<E> type; public MappedList(final Class<E> type, final List<Entity> entities, final Function<Entity, E> mapper, final Function<E, Entity> unmapper) { this.entities = entities; this.mapper = mapper; this.unmapper = unmapper; this.type = type; } @Override public int size() { return this.entities.size(); } @Override public boolean isEmpty() { return this.entities.isEmpty(); } @Override public boolean contains(final Object o) { if (this.type.isInstance(o)) { return this.entities.contains(this.unmapper.apply(this.type.cast(o))); } else { return this.entities.contains(o); } } @Override public Iterator<E> iterator() { return Iterators.transform(this.entities.iterator(), this.mapper); } @Override public Object[] toArray() { return toArray(ObjectArrays.newArray(this.type, size())); } @SuppressWarnings("unchecked") @Override public <T> T[] toArray(final T[] a) { final Object[] array; if (a.length < size()) { array = ObjectArrays.newArray(a.getClass(), size()); } else { array = a; } for (int i = 0; i < array.length; i++) { array[i] = this.mapper.apply(this.entities.get(i)); } if (array.length >= size()) { array[size()] = null; } return (T[]) array; } @Override public boolean add(final E e) { return this.entities.add(this.unmapper.apply(e)); } @Override public boolean remove(final Object o) { if (this.type.isInstance(o)) { return this.entities.remove(this.unmapper.apply(this.type.cast(o))); } else { return this.entities.remove(o); } } @Override public boolean containsAll(final Collection<?> c) { for (final Object o : c) { if (!contains(o)) { return false; } } return true; } @Override public boolean addAll(final Collection<? extends E> c) { if (c == null || c.isEmpty()) { return false; } for (final E e : c) { add(e); } return true; } @Override public boolean addAll(final int index, final Collection<? extends E> c) { if (c == null || c.isEmpty()) { return false; } int i = index; for (final E e : c) { add(i++, e); } return true; } @Override public boolean removeAll(final Collection<?> c) { if (c == null || c.isEmpty()) { return false; } boolean changed = false; for (final Object o : c) { changed |= remove(o); } return changed; } @Override public boolean retainAll(final Collection<?> c) { if (c == null || c.isEmpty()) { final boolean result = !this.entities.isEmpty(); this.entities.clear(); return result; } else { final ArrayList<Object> l = new ArrayList<Object>(c.size()); for (final Object o : c) { if (this.type.isInstance(o)) { l.add(this.unmapper.apply(this.type.cast(o))); } else { l.add(o); } } return this.entities.retainAll(l); } } @Override public void clear() { this.entities.clear(); } @Override public E get(final int index) { final Entity e = this.entities.get(index); return e == null ? null : this.mapper.apply(e); } @Override public E set(final int index, final E element) { final Entity e = this.entities.set(index, element == null ? null : this.unmapper.apply(element)); return e == null ? null : this.mapper.apply(e); } @Override public void add(final int index, final E element) { this.entities.add(index, element == null ? null : this.unmapper.apply(element)); } @Override public E remove(final int index) { final Entity e = this.entities.remove(index); return e == null ? null : this.mapper.apply(e); } @Override public int indexOf(final Object o) { if (this.type.isInstance(o)) { return this.entities.indexOf(this.unmapper.apply(this.type.cast(o))); } else { return this.entities.indexOf(o); } } @Override public int lastIndexOf(final Object o) { if (this.type.isInstance(o)) { return this.entities.lastIndexOf(this.unmapper.apply(this.type.cast(o))); } else { return this.entities.lastIndexOf(o); } } @Override public ListIterator<E> listIterator() { return new MappedListIterator<E>(this.entities.listIterator(), this.mapper, this.unmapper); } @Override public ListIterator<E> listIterator(final int index) { return new MappedListIterator<E>(this.entities.listIterator(index), this.mapper, this.unmapper); } @Override public List<E> subList(final int fromIndex, final int toIndex) { return new MappedList<E>(this.type, this.entities.subList(fromIndex, toIndex), this.mapper, this.unmapper); } }