package com.plectix.simulator.staticanalysis.abstracting; import java.util.Collection; import java.util.LinkedHashMap; import java.util.Map; import com.plectix.simulator.staticanalysis.Agent; import com.plectix.simulator.staticanalysis.NamedEntity; import com.plectix.simulator.staticanalysis.Site; /** * This class implements abstract agent.<br> * SubView presented in the some form<br> * AbstractAgent include part or all information of real Agent<br> * Uses for construct Contact map. * * @author avokhmin * */ public final class AbstractAgent extends NamedEntity { private static final String DEFAULT_NAME = Agent.DEFAULT_NAME; private final AbstractSite defaultSite = new AbstractSite(this, Site.DEFAULT_NAME); private final String name; private Map<String, AbstractSite> sitesMap = new LinkedHashMap<String, AbstractSite>(); /** * Constructor of CContactMapAbstractAgent.<br> * Sets <b>nameID</b> only. No fills sites map. * * @param agent * given agent */ public AbstractAgent(Agent agent) { this.name = agent.getName(); for (Site s : agent.getSites()) { AbstractSite newSite = new AbstractSite(s, this); addSite(newSite); } } public AbstractAgent(String name) { this.name = name; } /** * Constructor of CContactMapAbstractAgent.<br> * Sets <b>nameID</b>, fills sites map. * * @param agent * given agent */ public AbstractAgent(AbstractAgent agent) { this.name = agent.getName(); this.sitesMap = new LinkedHashMap<String, AbstractSite>(); for (Map.Entry<String, AbstractSite> entry : agent.getSitesMap() .entrySet()) { AbstractSite newSite = entry.getValue().clone(); newSite.setParentAgent(this); sitesMap.put(entry.getKey(), newSite); } } public AbstractAgent(Agent agent, AbstractAgent modelAgent) { this.name = agent.getName(); this.sitesMap = new LinkedHashMap<String, AbstractSite>(); for (Site site : agent.getSites()) { String key = site.getName(); AbstractSite abstractSite = new AbstractSite(site, this); sitesMap.put(key, abstractSite); } for (Map.Entry<String, AbstractSite> entry : modelAgent.getSitesMap().entrySet()) { AbstractSite abstractSite = this.sitesMap.get(entry.getKey()); if (abstractSite == null) { this.sitesMap.put(entry.getKey(), entry.getValue()); } } } /** * This method returns default site from current agent * @return default site from current agent */ public final AbstractSite getDefaultSite() { return defaultSite; } /** * This method returns character expression of current agent. * * @return character expression of current agent. */ public final String getKey() { return this.toString() + " " + sitesMap.toString(); } /** * This method returns map of sites. * * @return map of sites. */ public final Map<String, AbstractSite> getSitesMap() { return this.sitesMap; } /** * This method returns site by given id * * @param name * given id * @return site from sites map. */ public final AbstractSite getSiteByName(String name) { return this.sitesMap.get(name); } /** * This method adds given site to sites map. * * @param newSite * given site */ public final void addSite(AbstractSite newSite) { this.sitesMap.put(newSite.getName(), newSite); } /** * This method adds given site to sites map, if there hasn't it. * * @param siteToAdd * given site */ public final void addModelSite(AbstractSite siteToAdd) { String name = siteToAdd.getName(); AbstractSite site = this.sitesMap.get(name); if (site == null) { this.sitesMap.put(name, siteToAdd); } } /** * This method returns <tt>true</tt> if current agent include in given list * of agents.<br> * Checks by name * * @param collection * given collections of agents * @return <tt>true</tt> if current agent include in given list of agents, * otherwise <tt>false</tt> */ public final boolean includedInCollectionByName(Collection<AbstractAgent> collection) { for (AbstractAgent agent : collection) { if (this.getName().equals(agent.getName())) { return true; } } return false; } /** * This method returns <tt>true</tt> if given agent equals to current agent, * otherwise <tt>false</tt> * * @param agent * given agent * @return <tt>true</tt> if given agent equals to current agent, otherwise * <tt>false</tt> */ final boolean equalz(AbstractAgent agent) { if (this == agent) { return true; } if (agent == null) { return false; } if (!name.equals(agent.name)) return false; if (this.sitesMap.size() != agent.getSitesMap().size()) return false; if (!compareSites(sitesMap, agent.getSitesMap())) return false; return true; } /** * Util method. Uses for compare given sites maps. * * @param sitesMap1 * given site map * @param sitesMap2 * given site map * @return <tt>true</tt> if sites maps are equals, otherwise <tt>false</tt> */ private static final boolean compareSites(Map<String, AbstractSite> sitesMap1, Map<String, AbstractSite> sitesMap2) { for (Map.Entry<String, AbstractSite> entry : sitesMap1.entrySet()) { if (!entry.getValue().equalz(sitesMap2.get(entry.getKey()))) return false; } return true; } /** * This method returns name of this agent * * @see com.plectix.simulator.util.NameDictionary NameDictionary * @return name of this agent */ public final String getName() { return name; } /** * This method checks include current agent in given collections. * * @param collection * given collection for checks * @see #equalz(AbstractAgent) * @return <tt>true</tt> if current agent include in given collection, * otherwise <tt>false</tt> */ public final boolean includedInCollection(Collection<AbstractAgent> collection) { for (AbstractAgent agent : collection) { if (this.equalz(agent)) { return true; } } return false; } public final void addAllStates(Agent agent) { for (AbstractSite aSite : this.getSitesMap().values()) aSite.addStates(agent.getSiteByName(aSite.getName())); } public final void addAllStates(AbstractAgent agent) { for (AbstractSite aSite : this.getSitesMap().values()) aSite.addStates(agent.getSiteByName(aSite.getName())); } public final AbstractAgent summon(AbstractAgent agent) { AbstractAgent sum = new AbstractAgent(name); sum.sitesMap = new LinkedHashMap<String, AbstractSite>(); for (Map.Entry<String, AbstractSite> entry : agent.getSitesMap() .entrySet()) { AbstractSite newSite = entry.getValue().clone(); sum.sitesMap.put(entry.getKey(), newSite); } for (Map.Entry<String, AbstractSite> entry : this.getSitesMap() .entrySet()) { if (sum.sitesMap.get(entry.getKey()) == null) { AbstractSite newSite = entry.getValue().clone(); sum.sitesMap.put(entry.getKey(), newSite); } } return sum; } /** * This method checks possibility create injections. * * @param agentIn * given agent for checks * @return <tt>true</tt> if given agent fit to current agent, otherwise * <tt>false</tt> */ public final boolean isFit(AbstractAgent agentIn) { if (!this.name.equals(agentIn.getName())) return false; for (AbstractSite site : sitesMap.values()) { AbstractSite siteIn = agentIn.getSiteByName(site.getName()); if (siteIn == null) return false; if (!site.isFit(siteIn)) return false; } return true; } // TODO Please rename it public final boolean isFitTwo(AbstractAgent agentIn) { if (!this.name.equals(agentIn.getName())) return false; for (AbstractSite site : sitesMap.values()) { AbstractSite siteIn = agentIn.getSiteByName(site.getName()); if (siteIn == null) return false; if (!siteIn.isFit(site)) return false; } return true; } public final String toStringForXML() { StringBuffer sb = new StringBuffer(getName() + "("); boolean first = true; for (AbstractSite site : sitesMap.values()) { if (!first) { sb.append(","); } else { first = false; } sb.append(site.getName()); if (!site.getInternalState().hasDefaultName()) { sb.append("~" + site.getInternalState().getName()); } AbstractLinkState linkState = site.getLinkState(); if (!linkState.getAgentName().equals(Agent.DEFAULT_NAME)) { sb.append("!"); sb.append(linkState.getAgentName()); sb.append("."); sb.append(linkState.getConnectedSiteName()); } } sb.append(")"); return sb.toString(); } @Override public final String toString() { String st = getName(); return st; } @Override public final AbstractAgent clone() { return new AbstractAgent(this); } @Override protected String getDefaultName() { return DEFAULT_NAME; } }