package jcircus.environment; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.TreeMap; import java.util.Vector; import jcircus.exceptions.ChanUseUnificationException; import jcircus.exceptions.MoreThanOneWriterException; import jcircus.newutil.ChannelUtil; import jcircus.util.ChanUse; import net.sourceforge.czt.base.ast.ListTerm; import net.sourceforge.czt.circus.ast.ProcessPara; import net.sourceforge.czt.z.ast.Name; import net.sourceforge.czt.z.ast.Spec; import net.sourceforge.czt.z.ast.ZExprList; import net.sourceforge.czt.z.ast.ZNameList; /** * ChanUseEnv.java * * @author Angela Freitas */ public class ChanUseEnv { /** * Needs to be String because the key in TreeMap has to implement Comparable. * String (channelName) -> ChanUse */ private TreeMap treeMap_; /** * Constructor */ public ChanUseEnv() { this.treeMap_ = new TreeMap(); } /** * * @param channelName * @param javaType * @throws ChannelAlreadyDefinedException */ public void put(String channelName, ChanUse chanUse) { if (chanUse == null) throw new NullPointerException(); this.treeMap_.put(channelName.toString(), chanUse); } /** * * @param channelName * @return */ public ChanUse get(String channelName) { return treeMap_.get(channelName); } /** * * @param channelName */ public void remove(String channelName) { this.treeMap_.remove(channelName); } /** * * @return */ public int size() { return this.treeMap_.size(); } /** * * @param channelName * @return */ public boolean containsKey(String channelName) { return this.treeMap_.containsKey(channelName); } /** * * @param channelUseEnvironment * @throws ChannelAlreadyDefinedException */ private void putAll(ChanUseEnv channelUseEnvironment) { Iterator iterator = channelUseEnvironment.iteratorKeys(); String channelName; ChanUse javaTypeChannel; while(iterator.hasNext()) { channelName = iterator.next(); javaTypeChannel = channelUseEnvironment.get(channelName); this.put(channelName, javaTypeChannel); } } /** * * @param channelUseEnvironment */ public void removeAll(ChanUseEnv channelUseEnvironment) { Iterator iterator = channelUseEnvironment.iteratorKeys(); String channelName; while(iterator.hasNext()) { channelName = iterator.next(); this.remove(channelName); } } public ChanUseEnv merge(ChanUseEnv other, boolean isParallel) /*throws ChanUseUnificationException, MoreThanOneWriterException*/ { // Creates a new env, which will be returned ChanUseEnv r = new ChanUseEnv(); // Inserts all the channels of this env r.putAll(this); // Iterates over the second env Iterator iterator = other.iteratorKeys(); while(iterator.hasNext()) { String chanName = iterator.next(); ChanUse otherChanUse = other.get(chanName); ChanUse newChanUse = otherChanUse; // If the channel exists in both envs if (r.containsKey(chanName)) { ChanUse thisChanUse = r.get(chanName); if (isParallel) { // If this merge is a parallelism, permits if they are of // complementary types if (thisChanUse.equals(ChanUse.Input) && otherChanUse.equals(ChanUse.Output) || thisChanUse.equals(ChanUse.Output) && otherChanUse.equals(ChanUse.Input)) { // In this case the resulting type is mixed, to indicate // that it is used in a parallelism newChanUse = ChanUse.Mixed; // If they are equal } else if (otherChanUse.equals(thisChanUse)) { // The resulting remains the same newChanUse = otherChanUse; // If one is mixed and the other is input } else if (thisChanUse.equals(ChanUse.Mixed) && otherChanUse.equals(ChanUse.Input) || thisChanUse.equals(ChanUse.Input) && otherChanUse.equals(ChanUse.Mixed)) { // Remains mixed newChanUse = ChanUse.Mixed; // If one is mixed and the other is output } /*else if (thisChanUse.equals(ChanUse.Mixed) && otherChanUse.equals(ChanUse.Output) || thisChanUse.equals(ChanUse.Output) && otherChanUse.equals(ChanUse.Mixed)) { // Error because there is more than one writer in the // parallelism throw new MoreThanOneWriterException(); // If one is undefined and the other is input }*/ else if (thisChanUse.equals(ChanUse.Undefined) && otherChanUse.equals(ChanUse.Input) || thisChanUse.equals(ChanUse.Input) && otherChanUse.equals(ChanUse.Undefined)) { // Input newChanUse = ChanUse.Input; // If one is undefined and the other is output } else if (thisChanUse.equals(ChanUse.Undefined) && otherChanUse.equals(ChanUse.Output) || thisChanUse.equals(ChanUse.Output) && otherChanUse.equals(ChanUse.Undefined)) { // Output newChanUse = ChanUse.Output; // All other cases is a situation that I did not expected } else { // so throw an exception to find out what is happening! /*throw new ChanUseUnificationException( chanName, thisChanUse, otherChanUse);*/ } } else { // If this is not a composition of a parallelism, then we need // to have the same types if (otherChanUse.equals(thisChanUse)) { newChanUse = otherChanUse; } else { // throw new ChanUseUnificationException(chanName, thisChanUse, otherChanUse); } } }/*if (r.containsKey(chanName))*/ r.put(chanName, newChanUse); } return r; } /** * * @param newChannels * @param oldChannels * @return * @throws ChannelAlreadyDefinedException */ public ChanUseEnv substitute(ZExprList/*ListTerm*/ newChannels, ZNameList/*ListTerm*/ oldChannels) { ChanUseEnv r = new ChanUseEnv(); String channelName; String newChannelName; Name name; ChanUse javaType; int index; r.putAll(this); for (int i = 0; i < oldChannels.size(); i++) { name = (Name) oldChannels.get(i); newChannelName = ((Name) newChannels.get(i)).toString(); if (r.containsKey(name.toString())) { javaType = r.get(name.toString()); r.remove(name.toString()); r.put(newChannelName, javaType); } } return r; } /** * * @return */ public Iterator iteratorKeys() { return this.treeMap_.keySet().iterator(); } public Set keysFromMainAction (ProcessPara processPara, Spec spec) { Set keys = this.treeMap_.keySet(); Set keysFromMainAction = new HashSet (); Vector visibleChannelsFromMainAction = ChannelUtil.getVisibleChannelsFromMainAction(processPara, spec); keysFromMainAction.addAll(visibleChannelsFromMainAction); return keysFromMainAction; } public Iterator iteratorKeysFromMainAction (ProcessPara processPara, Spec spec) { return keysFromMainAction (processPara, spec).iterator(); } /** * */ public void print() { Iterator it = this.iteratorKeys(); System.out.println("---------------------------"); while(it.hasNext()) { String chanName = it.next(); ChanUse chanUse = this.get(chanName); System.out.println(chanName + " " + chanUse); } } }