package org.skyscreamer.yoga.selector.parser;
import org.skyscreamer.yoga.exceptions.ParseSelectorException;
import org.skyscreamer.yoga.selector.FieldSelector;
import org.skyscreamer.yoga.util.ParenthesisUtil;
/**
* This abstract class provides functionality for parenthetical-style selector
* parsers.
*
* @author Solomon Duskis <solomon@skyscreamer.org>
* @author Corby Page <corby@skyscreamer.org>
* @author Carter Page <carter@skyscreamer.org>
*/
public abstract class ParentheticalSelectorParser extends SelectorParser
{
protected FieldSelector parseParentheticalSelector( String rawSelectorExpression, String openParenthesis ) throws ParseSelectorException
{
FieldSelector selector = new FieldSelector();
StringBuilder stringBuilder = new StringBuilder( rawSelectorExpression );
while (stringBuilder.length() > 0)
{
processNextSelectorField( selector, stringBuilder, openParenthesis );
}
return selector;
}
private void processNextSelectorField(FieldSelector selector, StringBuilder selectorBuff,
String openParenthesis) throws ParseSelectorException
{
int index = 0;
boolean done = false;
StringBuilder fieldNameBuilder = new StringBuilder();
FieldSelector subSelector = new FieldSelector();
while (!done)
{
if (selectorBuff.charAt( index ) == ',')
{
done = true;
}
else if ( selectorBuff.substring( index ).startsWith( openParenthesis ) )
{
done = true;
int matchIndex = ParenthesisUtil.getMatchingParenthesisIndex( selectorBuff, index
+ openParenthesis.length() - 1 );
subSelector = parseParentheticalSelector(
selectorBuff.substring( index + openParenthesis.length(), matchIndex ),
openParenthesis );
if (selectorBuff.length() > matchIndex + 1
&& selectorBuff.charAt( matchIndex + 1 ) != ',')
{
throw new ParseSelectorException( "A nested selector not at the end of its parent must be followed by a comma" );
}
index = matchIndex + 1;
}
else
{
fieldNameBuilder.append( selectorBuff.charAt( index ) );
}
index++;
if (index == selectorBuff.length())
{
done = true;
}
}
selectorBuff.delete( 0, index );
String fieldName = fieldNameBuilder.toString();
if (fieldName.equals( HREF ))
{
throw new IllegalArgumentException( HREF + " is a reserved keyword for selectors" );
}
selector.register( fieldName, subSelector );
}
}