/**
* Copyright (c) 2014 Richard Warburton (richard.warburton@gmail.com)
* <p>
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
* <p>
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
* <p>
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
**/
package com.insightfullogic.honest_profiler.core.filters;
import java.util.ArrayList;
import java.util.List;
import java.util.function.DoubleFunction;
import java.util.function.Predicate;
public class Filters
{
private static final String TOTAL_TIME = "total time > ";
private static final String SELF_TIME = "self time > ";
private static final String CLASS_NAME = "class: ";
private final String description;
private final List<Filter> filters;
private int offset;
private Filters(String description)
{
filters = new ArrayList<>();
filters.add(new ThreadSampleFilter());
offset = 0;
if (!description.isEmpty() && description.charAt(description.length() - 1) != ';')
{
description = description + ';';
}
this.description = description;
}
public static List<Filter> parse(String description)
{
return new Filters(description).parse();
}
private List<Filter> parse()
{
while (offset < description.length())
{
if (!(parseByPrefix(TOTAL_TIME, withNumber(TotalTimeShareFilter::new))
|| parseByPrefix(SELF_TIME, withNumber(SelfTimeShareFilter::new))
|| parseByPrefix(CLASS_NAME, this::byClassName)))
{
throw new FilterParseException("Unable to parse: " + remainingDescription());
}
}
return filters;
}
private String remainingDescription()
{
return description.substring(offset);
}
private boolean byClassName(String className)
{
filters.add(new ClassNameFilter(className));
return true;
}
private boolean parseByPrefix(String prefix, Predicate<String> callback)
{
if (!description.startsWith(prefix, offset))
{
return false;
}
int endOfPrefix = offset + prefix.length();
int valueIndex = description.indexOf(';', endOfPrefix);
if (valueIndex == -1)
{
throw new FilterParseException("Unable to parse: " + remainingDescription() + " was expecting ';'");
}
String value = description.substring(endOfPrefix, valueIndex);
offset = valueIndex + 1;
return callback.test(value);
}
private Predicate<String> withNumber(DoubleFunction<Filter> factory)
{
return number -> {
try
{
double minShare = Double.parseDouble(number);
filters.add(factory.apply(minShare));
return true;
}
catch (NumberFormatException e)
{
throw new FilterParseException(e);
}
};
}
}