package de.unisiegen.gtitool.core.entities; import java.util.ArrayList; import java.util.Iterator; import javax.swing.event.EventListenerList; import de.unisiegen.gtitool.core.entities.listener.PrettyStringChangedListener; import de.unisiegen.gtitool.core.parser.ParserOffset; import de.unisiegen.gtitool.core.parser.style.PrettyPrintable; import de.unisiegen.gtitool.core.parser.style.PrettyString; import de.unisiegen.gtitool.core.parser.style.PrettyString.PrettyStringMode; /** * The {@link DefaultStack} entity. * * @author Christian Fehler * @version $Id$ */ public final class DefaultStack implements Stack { /** * The serial version uid. */ private static final long serialVersionUID = -4411648655106144327L; /** * The offset of this {@link DefaultStack} in the source code. * * @see #getParserOffset() * @see #setParserOffset(ParserOffset) */ private ParserOffset parserOffset = NO_PARSER_OFFSET; /** * The list of {@link Symbol}s. */ private ArrayList < Symbol > symbolList; /** * The cached {@link PrettyString}. */ private PrettyString cachedPrettyString = null; /** * The {@link EventListenerList}. */ private EventListenerList listenerList = new EventListenerList (); /** * The {@link PrettyStringChangedListener}. */ private PrettyStringChangedListener prettyStringChangedListener; /** * Allocates a new {@link DefaultStack}. */ public DefaultStack () { this.prettyStringChangedListener = new PrettyStringChangedListener () { public void prettyStringChanged () { firePrettyStringChanged (); } }; this.symbolList = new ArrayList < Symbol > (); } /** * {@inheritDoc} * * @see PrettyPrintable#addPrettyStringChangedListener(PrettyStringChangedListener) */ public final void addPrettyStringChangedListener ( PrettyStringChangedListener listener ) { this.listenerList.add ( PrettyStringChangedListener.class, listener ); } /** * {@inheritDoc} * * @see Stack#clear() */ public final void clear () { for ( Symbol current : this.symbolList ) { current .removePrettyStringChangedListener ( this.prettyStringChangedListener ); } this.symbolList.clear (); firePrettyStringChanged (); } /** * {@inheritDoc} * * @see Comparable#compareTo(Object) */ public final int compareTo ( Stack other ) { return toString ().compareTo ( other.toString () ); } /** * {@inheritDoc} * * @see Object#equals(Object) */ @Override public final boolean equals ( Object other ) { if ( other instanceof DefaultStack ) { DefaultStack stack = ( DefaultStack ) other; return this.symbolList.equals ( stack.symbolList ); } return false; } /** * Let the listeners know that the {@link PrettyString} has changed. */ protected final void firePrettyStringChanged () { this.cachedPrettyString = null; PrettyStringChangedListener [] listeners = this.listenerList .getListeners ( PrettyStringChangedListener.class ); for ( PrettyStringChangedListener current : listeners ) { current.prettyStringChanged (); } } /** * {@inheritDoc} * * @see Entity#getParserOffset() */ public final ParserOffset getParserOffset () { return this.parserOffset; } /** * {@inheritDoc} * * @see Entity#hashCode() */ @Override public final int hashCode () { return this.symbolList.hashCode (); } /** * {@inheritDoc} * * @see Stack#iterator() */ public final Iterator < Symbol > iterator () { return this.symbolList.iterator (); } /** * {@inheritDoc} * * @see Stack#peak() */ public final Symbol peak () { return this.symbolList.get ( 0 ); } /** * {@inheritDoc} * * @see Stack#peak(int) */ public ArrayList < Symbol > peak ( int size ) { ArrayList < Symbol > result = new ArrayList < Symbol > (); if ( size > this.symbolList.size () ) { result.addAll ( this.symbolList ); return result; } for ( int i = 0 ; i < size ; i++ ) { result.add ( this.symbolList.get ( i ) ); } return result; } /** * {@inheritDoc} * * @see Stack#pop() */ public final Symbol pop () { Symbol symbol = this.symbolList.remove ( 0 ); symbol .removePrettyStringChangedListener ( this.prettyStringChangedListener ); firePrettyStringChanged (); return symbol; } /** * {@inheritDoc} * * @see Stack#push(Symbol) */ public final void push ( Symbol symbol ) { // Symbol if ( symbol == null ) { throw new NullPointerException ( "symbol is null" ); //$NON-NLS-1$ } symbol.addPrettyStringChangedListener ( this.prettyStringChangedListener ); this.symbolList.add ( 0, symbol ); firePrettyStringChanged (); } /** * {@inheritDoc} * * @see PrettyPrintable#removePrettyStringChangedListener(PrettyStringChangedListener) */ public final void removePrettyStringChangedListener ( PrettyStringChangedListener listener ) { this.listenerList.remove ( PrettyStringChangedListener.class, listener ); } /** * {@inheritDoc} * * @see Entity#setParserOffset(ParserOffset) */ public final void setParserOffset ( ParserOffset parserOffset ) { this.parserOffset = parserOffset; } /** *{@inheritDoc} * * @see Stack#size() */ public final int size () { return this.symbolList.size (); } /** * {@inheritDoc} * * @see PrettyPrintable#toPrettyString() */ public final PrettyString toPrettyString () { if ( ( this.cachedPrettyString == null ) || PrettyString.MODE.equals ( PrettyStringMode.CACHING_OFF ) ) { this.cachedPrettyString = new PrettyString (); for ( Symbol current : this.symbolList ) { this.cachedPrettyString.add ( current ); } } return this.cachedPrettyString; } /** * {@inheritDoc} * * @see Entity#toString() */ @Override public final String toString () { StringBuilder result = new StringBuilder (); for ( Symbol current : this.symbolList ) { result.append ( current.getName () ); } return result.toString (); } }