package marubinotto.piggydb.model;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import marubinotto.util.Assert;
import marubinotto.util.CollectionUtils;
public class FragmentList<F extends Fragment> implements Iterable<F> {
private List<F> fragments;
private Map<Long, F> id2fragment;
private List<F> duplicates;
public FragmentList() {
setFragments(new ArrayList<F>());
}
public FragmentList(List<F> fragments) {
setFragments(fragments);
}
public FragmentList(F fragment) {
Assert.Arg.notNull(fragment, "fragment");
List<F> fragments = new ArrayList<F>();
fragments.add(fragment);
setFragments(fragments);
}
@SuppressWarnings("unchecked")
public static <SF extends Fragment> FragmentList<SF> createByDownCast(List<Fragment> fragments) {
Assert.Arg.notNull(fragments, "fragments");
List<SF> downCasted = new ArrayList<SF>();
for (Fragment fragment : fragments) {
downCasted.add((SF)fragment);
}
return new FragmentList<SF>(downCasted);
}
private void setFragments(List<F> fragments) {
Assert.Arg.notNull(fragments, "fragments");
this.fragments = fragments;
this.id2fragment = new HashMap<Long, F>();
this.duplicates = new ArrayList<F>();
for (F fragment : this.fragments) {
if (this.id2fragment.containsKey(fragment.getId()))
this.duplicates.add(fragment);
else
this.id2fragment.put(fragment.getId(), fragment);
}
}
public List<F> getFragments() {
return this.fragments;
}
public List<Fragment> covariantCast() {
return CollectionUtils.<Fragment>covariantCast(this.fragments);
}
public Iterator<F> iterator() {
return this.fragments.iterator();
}
public boolean isEmpty() {
return this.fragments.isEmpty();
}
public F get(Long id) {
Assert.Arg.notNull(id, "id");
return this.id2fragment.get(id);
}
public Set<Long> ids() {
return this.id2fragment.keySet();
}
public List<F> getDuplicates() {
return this.duplicates;
}
@SuppressWarnings("unchecked")
public FragmentList<F> getChildren() {
List<F> children = new ArrayList<F>();
for (F fragment : this) {
for (Fragment child : fragment.getChildren()) {
children.add((F)child);
}
}
return new FragmentList<F>(children);
}
}