/** * */ package org.dcache.services.info.base; import java.util.Iterator; /** * A StatePathPredicate indicates interest in a particular part of the dCache state * tree. It is an extension of the StatePath in that, logically, any StatePath can * be used to construct a StatePathPredicate. * <p> * The principle usage of the StatePathPredicate is select some subset of the values * within dCache's state. To do this, the <tt>matches()</tt> method should be used. * <p> * When testing whether a StatePath matches, a StatePathPredicate considers the * asterisk character ('*') to be a wildcard and will match any corresponding value * in the StatePath. * @author Paul Millar <paul.millar@desy.de> */ public class StatePathPredicate extends StatePath { private static final String WILDCARD_ELEMENT = "*"; /** * Parse a dot-separated path to build a StatePathPredicate * @param path the path, as an ordered list of path elements, each element separated by a dot. * @return the corresponding StatePath. */ public static StatePathPredicate parsePath(String path) { if (path == null) { return null; } String elements[] = path.split("\\."); return new StatePathPredicate(elements); } /** * Whether two elements are considered matching. * @param predicateElement * @param pathElement * @return true if pathElement matches predicateElement */ private static boolean elementsMatch(String predicateElement, String pathElement) { if (pathElement == null || predicateElement == null) { return false; } if (predicateElement.equals(WILDCARD_ELEMENT)) { return true; } if (pathElement.equals(predicateElement)) { return true; } return false; } public StatePathPredicate(StatePath path) { super(path); } public StatePathPredicate(String path) { super(path); } private StatePathPredicate(String[] elements) { super(elements); } /** * Indicate whether a particular StatePath matches the * predicate. A match is where each element of this predicate matches * the corresponding element of the StatePath. The StatePath length must * be equal to or greater than this StatePathPredicte. * * @param path the particular path within dCache's state. * @return true if this path matches this predicate, false otherwise. */ public boolean matches(StatePath path) { if (path == null) { return false; } if (path._elements.size() != this._elements.size()) { return false; } Iterator<String> myItr = this._elements.iterator(); for (String pathElement : path._elements) { String myElement = myItr.next(); if (!StatePathPredicate.elementsMatch(myElement, pathElement)) { return false; } } return true; } /** * Build a new StatePathPredicate that matches the childPaths of the StatePaths * that match this StatePathPredicate. For example, if the current * StatePathPredicate is characterised as <tt>aa.bb.*.cc</tt>, then * the returned StatePathPredicate is characterised by <tt>bb.*.cc</tt>. * <p> * If the StatePathPredicate has no children of children, null is returned. * * @return the path for the child element, or null if there is no child. */ @Override public StatePathPredicate childPath() { StatePath childPath = super.childPath(); return childPath == null ? null : new StatePathPredicate(childPath); } /** * Return true if the top-most element of this predicate matches the given String. * @param name the name of the child element * @return true if child element matches top-most element, false otherwise */ public boolean topElementMatches(String name) { return StatePathPredicate.elementsMatch(_elements.get(0), name); } }