package common.prettyprinter;
import java.text.CharacterIterator;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
/**
* Default implementation of the <code>PrettyCharIterator</code> interface,
* which operates on data provided by the <code>PrettyString</code> class.
*
* @author Benedikt Meurer
* @version $Id$
*
* @see common.prettyprinter.DefaultPrettyString
* @see common.prettyprinter.PrettyCharIterator
*/
final class DefaultPrettyCharIterator implements PrettyCharIterator {
//
// Attributes
//
/**
* The current character index of the iterator.
*
* @see #getIndex()
*/
private int index;
/**
* The raw character content of the {@link PrettyString} we're iterating.
*/
private String content;
/**
* The mapping of printables to annotations.
*
* @see #getAnnotation()
*/
private Map<PrettyPrintable, PrettyAnnotation> annotations;
/**
* The mapping of character indices to {@link common.prettyprinter.PrettyStyle}s.
*
* @see #getStyle()
*/
private PrettyStyle[] styles;
//
// Constructors (package)
//
/**
* Allocates a new <code>DefaultPrettyCharIterator</code> with the
* specified parameters and an <code>index</code> of 0.
*
* @param content the string content.
* @param annotations the annotations for <code>content</code>.
* @param styles the <code>PrettyStyle</code> mapping in <code>content</code>.
*
* @throws NullPointerException if either <code>content</code>, <code>annotations</code>
* or <code>styles</code> is <code>null</code>.
*/
DefaultPrettyCharIterator(String content, Map<PrettyPrintable, PrettyAnnotation> annotations, PrettyStyle[] styles) {
this(content, annotations, styles, 0);
}
/**
* Allocates a new <code>DefaultPrettyCharIterator</code> with the
* specified parameters.
*
* @param content the string content.
* @param annotations the annotations for <code>content</code>.
* @param styles the <code>PrettyStyle</code> mapping in <code>content</code>.
* @param index the start index.
*
* @throws NullPointerException if either <code>content</code>, <code>annotations</code>
* or <code>styles</code> is <code>null</code>.
*/
DefaultPrettyCharIterator(String content, Map<PrettyPrintable, PrettyAnnotation> annotations, PrettyStyle[] styles, int index) {
if (content == null) {
throw new NullPointerException("content is null");
}
if (annotations == null) {
throw new NullPointerException("annotations is null");
}
if (styles == null) {
throw new NullPointerException("styles is null");
}
this.index = index;
this.content = content;
this.annotations = annotations;
this.styles = styles;
}
//
// PrettyCharIterator methods
//
/**
* {@inheritDoc}
*
* @see common.prettyprinter.PrettyCharIterator#getAnnotation()
*/
public PrettyAnnotation getAnnotation() {
Collection<PrettyAnnotation> annotations = this.annotations.values();
for (Iterator<PrettyAnnotation> iterator = annotations.iterator(); iterator.hasNext(); ) {
PrettyAnnotation annotation = iterator.next();
if (annotation.getStartOffset() <= this.index && this.index <= annotation.getEndOffset())
return annotation;
}
// should never be reached
throw new IllegalStateException("Character iterator index out of bounds");
}
/**
* {@inheritDoc}
*
* @see common.prettyprinter.PrettyCharIterator#getStyle()
*/
public PrettyStyle getStyle() {
if (this.index < getEndIndex())
return this.styles[this.index];
else
return PrettyStyle.NONE;
}
//
// CharacterIterator methods
//
/**
* {@inheritDoc}
*
* @see java.text.CharacterIterator#first()
*/
public char first() {
return setIndex(getBeginIndex());
}
/**
* {@inheritDoc}
*
* @see java.text.CharacterIterator#last()
*/
public char last() {
return setIndex(getEndIndex());
}
/**
* {@inheritDoc}
*
* @see java.text.CharacterIterator#current()
*/
public char current() {
if (this.index == getEndIndex())
return CharacterIterator.DONE;
else
return this.content.charAt(this.index);
}
/**
* {@inheritDoc}
*
* @see java.text.CharacterIterator#next()
*/
public char next() {
if (this.index == getEndIndex())
return CharacterIterator.DONE;
return setIndex(this.index + 1);
}
/**
* {@inheritDoc}
*
* @see java.text.CharacterIterator#previous()
*/
public char previous() {
if (this.index == getBeginIndex())
return CharacterIterator.DONE;
return setIndex(this.index - 1);
}
/**
* {@inheritDoc}
*
* @see java.text.CharacterIterator#setIndex(int)
*/
public char setIndex(int position) {
if (position < getBeginIndex() || position > getEndIndex())
throw new IllegalArgumentException("Invalid character iterator position " + position);
this.index = position;
return current();
}
/**
* {@inheritDoc}
*
* @see java.text.CharacterIterator#getBeginIndex()
*/
public int getBeginIndex() {
return 0;
}
/**
* {@inheritDoc}
*
* @see java.text.CharacterIterator#getEndIndex()
*/
public int getEndIndex() {
return this.content.length();
}
/**
* {@inheritDoc}
*
* @see java.text.CharacterIterator#getIndex()
*/
public int getIndex() {
return this.index;
}
/**
* Clones the character iterator with its current state.
*
* @return the cloned character iterator.
*
* @see java.lang.Object#clone()
*/
public Object clone() {
return new DefaultPrettyCharIterator(this.content, this.annotations, this.styles, this.index);
}
}