package com.qubling.sidekick.search;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import com.qubling.sidekick.fetch.UpdateFetcher;
import com.qubling.sidekick.instance.Instance;
public class ResultsForUpdate<SomeInstance extends Instance<SomeInstance>>
implements ResultSet<SomeInstance>, ResultSet.OnChangeListener<SomeInstance> {
private UpdateFetcher<SomeInstance> filter;
private ArrayList<SomeInstance> filteredIndex;
private ResultSet<SomeInstance> unfilteredResultSet;
public ResultsForUpdate(UpdateFetcher<SomeInstance> filter, ResultSet<SomeInstance> results) {
this.filter = filter;
this.filteredIndex = new ArrayList<SomeInstance>();
this.unfilteredResultSet = results;
for (SomeInstance instance : unfilteredResultSet) {
if (this.filter.needsUpdate(instance)) {
filteredIndex.add(instance);
}
}
unfilteredResultSet.addOnChangeListener(this);
}
public UpdateFetcher<SomeInstance> getFilter() {
return filter;
}
public ResultSet<SomeInstance> getUnfilteredResultSet() {
return unfilteredResultSet;
}
@Override
public boolean add(SomeInstance instance) throws UnsupportedOperationException {
throw new UnsupportedOperationException("Do not modify ResultsForUpdate");
}
@Override
public boolean addAll(Collection<? extends SomeInstance> instances) {
throw new UnsupportedOperationException("Do not modify ResultsForUpdate");
}
@Override
public void clear() {
throw new UnsupportedOperationException("Do not modify ResultsForUpdate");
}
@Override
public boolean retainAll(Collection<?> collection) {
throw new UnsupportedOperationException("Do not modify ResultsForUpdate");
}
@Override
public boolean removeAll(Collection<?> collection) {
throw new UnsupportedOperationException("Do not modify ResultsForUpdate");
}
@Override
public boolean remove(Object o) {
throw new UnsupportedOperationException("Do not modify ResultsForUpdate");
}
public SomeInstance get(String key) {
SomeInstance instance = unfilteredResultSet.get(key);
if (instance != null && filteredIndex.contains(instance)) {
return instance;
}
return null;
}
public SomeInstance get(int index) {
return filteredIndex.get(index);
}
@Override
public boolean contains(Object o) {
return filteredIndex.contains(o);
}
@Override
public boolean containsAll(Collection<?> collection) {
return filteredIndex.containsAll(collection);
}
@Override
public int size() {
return filteredIndex.size();
}
@Override
public int getTotalSize() {
return unfilteredResultSet.getTotalSize();
}
@Override
public void setTotalSize(int totalSize) {
throw new UnsupportedOperationException("Do not modify ResultsForUpdate");
}
@Override
public boolean isEmpty() {
return filteredIndex.isEmpty();
}
@Override
public Object[] toArray() {
return filteredIndex.toArray();
}
@Override
public <OtherInstance> OtherInstance[] toArray(OtherInstance[] array) {
return filteredIndex.toArray(array);
}
@Override
public Iterator<SomeInstance> iterator() {
return filteredIndex.iterator();
}
public ArrayList<SomeInstance> toArrayList() {
ArrayList<SomeInstance> arrayList = new ArrayList<SomeInstance>(filteredIndex.size());
arrayList.addAll(filteredIndex);
return arrayList;
}
@Override
public <OtherInstance extends Instance<OtherInstance>> void addRemap(ResultSet<OtherInstance> others, ResultSet.Remap<OtherInstance, SomeInstance> map) {
unfilteredResultSet.addRemap(others, map);
for (OtherInstance otherInstance : others) {
for (SomeInstance instance : map.map(otherInstance)) {
if (filter.needsUpdate(instance)) {
filteredIndex.add(instance);
}
}
}
}
@Override
public void addOnChangeListener(OnChangeListener<SomeInstance> listener) {
unfilteredResultSet.addOnChangeListener(listener);
}
@Override
public void removeOnChangeListener(OnChangeListener<SomeInstance> listener) {
unfilteredResultSet.removeOnChangeListener(listener);
}
@Override
public void onAdd(SomeInstance instance) {
if (filter.needsUpdate(instance))
filteredIndex.add(instance);
}
@Override
public void onRemove(SomeInstance instance) {
filteredIndex.remove(instance);
}
@Override
public void sort(Comparator<SomeInstance> comparator) {
Collections.sort(filteredIndex, comparator);
unfilteredResultSet.sort(comparator);
}
@Override
public int indexOf(SomeInstance needle) {
int i = 0;
for (SomeInstance instance : this) {
if (instance.getKey().equals(needle.getKey()))
return i;
i++;
}
return -1;
}
@Override
public String toString() {
StringBuilder result = new StringBuilder("ResultsForUpdate(");
result.append(filter.getClass().getSimpleName());
result.append(";");
for (int i = 0; i < size() && i < 3; i++) {
result.append(get(i));
result.append(",");
}
if (size() > 3)
result.append("...");
result.append(")");
return result.toString();
}
}