![JAR search and dependency download from the Maven repository](/logo.png)
uk.nhs.ciao.docs.parser.PropertySelector Maven / Gradle / Ivy
package uk.nhs.ciao.docs.parser;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import uk.nhs.ciao.util.SimpleEntry;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.ObjectArrays;
/**
* Selects a property (or properties) from a dynamic map structure.
*
* Supported syntax is:
*
* .{string}
- matches key in map
* [{integer}]
- matches index in list
* .*
- matches any key in map
* [*]
- matches any index in list
*
*
* Some examples:
*
* authors[1]
* author.firstName
* author.*
* authors[*]
* authors[*].*
*
*/
public final class PropertySelector {
/**
* Selects the root of a properties map
*/
private static final PropertySelector ROOT = new PropertySelector(new Object[0]);
private final Object[] segments;
private final boolean multi;
private int hash;
/**
* Returns a selector matching the specified path
*/
public static PropertySelector valueOf(final String path) {
final boolean allowWildcards = true;
return Strings.isNullOrEmpty(path) ? ROOT : new PropertySelector(PropertyPath.parse(path, allowWildcards));
}
PropertySelector(final Object[] segments) {
this.segments = segments;
this.multi = PropertyPath.containsWildcard(segments);
}
/**
* Tests if this is the root selector
*/
public boolean isRoot() {
return segments.length == 0;
}
/**
* Tests if this selector may select multiple matches
* (i.e. contains a wildcard)
*/
public boolean isMulti() {
return multi;
}
/**
* Returns the PropertyName equivalent to this selector if a single name is identified or
* null
if the path contains wildcards
*/
public PropertyName toPropertyName() {
return multi ? null : new PropertyName(Arrays.copyOf(segments, segments.length));
}
/**
* Returns the string path associated with this selector
*/
public String getPath() {
return PropertyPath.toString(segments);
}
/**
* Returns the parent of this selector if it is not a root
*/
public PropertySelector getParent() {
return isRoot() ? null : new PropertySelector(Arrays.copyOf(segments, segments.length - 1));
}
/**
* Returns the child selector associated with this selector and the specified
* appended path segments
*/
public PropertySelector getChild(final String childPath) {
final boolean allowWildcards = true;
final Object[] childSegments = PropertyPath.parse(childPath, allowWildcards);
Preconditions.checkArgument(childSegments.length > 0, "childPath must be provided");
return new PropertySelector(ObjectArrays.concat(segments, childSegments, Object.class));
}
/**
* Selects the first matching property key/value pairs from the dynamic map
*
* The entry key is encoded as a matching path
*/
public Entry select(final Map properties) {
return select(Object.class, properties);
}
/**
* Selects the first matching property value from the dynamic map
*/
public Object selectValue(final Map properties) {
return selectValue(Object.class, properties);
}
/**
* Selects the first matching property key/value pairs from the dynamic map
*
* The entry key is encoded as a matching path
*
* @param type The type of objects matched - any objects matching the path selector but of
* the wrong type are ignored
*/
public Entry select(final Class type, final Map properties) {
final Entry