package org.obo.app.swing;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import com.eekboom.utils.Strings;
public class DefaultSearcher<T> implements AutocompleteSearcher<T> {
private final Collection<T> choices;
private final Class<T> hitClass;
private final List<SearchHit<T>> matches = new ArrayList<SearchHit<T>>();
public static final MatchType TO_STRING_STARTS_WITH = new MatchType() {
@Override
public String getName() {
return "";
}
};
public static final MatchType TO_STRING_CONTAINS = new MatchType() {
@Override
public String getName() {
return "";
}
};
public static final Comparator<DefaultHit<?>> HIT_COMPARATOR = new Comparator<DefaultHit<?>>() {
@Override
public int compare(DefaultHit<?> o1, DefaultHit<?> o2) {
return Strings.compareNatural(o1.getMatchText(), o2.getMatchText());
}
};
public DefaultSearcher(Collection<T> choices, Class<T> hitClass) {
this.choices = choices;
this.hitClass = hitClass;
}
@Override
public SearchHit<T> getAsHit(T item) {
return new DefaultHit<T>(item, "", new MatchType() {
@Override
public String getName() {
return "";
}
});
}
@Override
public SearchHit<T> getExactHit(String text) {
for (T choice : this.choices) {
if (text.equals(choice.toString())) {
return new DefaultHit<T>(choice, text, TO_STRING_STARTS_WITH);
}
}
return null;
}
@Override
public Class<T> getHitClass() {
return this.hitClass;
}
@Override
public List<SearchHit<T>> getMatches() {
return this.matches;
}
@Override
public boolean isSame(String text, T item) {
return item != null ? text.equals(item.toString()) : false;
}
@Override
public void setSearch(String input) {
this.matches.clear();
final List<DefaultHit<T>> startsWith = new ArrayList<DefaultHit<T>>();
final List<DefaultHit<T>> containedIn = new ArrayList<DefaultHit<T>>();
final String lowerInput = input.toLowerCase();
for (T choice : this.choices) {
final int position = choice.toString().toLowerCase().indexOf(lowerInput);
if (position == 0) {
startsWith.add(new DefaultHit<T>(choice, choice.toString(), TO_STRING_STARTS_WITH));
} else if (position > -1) {
containedIn.add(new DefaultHit<T>(choice, choice.toString(), TO_STRING_CONTAINS));
}
}
Collections.sort(startsWith, HIT_COMPARATOR);
Collections.sort(containedIn, HIT_COMPARATOR);
this.matches.addAll(startsWith);
this.matches.addAll(containedIn);
}
@Override
public String toString(T valueObject) {
return valueObject == null ? null : valueObject.toString();
}
}