package com.plectix.simulator.staticanalysis.abstracting;
import com.plectix.simulator.staticanalysis.Agent;
import com.plectix.simulator.staticanalysis.Link;
import com.plectix.simulator.staticanalysis.LinkRank;
import com.plectix.simulator.staticanalysis.LinkStatus;
import com.plectix.simulator.staticanalysis.Site;
/**
* This class implements link state. Uses in Contact map.
* @author avokhmin
*
*/
public final class AbstractLinkState {
private LinkRank statusLinkRank;
private LinkStatus statusLink;
private String connectedSiteName = Site.DEFAULT_NAME;
private String agentName = Agent.DEFAULT_NAME;
/**
* Constructor of CContactMapLinkState
*/
public AbstractLinkState() {
setFreeLinkState();
}
/**
* Constructor of CContactMapLinkState.
* @param linkState given link state for abstraction
*/
public AbstractLinkState(Link linkState) {
if (linkState.getConnectedSite() != null) {
this.agentName = linkState.getConnectedSite().getParentAgent().getName();
this.connectedSiteName = linkState.getConnectedSite().getName();
}
this.statusLinkRank = linkState.getStatusLinkRank();
this.statusLink = linkState.getStatusLink();
}
/**
* Constructor of CContactMapLinkState
* @param linkState given link state
*/
public AbstractLinkState(AbstractLinkState linkState) {
if (!linkState.getConnectedSiteName().equals(Site.DEFAULT_NAME)) {
this.agentName = linkState.getAgentName();
this.connectedSiteName = linkState.getConnectedSiteName();
}
this.statusLink = linkState.getStatusLink();
this.statusLinkRank = linkState.getStatusLinkRank();
}
/**
* Sets status of this link to a given one
* @param status new value
*/
public final void setStatusLink(LinkStatus status) {
this.statusLink = status;
if (status == LinkStatus.BOUND)
statusLinkRank = LinkRank.BOUND;
else
statusLinkRank = LinkRank.FREE;
}
/**
* This method sets id of link site
* @param id given id
*/
public final void setLinkSiteName(String name) {
this.connectedSiteName = name;
}
/**
* This method sets id of link agent
* @param id given id
*/
public final void setAgentName(String name) {
this.agentName = name;
}
/**
* Returns the rank of the status link (according to the Simulation Engine
* Specification part 2). We use this one to compare links.
* @return status-rank of this link
*/
public final LinkRank getStatusLinkRank() {
switch (statusLink) {
case BOUND:
if (!connectedSiteName.equals(Site.DEFAULT_NAME))
return LinkRank.BOUND;
else
return LinkRank.SEMI_LINK;
case WILDCARD:
return LinkRank.BOUND_OR_FREE;
default:
return LinkRank.FREE;
}
}
/**
* This method returns current status of this link
* @return current status of this link
*/
public final LinkStatus getStatusLink(){
return statusLink;
}
/**
* This method returns id of link site
* @return id of link site
*/
public final String getConnectedSiteName() {
return connectedSiteName;
}
/**
* This method returns id of link agent
* @return id of link agent
*/
public final String getAgentName() {
return agentName;
}
private final void setDefaultNames() {
connectedSiteName = Site.DEFAULT_NAME;
agentName = Agent.DEFAULT_NAME;
}
/**
* This method sets this link free
*/
public final void setFreeLinkState() {
statusLink = LinkStatus.FREE;
statusLinkRank = LinkRank.FREE;
setDefaultNames();
}
public final void setWildLinkState(){
statusLink = LinkStatus.WILDCARD;
statusLinkRank = LinkRank.BOUND_OR_FREE;
setDefaultNames();
}
public final void setSemiLink() {
statusLink = LinkStatus.BOUND;
statusLinkRank = LinkRank.SEMI_LINK;
setDefaultNames();
}
/**
* This method returns <tt>true</tt> if current link state equals to given link state, otherwise <tt>false</tt> <br>
* Equals by:
* <li><b>statusLinkRank</b></li>
* <li>link agent name</li>
* <li>link site name</li>
* <li>internal state from link site<br>
* if internal state from current/given link state does "EMPTY" returns <tt>true</tt>, otherwise compare their id.
* </li>
* @param linkState given state for checks
* @return <tt>true</tt> if current state equals to given state, otherwise <tt>false</tt>
*/
public final boolean equalz(AbstractLinkState linkState) {
if (this == linkState) {
return true;
}
if (linkState == null) {
return false;
}
if (this.statusLinkRank != linkState.getStatusLinkRank())
return false;
if (!this.agentName.equals(linkState.getAgentName()))
return false;
if (!this.connectedSiteName.equals(linkState.getConnectedSiteName()))
return false;
return true;
}
/**
* This method compares this link with the other one and returns true or false, according
* to the fixed order of link-status ranks.
* @see LinkRank
* @param solutionLinkState the other link to compare to
* @return <tt>true</tt> if this link's status-rank is "smaller" then status rank of the other link
*/
public final boolean compareLinkStates(
AbstractLinkState solutionLinkState) {
if (this.isLeftBranchStatus()
&& solutionLinkState.isRightBranchStatus())
return false;
if (this.isRightBranchStatus()
&& solutionLinkState.isLeftBranchStatus())
return false;
if (this.getStatusLinkRank().lessPriority(
solutionLinkState.getStatusLinkRank()))
return true;
if (this.getStatusLinkRank() == solutionLinkState.getStatusLinkRank()
&& this.getStatusLinkRank() == LinkRank.BOUND)
if (this.equalz(solutionLinkState))
return true;
if (this.getStatusLinkRank() == solutionLinkState.getStatusLinkRank()
&& this.getStatusLinkRank() != LinkRank.BOUND)
return true;
return false;
}
private final boolean isLeftBranchStatus() {
return (statusLink == LinkStatus.FREE) ? true : false;
}
private final boolean isRightBranchStatus() {
return (statusLink == LinkStatus.BOUND) ? true : false;
}
}