Skip to content

Commit

Permalink
Process all of the container children, not just the steps
Browse files Browse the repository at this point in the history
  • Loading branch information
ndw committed Oct 24, 2021
1 parent e6026ed commit 9b1db21
Show file tree
Hide file tree
Showing 12 changed files with 127 additions and 163 deletions.
5 changes: 1 addition & 4 deletions src/main/scala/com/xmlcalabash/model/xml/Catch.scala
Expand Up @@ -58,10 +58,7 @@ class Catch(override val config: XMLCalabash) extends Container(config) with Nam
val start = parent.asInstanceOf[TryCatchStart]
val node = start.addCatch(stepName, codes.toList, containerManifold)
_graphNode = Some(node)

for (child <- children[Step]) {
child.graphNodes(runtime, _graphNode.get)
}
super.graphNodes(runtime, parent)
}

override def graphEdges(runtime: XMLCalabashRuntime, parent: Node): Unit = {
Expand Down
5 changes: 1 addition & 4 deletions src/main/scala/com/xmlcalabash/model/xml/Choose.scala
Expand Up @@ -178,10 +178,7 @@ class Choose(override val config: XMLCalabash) extends Container(config) {
val start = parent.asInstanceOf[ContainerStart]
val node = start.addChoose(stepName)
_graphNode = Some(node)

for (child <- children[Step]) {
child.graphNodes(runtime, node)
}
super.graphNodes(runtime, parent)
}

override def graphEdges(runtime: XMLCalabashRuntime, parent: Node): Unit = {
Expand Down
5 changes: 1 addition & 4 deletions src/main/scala/com/xmlcalabash/model/xml/ChooseBranch.scala
Expand Up @@ -136,10 +136,7 @@ class ChooseBranch(override val config: XMLCalabash) extends Container(config) w
val start = parent.asInstanceOf[ChooseStart]
val node = start.addWhen(testExpr, stepName, containerManifold)
_graphNode = Some(node)

for (child <- children[Step]) {
child.graphNodes(runtime, node)
}
super.graphNodes(runtime, parent)
}

override def graphEdges(runtime: XMLCalabashRuntime, parent: Node): Unit = {
Expand Down
230 changes: 116 additions & 114 deletions src/main/scala/com/xmlcalabash/model/xml/Container.scala
Expand Up @@ -168,143 +168,145 @@ class Container(override val config: XMLCalabash) extends Step(config) with Name
}

// Add ContentTypeCheckers and select filters if we need them
val innerEnv = lastStep.get.environment()
for (input <- children[DeclareInput]) {
if (input.select.isDefined) {
logger.debug(s"Adding select filter for container input ${stepName}/${input.port}: ${input.select.get}")
val context = staticContext.withStatics(inScopeStatics)

val ispec = if (input.sequence) {
XmlPortSpecification.ANYSOURCESEQ
} else {
XmlPortSpecification.ANYSOURCE
}
if (lastStep.isDefined) {
val innerEnv = lastStep.get.environment()
for (input <- children[DeclareInput]) {
if (input.select.isDefined) {
logger.debug(s"Adding select filter for container input ${stepName}/${input.port}: ${input.select.get}")
val context = staticContext.withStatics(inScopeStatics)

val ispec = if (input.sequence) {
XmlPortSpecification.ANYSOURCESEQ
} else {
XmlPortSpecification.ANYSOURCE
}

val params = new SelectFilterParams(context, input.select.get, input.port, ispec)
val filter = new AtomicStep(config, params)
filter.stepType = XProcConstants.cx_select_filter
val params = new SelectFilterParams(context, input.select.get, input.port, ispec)
val filter = new AtomicStep(config, params)
filter.stepType = XProcConstants.cx_select_filter

addChild(filter)
addChild(filter)

val finput = new WithInput(config)
finput.port = "source"
finput.primary = true
filter.addChild(finput)
val finput = new WithInput(config)
finput.port = "source"
finput.primary = true
filter.addChild(finput)

val foutput = new WithOutput(config)
foutput.port = "result"
foutput.primary = true
filter.addChild(foutput)
val foutput = new WithOutput(config)
foutput.port = "result"
foutput.primary = true
filter.addChild(foutput)

for (name <- staticContext.findVariableRefsInString(input.select.get)) {
var binding = _inScopeDynamics.get(name)
if (binding.isDefined) {
val npipe = new NamePipe(config, name, binding.get.tumble_id, binding.get)
filter.addChild(npipe)
} else {
binding = _inScopeStatics.get(name.getClarkName)
if (binding.isEmpty) {
throw new RuntimeException(s"Reference to variable not in scope: $name")
for (name <- staticContext.findVariableRefsInString(input.select.get)) {
var binding = _inScopeDynamics.get(name)
if (binding.isDefined) {
val npipe = new NamePipe(config, name, binding.get.tumble_id, binding.get)
filter.addChild(npipe)
} else {
binding = _inScopeStatics.get(name.getClarkName)
if (binding.isEmpty) {
throw new RuntimeException(s"Reference to variable not in scope: $name")
}
}
}
}

replumb(input, foutput)
replumb(input, foutput)

val newpipe = new Pipe(config)
newpipe.step = stepName
newpipe.port = input.port
newpipe.link = input
finput.addChild(newpipe)
}
val newpipe = new Pipe(config)
newpipe.step = stepName
newpipe.port = input.port
newpipe.link = input
finput.addChild(newpipe)
}

if (!MediaType.OCTET_STREAM.allowed(input.contentTypes)) {
logger.debug(s"Adding content-type-checker for container input ${stepName}/${input.port}")
val params = new ContentTypeCheckerParams(input.port, input.contentTypes, staticContext, None, inputPort = true, true)
val atomic = new AtomicStep(config, params)
atomic.stepType = XProcConstants.cx_content_type_checker
addChild(atomic)
if (!MediaType.OCTET_STREAM.allowed(input.contentTypes)) {
logger.debug(s"Adding content-type-checker for container input ${stepName}/${input.port}")
val params = new ContentTypeCheckerParams(input.port, input.contentTypes, staticContext, None, inputPort = true, true)
val atomic = new AtomicStep(config, params)
atomic.stepType = XProcConstants.cx_content_type_checker
addChild(atomic)

val winput = new WithInput(config)
winput.port = "source"
atomic.addChild(winput)
val winput = new WithInput(config)
winput.port = "source"
atomic.addChild(winput)

val woutput = new WithOutput(config)
woutput.port = "result"
atomic.addChild(woutput)
val woutput = new WithOutput(config)
woutput.port = "result"
atomic.addChild(woutput)

replumb(input, woutput)
replumb(input, woutput)

val newpipe = new Pipe(config)
newpipe.step = stepName
newpipe.port = input.port
newpipe.link = input
winput.addChild(newpipe)
val newpipe = new Pipe(config)
newpipe.step = stepName
newpipe.port = input.port
newpipe.link = input
winput.addChild(newpipe)
}
}
}

for (output <- children[DeclareOutput]) {
var check = false
//println(s"${stepName}, ${output.port}, ${output.contentTypes}")
for (binding <- output.children[Pipe]) {
val port = binding.port
val step = innerEnv.step(binding.step).get
val outputContentTypes = step match {
case atom: AtomicStep =>
val decl = atom.declaration(atom.stepType).get
decl.output(port, None).contentTypes
case cont: Container =>
if (cont._outputs.contains(port)) {
cont._outputs(port).contentTypes
} else {
// See if we can find a with-output for this port
var woutput = Option.empty[WithOutput]
for (wo <- cont.children[WithOutput]) {
if (wo.port == port) {
woutput = Some(wo)
}
}
if (woutput.isEmpty) {
// It must be implicit, so no checking is required
List(MediaType.OCTET_STREAM)
for (output <- children[DeclareOutput]) {
var check = false
//println(s"${stepName}, ${output.port}, ${output.contentTypes}")
for (binding <- output.children[Pipe]) {
val port = binding.port
val step = innerEnv.step(binding.step).get
val outputContentTypes = step match {
case atom: AtomicStep =>
val decl = atom.declaration(atom.stepType).get
decl.output(port, None).contentTypes
case cont: Container =>
if (cont._outputs.contains(port)) {
cont._outputs(port).contentTypes
} else {
woutput.get.contentTypes
// See if we can find a with-output for this port
var woutput = Option.empty[WithOutput]
for (wo <- cont.children[WithOutput]) {
if (wo.port == port) {
woutput = Some(wo)
}
}
if (woutput.isEmpty) {
// It must be implicit, so no checking is required
List(MediaType.OCTET_STREAM)
} else {
woutput.get.contentTypes
}
}
}
}
}

//println(s" ${step} / ${outputContentTypes}")
for (pct <- outputContentTypes) {
check = check || !pct.allowed(output.contentTypes)
//println(s" ${step} / ${outputContentTypes}")
for (pct <- outputContentTypes) {
check = check || !pct.allowed(output.contentTypes)
}
}
}

if (check) {
logger.debug(s"Adding content-type-checker for container output ${stepName}/${output.port}")
val params = new ContentTypeCheckerParams(output.port, output.contentTypes, staticContext, None, inputPort = false, true)
val atomic = new AtomicStep(config, params)
atomic.stepType = XProcConstants.cx_content_type_checker
addChild(atomic)

val winput = new WithInput(config)
winput.port = "source"
atomic.addChild(winput)

val pipes = ListBuffer.empty[Pipe] ++ output.children[Pipe]
for (oldpipe <- pipes) {
output.removeChild(oldpipe)
winput.addChild(oldpipe)
}
if (check) {
logger.debug(s"Adding content-type-checker for container output ${stepName}/${output.port}")
val params = new ContentTypeCheckerParams(output.port, output.contentTypes, staticContext, None, inputPort = false, true)
val atomic = new AtomicStep(config, params)
atomic.stepType = XProcConstants.cx_content_type_checker
addChild(atomic)

val winput = new WithInput(config)
winput.port = "source"
atomic.addChild(winput)

val pipes = ListBuffer.empty[Pipe] ++ output.children[Pipe]
for (oldpipe <- pipes) {
output.removeChild(oldpipe)
winput.addChild(oldpipe)
}

val woutput = new WithOutput(config)
woutput.port = "result"
atomic.addChild(woutput)
val woutput = new WithOutput(config)
woutput.port = "result"
atomic.addChild(woutput)

val newpipe = new Pipe(config)
newpipe.step = atomic.stepName
newpipe.port = "result"
newpipe.link = woutput
output.addChild(newpipe)
val newpipe = new Pipe(config)
newpipe.step = atomic.stepName
newpipe.port = "result"
newpipe.link = woutput
output.addChild(newpipe)
}
}
}
}
Expand Down
5 changes: 1 addition & 4 deletions src/main/scala/com/xmlcalabash/model/xml/Finally.scala
Expand Up @@ -36,10 +36,7 @@ class Finally(override val config: XMLCalabash) extends Container(config) with N
val start = parent.asInstanceOf[TryCatchStart]
val node = start.addFinally(stepName, containerManifold)
_graphNode = Some(node)

for (child <- children[Step]) {
child.graphNodes(runtime, _graphNode.get)
}
super.graphNodes(runtime, parent)
}

override def graphEdges(runtime: XMLCalabashRuntime, parent: Node): Unit = {
Expand Down
11 changes: 1 addition & 10 deletions src/main/scala/com/xmlcalabash/model/xml/ForEach.scala
Expand Up @@ -48,16 +48,7 @@ class ForEach(override val config: XMLCalabash) extends Container(config) with N
val start = parent.asInstanceOf[ContainerStart]
val node = start.addForEach(stepName, containerManifold)
_graphNode = Some(node)

for (child <- allChildren) {
child match {
case _: Step =>
child.graphNodes(runtime, node)
case _: Variable =>
child.graphNodes(runtime, node)
case _ => ()
}
}
super.graphNodes(runtime, parent)
}

override def graphEdges(runtime: XMLCalabashRuntime, parent: Node): Unit = {
Expand Down
5 changes: 1 addition & 4 deletions src/main/scala/com/xmlcalabash/model/xml/ForLoop.scala
Expand Up @@ -56,10 +56,7 @@ class ForLoop(override val config: XMLCalabash) extends ForContainer(config) wit
val start = parent.asInstanceOf[ContainerStart]
val node = start.addFor(stepName, countFrom, countTo, countBy, containerManifold)
_graphNode = Some(node)

for (child <- children[Step]) {
child.graphNodes(runtime, node)
}
super.graphNodes(runtime, parent)
}

override def graphEdges(runtime: XMLCalabashRuntime, parent: Node): Unit = {
Expand Down
5 changes: 1 addition & 4 deletions src/main/scala/com/xmlcalabash/model/xml/ForUntil.scala
Expand Up @@ -104,10 +104,7 @@ class ForUntil(override val config: XMLCalabash) extends ForContainer(config) wi
val start = parent.asInstanceOf[ContainerStart]
val node = start.addUntil(compare, returnSet=="all", stepName, containerManifold)
_graphNode = Some(node)

for (child <- children[Step]) {
child.graphNodes(runtime, node)
}
super.graphNodes(runtime, parent)
}

override def graphEdges(runtime: XMLCalabashRuntime, parent: Node): Unit = {
Expand Down
5 changes: 1 addition & 4 deletions src/main/scala/com/xmlcalabash/model/xml/ForWhile.scala
Expand Up @@ -106,10 +106,7 @@ class ForWhile(override val config: XMLCalabash) extends ForContainer(config) wi
val start = parent.asInstanceOf[ContainerStart]
val node = start.addWhile(tester, returnSet=="all", stepName, containerManifold)
_graphNode = Some(node)

for (child <- children[Step]) {
child.graphNodes(runtime, node)
}
super.graphNodes(runtime, parent)
}

override def graphEdges(runtime: XMLCalabashRuntime, parent: Node): Unit = {
Expand Down
4 changes: 1 addition & 3 deletions src/main/scala/com/xmlcalabash/model/xml/Group.scala
Expand Up @@ -33,9 +33,7 @@ class Group(override val config: XMLCalabash) extends Container(config) with Nam
_graphNode = Some(node)
}

for (child <- children[Step]) {
child.graphNodes(runtime, _graphNode.get)
}
super.graphNodes(runtime, parNode)
}

override def graphEdges(runtime: XMLCalabashRuntime, parent: Node): Unit = {
Expand Down
5 changes: 1 addition & 4 deletions src/main/scala/com/xmlcalabash/model/xml/Try.scala
Expand Up @@ -158,10 +158,7 @@ class Try(override val config: XMLCalabash) extends Container(config) with Named
val start = parent.asInstanceOf[ContainerStart]
val node = start.addTryCatch(stepName, containerManifold)
_graphNode = Some(node)

for (child <- children[Container]) {
child.graphNodes(runtime, node)
}
super.graphNodes(runtime, parent)
}

override def graphEdges(runtime: XMLCalabashRuntime, parent: Node): Unit = {
Expand Down
5 changes: 1 addition & 4 deletions src/main/scala/com/xmlcalabash/model/xml/Viewport.scala
Expand Up @@ -122,10 +122,7 @@ class Viewport(override val config: XMLCalabash) extends Container(config) with
val composer = new XMLViewportComposer(config, context, _match)
val node = start.addViewport(composer, stepName, containerManifold)
_graphNode = Some(node)

for (child <- children[Step]) {
child.graphNodes(runtime, node)
}
super.graphNodes(runtime, parent)

// The binding links we created earlier now need to be patched so that this
// is the node they go to.
Expand Down

0 comments on commit 9b1db21

Please sign in to comment.