package org.solrmarc.index.collector;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import org.solrmarc.index.indexer.IndexerSpecException;
import org.solrmarc.tools.SolrMarcIndexerException;
import org.solrmarc.tools.StringNaturalCompare;
public class MultiValueCollector //implements AbstractValueCollector<Collection<String>>
{
boolean isUnique = false;
boolean deleteRecordIfEmpty = false;
Comparator<String> sortComparator = null;
public enum eFirstVal { ALL, FIRST, NOTFIRST };
public static eFirstVal fromString(String str)
{
if (str.equals("first")) return(eFirstVal.FIRST);
if (str.equals("notfirst")) return(eFirstVal.NOTFIRST);
return(eFirstVal.ALL);
};
eFirstVal first = eFirstVal.ALL;
public MultiValueCollector(String comp, String dir, boolean unique, String first)
{
isUnique = unique;
this.first = fromString(first);;
sortComparator = setComparator(comp, dir);
}
public MultiValueCollector(boolean unique, String first)
{
isUnique = unique;
this.first = fromString(first);;
sortComparator = null;
}
public MultiValueCollector()
{
isUnique = false;
this.first = eFirstVal.ALL;
sortComparator = null;
}
private class LengthComp implements Comparator<String> {
public int compare(String s1, String s2)
{
return s1.length() - s2.length();
}
}
private class NaturalComp implements Comparator<String> {
public int compare(String s1, String s2)
{
return s1.compareTo(s2);
}
}
private Comparator<String> setComparator(String compStr, String dir)
{
Comparator<String> comp = null;
if (compStr == null) return(null);
if (compStr.equals("str") && dir.equals("desc"))
comp = Collections.reverseOrder();
else if (compStr.equals("str") && dir.equals("asc"))
comp = new NaturalComp();
else if (compStr.equals("num") && dir.equals("asc"))
comp = new StringNaturalCompare();
else if (compStr.equals("num") && dir.equals("desc"))
comp = Collections.reverseOrder( new StringNaturalCompare());
else if (compStr.equals("length") && dir.equals("asc"))
comp = new LengthComp();
else if (compStr.equals("length") && dir.equals("desc"))
comp = Collections.reverseOrder( new LengthComp());
else if (!compStr.equals("length") && !compStr.equals("num") && !compStr.equals("str"))
{
throw new IndexerSpecException("Invalid sort specification, valid values are \"str\" \"num\" \"length\" ");
}
else
{
throw new IndexerSpecException("Invalid sort direction, valid values are \"asc\" \"desc\" ");
}
return(comp);
}
public Collection<String> collect(final Collection<String> values)
{
if ((!isUnique || values instanceof Set<?> ) && sortComparator == null && first == eFirstVal.ALL && deleteRecordIfEmpty == false)
return values;
Collection<String> result;
if (isUnique)
{
if (sortComparator == null)
{
result = new LinkedHashSet<String>();
}
else
{
result = new TreeSet<String>(sortComparator);
}
result.addAll(values);
}
else if (sortComparator != null)
{
List<String> resultL = new ArrayList<String>();
resultL.addAll(values);
Collections.sort(resultL, sortComparator);
result = resultL;
}
else
{
result = values;
}
if (result == null || result.isEmpty())
{
if (deleteRecordIfEmpty)
{
throw new SolrMarcIndexerException(SolrMarcIndexerException.DELETE);
}
return (result);
}
else if (first == eFirstVal.FIRST)
{
return Collections.singletonList(result.iterator().next());
}
else if (first == eFirstVal.NOTFIRST)
{
if (result instanceof List)
{
result = ((List<String>) result).subList(1, result.size());
}
else
{
result = Collections.list(Collections.enumeration(result)).subList(1, result.size());
}
}
if (deleteRecordIfEmpty)
{
if (result.size() == 0)
{
throw new SolrMarcIndexerException(SolrMarcIndexerException.DELETE);
}
}
return(result);
}
public boolean isUnique()
{
return isUnique;
}
public MultiValueCollector setUnique(boolean isUnique)
{
this.isUnique = isUnique;
return(this);
}
public Comparator<String> getSortComparator()
{
return sortComparator;
}
public MultiValueCollector setSortComparator(String comp, String dir)
{
this.sortComparator = setComparator(comp, dir);
return(this);
}
// public boolean isFirst()
// {
// return first;
// }
public MultiValueCollector setFirst(eFirstVal first)
{
this.first = first;
return(this);
}
public MultiValueCollector setFirst(String firstStr)
{
this.first = fromString(firstStr);
return(this);
}
public void setDeleteRecordIfEmpty()
{
this.deleteRecordIfEmpty = true;
}
}