package com.plectix.simulator.util.string; import java.util.Comparator; import com.plectix.simulator.staticanalysis.Link; import com.plectix.simulator.staticanalysis.LinkStatus; import com.plectix.simulator.staticanalysis.Site; /** * This class compares two Sites. We assume that the Agent Names are the same. Here is the comparison rules: * * <ul> * <li> First we compare the Site names. * <li> If two Sites have the same name, we compare their Internal State names. * <li> If two Sites are still equivalent, then a free site comes before a bound site * <li> If both Sites are bound, we compare the name of the Sites they are bound to * <li> If these names are the same, then we compare the Internal State names of the Sites they are bound to * <li> If still equivalent, then we compare the Agent names they are bound to * </ul> * * @author ecemis */ public final class SiteComparator implements Comparator<Site> { public static final SiteComparator SITE_COMPARATOR = new SiteComparator(); /** * Default constructor. */ private SiteComparator() { super(); } public final int compare(final Site o1, final Site o2) { if (o1 == null) { if (o2 == null) { return 0; } else { return -1; } } else { if (o2 == null) { return 1; } else { // don't handle this case here... go below... } } // first compare the site names: int result = o1.getName().compareTo(o2.getName()); if (result != 0) { return result; } // then compare the names of the internal states: result = o1.getInternalState().getName().compareTo(o2.getInternalState().getName()); if (result != 0) { return result; } // both sites have the same name and same internal states... // so let's compare their link sites: Site linkSite1 = getLinkSite(o1); Site linkSite2 = getLinkSite(o2); if (linkSite1 == null) { if (linkSite2 == null) { // both sites are free: return 0; } else { // let's have free site before bound site: return -1; } } else { if (linkSite2 == null) { // let's have free site before bound site: return +1; } else { // both sites are bound: // so let's compare the site names they are bound to: result = linkSite1.getName().compareTo(linkSite2.getName()); if (result != 0) { return result; } // both sites are bound to a site with the same name! // then compare the names of the internal states: result = linkSite1.getInternalState().getName().compareTo(linkSite2.getInternalState().getName()); if (result != 0) { return result; } // so let's compare the name of the Agents they are bound to: return linkSite1.getParentAgent().getName().compareTo(linkSite2.getParentAgent().getName()); } } // we assume that the agents have the same name, so we can't use the agentLink to, CAgent agentLink = o1.getAgentLink(); // can't use linkIndex as an invariant: int linkIndex = o1.getLinkIndex(); } private static final Site getLinkSite(final Site site) { Link linkState = site.getLinkState(); LinkStatus statusLink = linkState.getStatusLink(); if (statusLink == LinkStatus.BOUND) { return linkState.getConnectedSite(); } else if (statusLink == LinkStatus.WILDCARD) { return null; } else if (statusLink == LinkStatus.FREE) { return null; } else { // we expect that the site will be either BOUND, WILDCARD, or FREE. throw exception otherwise: throw new RuntimeException("Unexpected State: Link state is neither BOUND nor WILDCARD nor FREE."); } } }