private boolean unknown(XMLGraph g) {
return g != null && g.isUnknown();
}
public XMLGraph transferCopy(final CopyStm s, final XMLGraph base, XMLGraph firstattr, XMLGraph firstchild, XMLGraph nextnode) {
XMLGraph g = base.clone();
if (base.isUnknown() || unknown(firstattr) || unknown(firstchild) || unknown(nextnode)) {
g.setUnknown();
return g;
}
restoreEdges(stm_nodes.getCopyLeftChoice(s, g), g);
switch (s.getKind()) {
case ELEMENT:
stm_nodes.getCopyElementNode(s, g).setName(getFirstElementNames(base), g);
restoreEdges(stm_nodes.getCopyElementNode(s, g).getContent(), g);
if (firstattr != null) {
g.merge(firstattr);
stm_nodes.getCopyFirstAttribute(s, g).setContent(firstattr.getRoots(), g);
}
if (firstchild != null) {
g.merge(firstchild);
stm_nodes.getCopyFirstChild(s, g).setContent(firstchild.getRoots(), g);
}
if (nextnode != null) {
g.merge(nextnode);
stm_nodes.getCopyNextNode(s, g).setContent(nextnode.getRoots(), g);
}
g.getRoots().clear();
g.getRoots().add(stm_nodes.getCopyTopNode(s, g).getIndex());
break;
case COMMENT:
case PROCESSINGINSTRUCTION:
g = nextnode.clone();
break;
case ATTRIBUTE:
case ATTRNODE:
case ATTRIBUTEGAP:
case TEMPLATEGAP:
case TEMPNODE:
case TEXT:
ChoiceNode left = stm_nodes.getCopyLeftChoice(s, g);
final LinkedHashSet<Integer> leftContent = new LinkedHashSet<Integer>();
if (nextnode != null) {
g.merge(nextnode);
g.getRoots().clear();
g.getRoots().add(stm_nodes.getCopyTopNode(s, g).getIndex());
stm_nodes.getCopyNextNode(s, g).setContent(nextnode.getRoots(), g);
}
apply(base, new CachedNodeProcessor<EPresence>() {
@Override
public EPresence cycle() {
return EPresence.UNKNOWN;
}
@Override
public EPresence process(AttributeNode n) {
leftContent.add(n.getIndex());
//addChild(left, n.getIndex(), g);
//left.getContents().add(n.getIndex());
return EPresence.NONEMPTY;
}
@Override
public EPresence process(ElementNode n) {
return EPresence.BOTTOM;
}
@Override
public EPresence process(OneOrMoreNode n) {
return base.getNode(n.getContent()).process(this);
}
@Override
public EPresence process(TextNode n) {
if (s.getKind() == CopyStm.Kind.TEXT) {
if (n.getText().isEmpty())
return EPresence.BOTTOM;
leftContent.add(n.getIndex());
//addChild(left, child, g)
//left.getContents().add(n.getIndex());
if (n.getText().isEmptyString())
return EPresence.EMPTY;
else if (n.getText().run(""))
return EPresence.UNKNOWN;
else
return EPresence.NONEMPTY;
}
return EPresence.BOTTOM;
}
@Override
public EPresence process(ChoiceNode n) {
EPresence p = EPresence.BOTTOM;
if (n.isGap() && n.isOpen()) {
if (base.getOpenAttributeGaps().contains(n.getName()) || base.getOpenTemplateGaps().contains(n.getName())) {
//left.getContents().add(n.getIndex());
leftContent.add(n.getIndex());
p = EPresence.UNKNOWN;
}
}
for (int child : n.getContents()) {
p = p.leastUpperBound(base.getNode(child).process(this));
}
return p;
}
@Override
public EPresence process(SequenceNode n) {
EPresence p = EPresence.EMPTY;
for (int child : n.getContents()) {
p = p.concat(base.getNode(child).process(this));
if (p.definitelyNonEmpty())
break;
}
return p;
}
@Override
public EPresence process(InterleaveNode n) {
EPresence p = EPresence.BOTTOM;
for (int child : n.getContents()) {
p = p.leastUpperBound(base.getNode(child).process(this));
}
return p;
}
});
left.setContent(leftContent, g);
//left.getContents().addAll(base.getRoots());
break;
default:
throw new RuntimeException("unexpected copy type " + s.getKind());
}
g.sharpen();
return g;
}