blob: 330734bb05eff589b38f19cc5054ef16d0c5452a [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009 University of Illinois at Urbana-Champaign and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* UIUC - Initial API and implementation
*******************************************************************************/
package org.eclipse.rephraserengine.core.vpg;
import java.io.Serializable;
import org.eclipse.rephraserengine.core.preservation.ReplacementList;
/**
* A semantic edge in a VPG.
* <a href="../../../overview-summary.html#DEA">More Information</a>
*
* @author Jeff Overbey
*
* @param <A> AST type
* @param <T> token type
* @param <R> {@link IVPGNode}/{@link NodeRef} type
*/
public final class VPGEdge<A, T, R extends IVPGNode<T>> implements Comparable<VPGEdge<?,?,?>>, Serializable
{
private static final long serialVersionUID = 1L;
public static enum Classification
{
INCOMING,
OUTGOING,
INTERNAL,
EXTERNAL
}
protected final R source;
protected final R sink;
protected final int type;
protected transient VPGEdge<A, T, R> origEdge;
/**
* Constructor. Creates an edge of the given type between the given tokens in the given VPG.
* <p>
* The edge is <i>not</i> added to the VPG database automatically.
*/
public VPGEdge(R source, R sink, int type)
{
this.source = source;
this.sink = sink;
this.type = type;
this.origEdge = this;
}
/**
* Constructor. Creates an edge of the given type between the given tokens in the given VPG.
* <p>
* The edge is <i>not</i> added to the VPG database automatically.
*/
public VPGEdge(R source, R sink, Enum<?> type)
{
this(source, sink, type.ordinal());
}
///////////////////////////////////////////////////////////////////////////
// Accessors
///////////////////////////////////////////////////////////////////////////
/**
* @return a TokenRef describing the token from which this edge emanates
*/
public R getSource()
{
return source;
}
/**
* @return a TokenRef describing the token to which this edge points
*/
public R getSink()
{
return sink;
}
/** @return the type of this edge */
public int getType()
{
return type;
}
/**
* @return the original edge, if this edge is a projection created by
* {@link #projectInitial(ReplacementList)} or {@link #projectFinal(ReplacementList)}
*/
public VPGEdge<A, T, R> getOriginalEdge()
{
return origEdge;
}
///////////////////////////////////////////////////////////////////////////
// Utility Methods
///////////////////////////////////////////////////////////////////////////
/** @return the token from which this edge emanates
* (i.e., a pointer to the token in an AST) */
public T findSource() throws Exception
{
return source.getASTNode();
}
/** @return the token to which this edge points
* (i.e., a pointer to the token in an AST) */
public T findSink() throws Exception
{
return sink.getASTNode();
}
///////////////////////////////////////////////////////////////////////////
public int compareTo(VPGEdge<?,?,?> that)
{
int result = 0;
if (this.type < that.type)
result = -1;
else if (this.type > that.type)
result = 1;
if (result != 0) return result;
result = this.getClassification().compareTo(that.getClassification());
if (result != 0) return result;
if (this.source != null && that.source == null)
result = -1;
else if (this.source == null && that.source != null)
result = 1;
else if (this.source != null && that.source != null)
result = this.source.compareTo(that.source);
if (result != 0) return result;
if (this.sink != null && that.sink == null)
result = -1;
else if (this.sink == null && that.sink != null)
result = 1;
else if (this.sink != null && that.sink != null)
result = this.sink.compareTo(that.sink);
return result;
}
@Override public String toString()
{
return "Edge of type " + type + " from " + source + " to " + sink; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
/**
* @return the initial model projection of this edge
*/
public VPGEdge<A, T, R> projectInitial(ReplacementList replacements, VPG<A,T,R> vpg)
{
R srcProj = replacements.projectInitial(source, vpg);
R sinkProj = replacements.projectInitial(sink, vpg);
VPGEdge<A, T, R> result = new VPGEdge<A, T, R>(srcProj, sinkProj, type);
result.origEdge = this;
return result;
}
/**
* @return the final model projection of this edge
*/
public VPGEdge<A, T, R> projectFinal(ReplacementList replacements, VPG<A,T,R> vpg)
{
R srcProj = replacements.projectFinal(source, vpg);
R sinkProj = replacements.projectFinal(sink, vpg);
VPGEdge<A, T, R> result = new VPGEdge<A, T, R>(srcProj, sinkProj, type);
result.origEdge = this;
return result;
}
/**
* @return the classification of this edge
*/
public Classification getClassification()
{
if (source != null && sink != null)
return Classification.EXTERNAL;
else if (source != null && sink == null)
return Classification.INCOMING;
else if (source == null && sink != null)
return Classification.OUTGOING;
else // (source == null && sink == null)
return Classification.INTERNAL;
}
}