package dk.brics.xact.analysis.xmlgraph;
import java.util.ArrayList;
import java.util.List;
import dk.brics.automaton.Automaton;
import dk.brics.xmlgraph.AttributeNode;
import dk.brics.xmlgraph.ChoiceNode;
import dk.brics.xmlgraph.ElementNode;
import dk.brics.xmlgraph.InterleaveNode;
import dk.brics.xmlgraph.MultiContentNode;
import dk.brics.xmlgraph.Node;
import dk.brics.xmlgraph.OneOrMoreNode;
import dk.brics.xmlgraph.SequenceNode;
import dk.brics.xmlgraph.TextNode;
import dk.brics.xmlgraph.XMLGraph;
/**
* Determines for a given node the possible strings that can occur as text there.
* Occurrences of elements and attributes are treated as text nodes with the empty language.
*/
public class TextProcessor {
XMLGraph graph;
final public Automaton apply(XMLGraph g, Node node) {
graph = g;
Automaton result = node.process(proc);
return result;
}
final public Automaton apply(XMLGraph g) {
graph = g;
Automaton result = Automaton.makeEmpty();
for (int root : g.getRoots()) {
Node node = g.getNode(root);
Automaton c = node.process(proc);
result = result.union(c);
}
return result;
}
private Processor proc = new Processor();
private class Processor extends CachedNodeProcessor<Automaton> {
@Override
public Automaton cycle() {
return Automaton.makeAnyString();
}
@Override
public Automaton process(AttributeNode n) {
return Automaton.makeEmpty();
}
@Override
public Automaton process(ElementNode n) {
return Automaton.makeEmpty();
}
@Override
public Automaton process(TextNode n) {
return n.getText();
}
@Override
public Automaton process(ChoiceNode n) {
return choiceOrInterleave(n);
}
@Override
public Automaton process(InterleaveNode n) {
return choiceOrInterleave(n);
}
private Automaton choiceOrInterleave(MultiContentNode n) {
List<Automaton> autos = new ArrayList<Automaton>();
for (int child : n.getContents()) {
autos.add(graph.getNode(child).process(this));
}
Automaton result = Automaton.union(autos);
if (n instanceof InterleaveNode)
result = result.repeat(1);
return result;
}
@Override
public Automaton process(SequenceNode n) {
List<Automaton> autos = new ArrayList<Automaton>();
for (int child : n.getContents()) {
autos.add(graph.getNode(child).process(this));
}
Automaton result = Automaton.concatenate(autos);
return result;
}
@Override
public Automaton process(OneOrMoreNode n) {
Automaton result = graph.getNode(n.getContent()).process(this).repeat(1);
return result;
}
}
}