package com.elsea.stone.property;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Predicate;
public class PropertyPoolSearch {
private PropertyPool pool;
private ArrayList<PropertyElement> valuePool;
public PropertyPoolSearch(PropertyPool pool)
{
this.pool = pool;
}
/**
* Return the first Property Element with the name specified by the argument.
* The returned property element could be a group or a property.
*
* @param elementName The name of the element you want to find
* @return The element with the specified name
*/
public PropertyElement getElement(String elementName)
{
List<PropertyElement> results = getAllElements(elementName);
if (results.size() > 0) return results.get(0);
else return null;
}
/**
* Returns all element, whether property or group, with the specified name.
*
* @param name The name of the elements you want to find
* @return The elements with the specified name
*/
public List<PropertyElement> getAllElements(String name)
{
return filter(p -> p.getName().equals(name));
}
/**
* Returns the first group with the name specified by the argument.
*
* @param name The name of the group you want to find
* @return The group with the specified name
*/
public PropertyGroup getGroup(String name)
{
for (PropertyElement p : getAllElements(name)) {
if (p instanceof PropertyGroup) return (PropertyGroup) p;
}
return null;
}
/**
* Returns the first property with the name specified by the argument.
*
* @param name The name of the property you want to find
* @return The property with the specified name
*/
public Property getProperty(String name)
{
for (PropertyElement p : getAllElements(name)) {
if (p instanceof Property) return (Property) p;
}
return null;
}
/**
* Tests whether or not the pool being searched has duplicate elements
* that each have the same name. It does not test if they have the same
* values.
*
* @param name The name to identify any duplicates of
* @return Whether or not there are duplicates
*/
public boolean hasDuplicatesOf(String name)
{
if (filter(p -> p.getName().equals(name)).size() > 1) return true;
else return false;
}
/**
* Return a list containing all children of the first group found with the name
* specified by the argument of this method.
*
* @param groupName The name of the group whose children will be found
* @return The children of the specified group
*/
public List<PropertyElement> getElementsInGroup(String groupName)
{
List<PropertyElement> results =
filter(p -> p.getName().equals(groupName) && p instanceof PropertyGroup);
if (results.size() > 0)
{
PropertyGroup g = ((PropertyGroup) results.get(0));
return g.getChildren();
}
else return null;
}
/**
* Tests each element in the pool against a predicate
*
* @param p The predicate to test each element against
* @return A list of the elements that tested true against the predicate
*/
public ArrayList<PropertyElement> filter(Predicate<PropertyElement> p)
{
valuePool = new ArrayList<PropertyElement>();
recursive_filter(p, pool.getParent());
return valuePool;
}
private void recursive_filter(Predicate<PropertyElement> p, PropertyElement current)
{
if (p.test(current))
valuePool.add(current);
if (current instanceof PropertyGroup)
{
PropertyGroup group = (PropertyGroup) current;
for (int i = 0; i < group.getSize(); i++)
recursive_filter(p, group.getChildAt(i));
}
}
public void forEach(Consumer<PropertyElement> c)
{
recursive_forEach(c, pool.getParent());
}
private void recursive_forEach(Consumer<PropertyElement> c, PropertyElement current)
{
c.accept(current);
if (current instanceof PropertyGroup)
{
PropertyGroup group = (PropertyGroup) current;
for (int i = 0; i < group.getSize(); i++)
recursive_forEach(c, group.getChildAt(i));
}
}
}