* make all internal elements known to the internal accounting these may be process references and in the future
* also inner process definitions
*/
if(subprocesses!=null)
for(ParserVal val:subprocesses.inner){
NamedSource el;
if(usedNames.contains(val.getText()))
throw new IllegalArgumentException("Process "+name+" contains repeated element name "
+val.getText());
if(val instanceof ProcessRef){
ProcessRef r=((ProcessRef)val);
// TODO find the corresponding process, if it is not a primitive. Should be done during parsing?
if(r.process==null){
if(r.localName==null)
throw new IllegalStateException("no process set for anonymous reference");
throw new IllegalStateException("no process set for reference "+r.localName);
}
el=r.process.createTemplate();
usedNames.add(r.localName);
subprocessMap.put(val.getText(), (Process)el);
subrefMap.put(val.getText(), r);
subs.put(val.getText(), el);
break; // do not insert it into subprocess map
}
// TODO: allow inner process definitions
throw new IllegalArgumentException("Element "+val.getText()+" contained in element "
+getText()
+" is not of suitable type (must be process reference) in "+filename+", line "+line);
}
// TODO: now that we know all sub elements, iterate once again over them, and connect
// their inputs. All connection counterparts, except for formulas, must be available now.
// For formulas, anonymous subprocesses must be created on the fly and
// get their inputs directly fed.
for(String ename:subs.keySet()){
// iterate over all subprocesses and subprocess references and connect their inputs
NamedSource val=subs.get(ename);
if(val instanceof ProcessRef){
ProcessRef r=(ProcessRef)val;
Process p=subprocessMap.get(r.localName);
if(r.getInputAssignments()!=null)
for(InputAssignment i:r.getInputAssignments().getAssignments()){
// now for each input of the subprocess, check if there is an assignment
if(i.getInputName()==null||i.getInputName().length()==0)
continue;
// first, get the destination index to which to connect to
Parameter dest=p.namedInputs.get(i.getInputName());
// then for each assignment, check if there is an input, and set the connection
if(i.getFormula()==null){
// this input of the sub element stays open, so ignore it
}else{
SourceStore sst=getAsSource(i.getFormula());
p.setSource(dest.i, sst.source, sst.sourceIndex);
}
}
}else if(val instanceof Process){
throw new IllegalArgumentException("Found process "+val.getAbstractName()+" where a processreference was expected - nested process definitions not yet implemented");
}else
// don't expect that here.
throw new IllegalArgumentException("Found symbol "+val.getAbstractName()+" where a processreference was expected");
}
// connect all variables to their value sources
if(variables!=null)
for(ParserVal val:variables.inner){
Variable v=containedVariables.get(val.getText());
SourceStore sst=getAsSource(val.inner.get(0));
v.setSource(0, sst.source, sst.sourceIndex);
}
// after all internal elements are connected, fix the connections of the outputs.
// here also, create anonymous subprocesses if applicable.
for(ParserVal val:outputs.inner){
if(usedNames.contains(val.getText()))
throw new IllegalArgumentException("Process "+name+" contains repeated output name "
+val.getText());
namedOutputs.put(val.getText(), new Parameter(val.getText(), nameCount));
// TODO will we ever have process definitions with outputs other than STREAM?
sourceTypes.put(nameCount, ValueType.STREAM);
sourceMap.put(nameCount, getAsSource(val));
usedNames.add(val.getText());
nameCount++;
}
@SuppressWarnings("unused")
Process process=new Process();