package org.skyscreamer.yoga.util; import org.skyscreamer.yoga.exceptions.ParseSelectorException; /** * Utility for finding nested parentheses * * @author Solomon Duskis <solomon@skyscreamer.org> * @author Corby Page <corby@skyscreamer.org> * @author Carter Page <carter@skyscreamer.org> */ public class ParenthesisUtil { /** * Given an index of an opening parenthesis "(", find the matching closing parenthesis ")". If there are embedded * parenthesis inside the matching pair, this method will ignore them. * <p/> * Example: * <pre> * getMatchingParenthesis("a(b(c))", 1) returns 6 * getMatchingParenthesis("a(b(c))", 3) returns 5 * </pre> * * @param selector String to analyze for the matching selector * @param index Index of the opening parenthesis to match * @return Index of matching closing parenthesis * @throws org.skyscreamer.yoga.exceptions.ParseSelectorException */ public static int getMatchingParenthesisIndex( CharSequence selector, int index ) throws ParseSelectorException { return getMatchingBracketIndex( selector, index, '(', ')' ); } private static int getMatchingBracketIndex( CharSequence selector, int index, char openBracket, char closeBracket ) throws ParseSelectorException { if ( selector.charAt( index ) != openBracket ) { throw new ParseSelectorException( "Selector does not have an opening bracket at index " + index ); } int parenthesesCount = 1; while ( parenthesesCount > 0 && index < selector.length() - 1 ) { index++; if ( selector.charAt( index ) == openBracket ) { parenthesesCount++; } if ( selector.charAt( index ) == closeBracket ) { parenthesesCount--; } } if ( parenthesesCount > 0 ) { throw new ParseSelectorException( "More opening brackets than closing brackets" ); } return index; } }