if (g.isUnknown() || xmlsrc.isUnknown()) {
g.setUnknown();
return g;
}
final SequenceNode seq = stm_nodes.getInsertSequenceNode(s, g);
final ChoiceNode left;
final ChoiceNode right;
final TextNode text = stm_nodes.getInsertTextNode(s, g);
switch (s.getKind()) {
case APPEND:
case APPENDCONTENT:
case INSERTAFTER:
case SETATTRIBUTE:
left = makePrivate(stm_nodes.getInsertLeftSide(s, g), g);
right = makePrivate(stm_nodes.getInsertRightSide(s, g), g);
break;
case PREPEND:
case PREPENDCONTENT:
case INSERTBEFORE:
// SWAP left and right if prepending
left = makePrivate(stm_nodes.getInsertRightSide(s, g), g);
right = makePrivate(stm_nodes.getInsertLeftSide(s, g), g);
break;
default:
throw new RuntimeException("unknown insert kind");
}
text.replaceText(s.getStringSource(), g);
right.getContents().addAll(xmlsrc.getRoots());
right.getContents().add(text.getIndex());
switch (s.getKind()) {
case APPEND:
case PREPEND:
g.merge(xmlsrc);
left.getContents().addAll(base.getRoots());
g.getRoots().clear();
g.getRoots().add(seq.getIndex());
return g;
case SETATTRIBUTE:
case APPENDCONTENT: // this is both appendContent(XML) and appendContent(XPath,XML)
case PREPENDCONTENT:{
final StatusMap stm = evaluateXPathOrRoot(s.getXPath(), g);
boolean empty = checkXPathEmpty(s, g, stm);
if (empty)
return g;
g.merge(xmlsrc);
g.getRoots().retainAll(base.getRoots());
// TODO can we append as root here???
g.processReachableNodes(new NodeProcessor<Object>() {
@Override
public Object process(ElementNode n) {
ChoiceNode ch = (ChoiceNode)g.getNode(n.getContent());
switch (stm.get(n.getIndex())) {
case DEFINITE:
case ALL:
left.getContents().addAll(ch.getContents());
ch = makePrivate(ch, g);
if (g.getGapTypeMap().isEmpty()) {
ch.getContents().clear();
}
ch.getContents().add(seq.getIndex());
break;
case SOME:
case DONTKNOW:
ch = makePrivate(ch, g);
left.getContents().addAll(ch.getContents());
ch.getContents().add(seq.getIndex());
break;
case NONE:
case NEVER:
break;
}
return null;
}
});
g.sharpen();
return g;
}
case INSERTAFTER:
case INSERTBEFORE: {
final StatusMap stm = evaluateXPathOrRoot(s.getXPath(), g);
boolean empty = checkXPathEmpty(s, g, stm);
if (empty)
return g;
g.merge(xmlsrc);
g.getRoots().retainAll(base.getRoots());
g.processReachableNodes(new NodeProcessor<Object>() {
@Override
public Object process(ChoiceNode ch) {
LinkedHashSet<Integer> cs = new LinkedHashSet<Integer>(ch.getContents());
for (int child : ch.getContents()) {
Node node = g.getNode(child);
if (node instanceof ConcreteNode) {
switch (stm.get(child)) {
case ALL:
case DEFINITE:
if (g.getGapTypeMap().isEmpty()) {
cs.remove(child);
}
left.getContents().add(child);
cs.add(seq.getIndex());
break;
case SOME:
case DONTKNOW:
left.getContents().add(child);
cs.add(seq.getIndex());
break;
case NONE:
case NEVER:
break;
}
}
}
ch.setContent(cs, g);
return null;
}
});
g.sharpen();
return g;