package jcircus.parallelism;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Vector;
import jcircus.newutil.ChanSetUtil;
import jcircus.newutil.ChannelUtil;
import jcircus.newutil.ExceptionUtil;
import jcircus.newutil.FactoryUtil;
import jcircus.newutil.ProcessUtil;
import net.sourceforge.czt.circus.ast.Action1;
import net.sourceforge.czt.circus.ast.Action2;
import net.sourceforge.czt.circus.ast.ActionPara;
import net.sourceforge.czt.circus.ast.AlphabetisedParallelProcess;
import net.sourceforge.czt.circus.ast.BasicProcess;
import net.sourceforge.czt.circus.ast.CallAction;
import net.sourceforge.czt.circus.ast.CallProcess;
import net.sourceforge.czt.circus.ast.CircusAction;
import net.sourceforge.czt.circus.ast.CircusProcess;
import net.sourceforge.czt.circus.ast.ExtChoiceProcess;
import net.sourceforge.czt.circus.ast.IntChoiceProcess;
import net.sourceforge.czt.circus.ast.InterleaveAction;
import net.sourceforge.czt.circus.ast.InterleaveProcess;
import net.sourceforge.czt.circus.ast.ParallelProcess;
import net.sourceforge.czt.circus.ast.PrefixingAction;
import net.sourceforge.czt.circus.ast.Process1;
import net.sourceforge.czt.circus.ast.Process2;
import net.sourceforge.czt.circus.ast.ProcessPara;
import net.sourceforge.czt.circus.ast.SeqProcess;
import net.sourceforge.czt.circus.util.Factory;
import net.sourceforge.czt.z.ast.AxPara;
import net.sourceforge.czt.z.ast.NarrSect;
import net.sourceforge.czt.z.ast.Para;
import net.sourceforge.czt.z.ast.Spec;
import net.sourceforge.czt.z.ast.ZName;
import net.sourceforge.czt.z.ast.ZNameList;
import net.sourceforge.czt.z.ast.ZParaList;
import net.sourceforge.czt.z.ast.ZSect;
public class CopyUpdater {
private HashMap <String, Boolean> needsToBeUpdated = new LinkedHashMap <String, Boolean> ();
public void updateNeedsToBeUpdated (ZParaList paras, Spec spec) {
for (int i = 0; i < paras.size(); i++) {
if (paras.get(i) instanceof ProcessPara) {
ProcessPara para = (ProcessPara) paras.get(i); //Aqui vai invocar os visitadores dos paragrafos que nao forem narrativos (com texto), ou de tags de Latex
CircusProcess process = para.getCircusProcess();
if (process instanceof InterleaveProcess) {
CircusProcess procLeft = ((InterleaveProcess)process).getLeftProcess();
CircusProcess procRight = ((InterleaveProcess)process).getRightProcess();
Vector <String> visibleLeft = ChannelUtil.getVisibleChannels (procLeft, spec);
Vector <String> visibleRight = ChannelUtil.getVisibleChannels (procRight, spec);
if (FriendshipSets.intersection (visibleLeft, visibleRight).size() > 0) {
needsToBeUpdated.put(para.getZName().toString(), true);
}
}
else if (process instanceof ParallelProcess) {
CircusProcess procLeft = ((ParallelProcess)process).getLeftProcess();
CircusProcess procRight = ((ParallelProcess)process).getRightProcess();
Vector <String> visibleLeft = ChannelUtil.getVisibleChannels (procLeft, spec);
Vector <String> visibleRight = ChannelUtil.getVisibleChannels (procRight, spec);
Vector <String> channelSet = ChanSetUtil.channelSet(process, spec);
if (FriendshipSets.forcedInter (visibleLeft, visibleRight, channelSet).size() > 0) {
needsToBeUpdated.put(para.getZName().toString(), true);
}
}
else {
needsToBeUpdated.put(para.getZName().toString(), false);
}
}
}
}
public void updateSpec (Spec spec) {
ZSect zSect;
if (spec.getSect().get(0) instanceof NarrSect)
zSect = (ZSect) spec.getSect().get(1);
else
zSect = (ZSect) spec.getSect().get(0);
ZParaList paras = /*(ZParaList)*/ zSect.getZParaList();
updateNeedsToBeUpdated (paras, spec);
for (int i = 0; i < paras.size(); i++) {
if (paras.get(i) instanceof ProcessPara) {
ProcessPara para = (ProcessPara) paras.get(i); //Aqui vai invocar os visitadores dos paragrafos que nao forem narrativos (com texto), ou de tags de Latex
updateProcessPara (paras, para, spec);
}
}
System.out.print ("");
}
private void updateProcessPara (ZParaList paraList, ProcessPara para, Spec spec) {
CircusProcess proc = para.getCircusProcess();
ZNameList nameList = (ZNameList) para.getGenFormals();
String name = para.getZName().toString();
if (needsToBeUpdated.get(name) != null) {
if (needsToBeUpdated.get(name).equals(true))
updateCircusProcess (paraList, proc, name, spec, nameList, false);
}
}
private void renameProcess (CircusProcess process, String prefixName) {
if (process instanceof Process2) {
renameProcess (((Process2)process).getLeftProcess(), prefixName);
renameProcess (((Process2)process).getRightProcess(), prefixName);
}
else if (process instanceof Process1) {
renameProcess (((Process1)process).getCircusProcess(), prefixName);
}
else if (process instanceof CallProcess) {
Factory f = new Factory ();
String previousName = ((CallProcess)process).getCallExpr().getZName().toString();
((CallProcess)process).getCallExpr().setName(f.createZName(prefixName + previousName));
}
else {
//ExceptionUtil.throwException("Please implement an else if for " + process.getClass());
ExceptionUtil.throwImplementationException("CopyUpdater.renameProcess", process.getClass());
}
}
private boolean containsProcessPara (String name, ZParaList paraList) {
for (int i = 0; i < paraList.size(); i++) {
Para para = paraList.get(i);
if (para instanceof ProcessPara) {
ProcessPara procPara = (ProcessPara)para;
if (procPara.getZName().toString().equals(name))
return true;
}
}
return false;
}
private void updateCircusProcess (ZParaList paraList, CircusProcess process, String nameOfPreviousProcess, Spec spec, ZNameList genFormals, boolean addCopy) {
Factory f = new Factory ();
FactoryUtil pf = new FactoryUtil ();
if (process instanceof Process2) {
Process2 process2 = (Process2) process;
if (process2.getAnn(CopyCallAnn.class) == null) {
updateCircusProcess (paraList, process2.getLeftProcess(), nameOfPreviousProcess, spec, genFormals, true);
updateCircusProcess (paraList, process2.getRightProcess(), nameOfPreviousProcess, spec, genFormals, true);
}
process2.getAnns().add(new CopyCallAnn());
System.out.print("");
}
else if (process instanceof CallProcess) {
ProcessPara processPara = f.createProcessPara();
processPara.setCircusProcess(ProcessUtil.getContentOfCallProcess (process, spec));
String nameOfCallProcess = ((CallProcess)process).getCallExpr().getZName().toString();
renameProcess ((CallProcess)process, nameOfPreviousProcess);
processPara.setName(f.createZName(nameOfPreviousProcess + nameOfCallProcess));
processPara.setGenFormals (genFormals);
updateCircusProcess (paraList, processPara.getCircusProcess(), nameOfPreviousProcess/* + nameOfCallProcess*/, spec, genFormals, true);
if (!containsProcessPara (nameOfPreviousProcess + nameOfCallProcess, paraList)) {
processPara.getAnns().add(new CopyProcessAnn());
addProcessPara2ParaList (processPara, paraList);
nameOfPreviousProcess += nameOfCallProcess;
addCopy = false;
System.out.print ("");
}
}
else {}
}
private void addProcessPara2ParaList (ProcessPara para, ZParaList paraList) {
Factory f = new Factory ();
boolean aux = false;
boolean stop = false;
int size = paraList.size();
int i = size - 1;
int j = 0;
while (!stop) {
Para p = paraList.get(j);
if (p instanceof ProcessPara) {
stop = true;
}
j++;
}
j-=3;
while (!aux) {
Para p = paraList.get(i);
if (p instanceof ProcessPara) {
paraList.add(size - j - 1, para);
aux = true;
}
j++;
i--;
}
}
public void copyProcessPara (ZSect zSect, ProcessPara processPara) {
FactoryUtil pf = new FactoryUtil ();
String name = processPara.getZName().toString();
Factory f = new Factory ();
ProcessPara copyOfProcessPara = f.createProcessPara();
copyOfProcessPara.setName(f.createZName(name));
copyOfProcessPara.setCircusProcess(copyCircusProcess (processPara.getCircusProcess(), name));
zSect.getZParaList().add(copyOfProcessPara);
}
private CircusProcess copyCircusProcess (CircusProcess cp, String nameOfCircusProcessToBeCopied) {
FactoryUtil pf = new FactoryUtil ();
return pf.createCircusProcess (cp);
/*if (cp instanceof BasicProcess) {
return cloneBasicProcess ((BasicProcess)cp);
}
else if (cp instanceof CallProcess) {
CallProcess call = f.createCallProcess();
call.setActuals(((CallProcess)cp).getActuals());
call.setUsage(((CallProcess)cp).getUsage());
call.setCallExpr(((CallProcess)cp).getCallExpr());
return call;
}
else if (cp instanceof Process2) {
if (cp instanceof ParallelProcess) {
ParallelProcess cp2 = (ParallelProcess)cp;
ParallelProcess parallelProcess = f.createParallelProcess();
parallelProcess.setChannelSet (cp2.getChannelSet());
parallelProcess.setLeftProcess(cloneCircusProcess (cp2.getLeftProcess()));
parallelProcess.setRightProcess(cloneCircusProcess (cp2.getRightProcess()));
return parallelProcess;
}
else if (cp instanceof AlphabetisedParallelProcess) {
AlphabetisedParallelProcess cp2 = (AlphabetisedParallelProcess)cp;
AlphabetisedParallelProcess parallelProcess = f.createAlphabetisedParallelProcess();
parallelProcess.setLeftAlpha (cp2.getLeftAlpha());
parallelProcess.setRightAlpha (cp2.getRightAlpha());
parallelProcess.setLeftProcess(cloneCircusProcess (cp2.getLeftProcess()));
parallelProcess.setRightProcess(cloneCircusProcess (cp2.getRightProcess()));
return parallelProcess;
}
else if (cp instanceof InterleaveProcess) {
InterleaveProcess cp2 = (InterleaveProcess)cp;
InterleaveProcess interleaveProcess = f.createInterleaveProcess();
interleaveProcess.setLeftProcess(cloneCircusProcess (cp2.getLeftProcess()));
interleaveProcess.setRightProcess(cloneCircusProcess (cp2.getRightProcess()));
return interleaveProcess;
}
else if (cp instanceof ExtChoiceProcess) {
ExtChoiceProcess cp2 = (ExtChoiceProcess)cp;
ExtChoiceProcess extchoiceProcess = f.createExtChoiceProcess();
extchoiceProcess.setLeftProcess(cloneCircusProcess (cp2.getLeftProcess()));
extchoiceProcess.setRightProcess(cloneCircusProcess (cp2.getRightProcess()));
return extchoiceProcess;
}
else if (cp instanceof IntChoiceProcess) {
IntChoiceProcess cp2 = (IntChoiceProcess)cp;
IntChoiceProcess intchoiceProcess = f.createIntChoiceProcess();
intchoiceProcess.setLeftProcess(cloneCircusProcess (cp2.getLeftProcess()));
intchoiceProcess.setRightProcess(cloneCircusProcess (cp2.getRightProcess()));
return intchoiceProcess;
}
else if (cp instanceof SeqProcess) {
SeqProcess cp2 = (SeqProcess)cp;
SeqProcess seqProcess = f.createSeqProcess();
seqProcess.setLeftProcess(cloneCircusProcess (cp2.getLeftProcess()));
seqProcess.setRightProcess(cloneCircusProcess (cp2.getRightProcess()));
return seqProcess;
}
}*/
}
}