package de.unisiegen.gtitool.core.entities.regex;
import java.util.ArrayList;
import java.util.HashSet;
import javax.swing.event.EventListenerList;
import de.unisiegen.gtitool.core.entities.Entity;
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.PrettyToken;
import de.unisiegen.gtitool.core.parser.style.Style;
import de.unisiegen.gtitool.core.util.ObjectPair;
/**
* Representation of a Disjunction in the Regex
*
* @author Simon Meurer
* @version
*/
public class DisjunctionNode extends TwoChildNode
{
/**
* The serial version uid
*/
private static final long serialVersionUID = 8726582926785501568L;
/**
* Cached {@link ArrayList} for firstPos
*/
private transient ArrayList < LeafNode > firstPosCache = null;
/**
* Cached {@link ArrayList} for lastPos
*/
private transient ArrayList < LeafNode > lastPosCache = null;
/**
* The {@link EventListenerList}.
*/
private EventListenerList listenerList = new EventListenerList ();
/**
* The offset of this {@link DisjunctionNode} in the source code.
*
* @see #getParserOffset()
* @see #setParserOffset(ParserOffset)
*/
private ParserOffset parserOffset = NO_PARSER_OFFSET;
/**
* Constructor for a {@link DisjunctionNode}
*
* @param regex1 First element of the {@link DisjunctionNode}
* @param regex2 Second element of the {@link DisjunctionNode}
*/
public DisjunctionNode ( RegexNode regex1, RegexNode regex2 )
{
super ( regex1, regex2 );
}
/**
* {@inheritdoc}
*
* @see PrettyPrintable#addPrettyStringChangedListener(de.unisiegen.gtitool.core.entities.listener.PrettyStringChangedListener)
*/
public void addPrettyStringChangedListener (
PrettyStringChangedListener listener )
{
this.listenerList.add ( PrettyStringChangedListener.class, listener );
}
/**
* {@inheritDoc}
*
* @see de.unisiegen.gtitool.core.entities.regex.RegexNode#clone()
*/
@Override
public RegexNode clone ()
{
return new DisjunctionNode ( this.regex1.clone (), this.regex2.clone () );
}
/**
* {@inheritDoc}
*
* @see Comparable#compareTo(java.lang.Object)
*/
public int compareTo ( @SuppressWarnings ( "unused" ) RegexNode o )
{
return 0;
}
/**
* Counts the left Children of the {@link ConcatenationNode}
*
* @return The leftChildren count
*/
public int countLeftChildren ()
{
return 1 + this.regex1.getAllChildren ().size ();
}
/**
* Counts the right Children of the {@link ConcatenationNode}
*
* @return The rightChildren count
*/
public int countRightChildren ()
{
return 1 + this.regex2.getAllChildren ().size ();
}
/**
* {inheritDoc}
*
* @see Object#equals(java.lang.Object)
*/
@Override
public boolean equals ( Object obj )
{
if ( obj == this )
{
return true;
}
if ( obj instanceof DisjunctionNode )
{
DisjunctionNode dis = ( DisjunctionNode ) obj;
return this.regex1.equals ( dis.regex1 )
&& this.regex2.equals ( dis.regex2 );
}
return false;
}
/**
* {@inheritDoc}
*
* @see RegexNode#firstPos()
*/
@Override
public ArrayList < LeafNode > firstPos ()
{
if ( this.firstPosCache == null )
{
this.firstPosCache = new ArrayList < LeafNode > ();
this.firstPosCache.addAll ( this.regex1.firstPos () );
this.firstPosCache.addAll ( this.regex2.firstPos () );
}
return this.firstPosCache;
}
/**
* {@inheritDoc}
*
* @see RegexNode#followPos()
*/
@Override
public HashSet < ObjectPair < LeafNode, LeafNode >> followPos ()
{
HashSet < ObjectPair < LeafNode, LeafNode >> result = new HashSet < ObjectPair < LeafNode, LeafNode > > ();
result.addAll ( this.regex1.followPos () );
result.addAll ( this.regex2.followPos () );
return result;
}
/**
* {@inheritDoc}
*
* @see RegexNode#getAllChildren()
*/
@Override
public ArrayList < RegexNode > getAllChildren ()
{
ArrayList < RegexNode > nodes = new ArrayList < RegexNode > ();
nodes.add ( this.regex1 );
nodes.add ( this.regex2 );
nodes.addAll ( this.regex1.getAllChildren () );
nodes.addAll ( this.regex2.getAllChildren () );
return nodes;
}
/**
* {@inheritDoc}
*
* @see RegexNode#getLeftChildrenCount()
*/
@Override
public int getLeftChildrenCount ()
{
return 1 + this.regex1.getAllChildren ().size ();
}
/**
* {inheritDoc}
*
* @see RegexNode#getNodeString()
*/
@Override
public PrettyString getNodeString ()
{
return new PrettyString ( new PrettyToken ( "|", Style.REGEX_SYMBOL ) ); //$NON-NLS-1$
}
/**
* {@inheritDoc}
*
* @see Entity#getParserOffset()
*/
public ParserOffset getParserOffset ()
{
return this.parserOffset;
}
/**
* {@inheritDoc}
*
* @see de.unisiegen.gtitool.core.entities.regex.RegexNode#getPriority()
*/
@Override
public int getPriority ()
{
return 1;
}
/**
* {@inheritDoc}
*
* @see RegexNode#getRightChildrenCount()
*/
@Override
public int getRightChildrenCount ()
{
return 1 + this.regex2.getAllChildren ().size ();
}
/**
* {@inheritDoc}
*
* @see RegexNode#getAllChildren()
*/
@Override
public ArrayList < LeafNode > getTokenNodes ()
{
ArrayList < LeafNode > nodes = new ArrayList < LeafNode > ();
nodes.addAll ( this.regex1.getTokenNodes () );
nodes.addAll ( this.regex2.getTokenNodes () );
return nodes;
}
/**
* {@inheritDoc}
*
* @see RegexNode#lastPos()
*/
@Override
public ArrayList < LeafNode > lastPos ()
{
if ( this.lastPosCache == null )
{
this.lastPosCache = new ArrayList < LeafNode > ();
this.lastPosCache.addAll ( this.regex1.lastPos () );
this.lastPosCache.addAll ( this.regex2.lastPos () );
}
return this.lastPosCache;
}
/**
* {@inheritDoc}
*
* @see RegexNode#nullable()
*/
@Override
public boolean nullable ()
{
return this.regex1.nullable () || this.regex2.nullable ();
}
/**
* {@inheritdoc}
*
* @see PrettyPrintable#removePrettyStringChangedListener(de.unisiegen.gtitool.core.entities.listener.PrettyStringChangedListener)
*/
public void removePrettyStringChangedListener (
PrettyStringChangedListener listener )
{
this.listenerList.remove ( PrettyStringChangedListener.class, listener );
}
/**
* {@inheritDoc}
*
* @see Entity#setParserOffset(ParserOffset)
*/
public void setParserOffset ( ParserOffset parserOffset )
{
this.parserOffset = parserOffset;
}
/**
* {@inheritDoc}
*
* @see RegexNode#toCoreSyntax(boolean)
*/
@Override
public RegexNode toCoreSyntax ( boolean withCharacterClasses )
{
DisjunctionNode dis = new DisjunctionNode ( this.regex1
.toCoreSyntax ( withCharacterClasses ), this.regex2
.toCoreSyntax ( withCharacterClasses ) );
return dis;
}
/**
* {@inheritDoc}
*
* @see PrettyPrintable#toPrettyString()
*/
public PrettyString toPrettyString ()
{
PrettyString string = new PrettyString ();
if ( this.regex1.getPriority () < getPriority () )
{
string.add ( new PrettyToken ( "(", Style.REGEX_SYMBOL ) ); //$NON-NLS-1$
}
string.add ( this.regex1.toPrettyString () );
if ( this.regex1.getPriority () < getPriority () )
{
string.add ( new PrettyToken ( ")", Style.REGEX_SYMBOL ) ); //$NON-NLS-1$
}
string
.add ( new PrettyString ( new PrettyToken ( "|", Style.REGEX_SYMBOL ) ) ); //$NON-NLS-1$
if ( this.regex2.getPriority () < getPriority () )
{
string.add ( new PrettyToken ( "(", Style.REGEX_SYMBOL ) ); //$NON-NLS-1$
}
string.add ( this.regex2.toPrettyString () );
if ( this.regex2.getPriority () < getPriority () )
{
string.add ( new PrettyToken ( ")", Style.REGEX_SYMBOL ) ); //$NON-NLS-1$
}
return string;
}
/**
* {@inheritDoc}
*
* @see Object#toString()
*/
@Override
public String toString ()
{
return "(" + this.regex1.toString () + "|" + this.regex2.toString () + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
}