public static TreebankNode insertAnnotationNode(JCas jcas, TopTreebankNode root, Annotation arg1, String nodeType) {
// tree did not match the arg exactly, so if possible we'll insert a node in the tree here that
// is under tree but above its children. So we'll try to find the start and end child that this
// arg covers if possible.
TreebankNode tree = root;
TreebankNode lastTree = null; //tree;
do{
lastTree = tree;
// only continue downward traversal if we are not at a POS node...
// if(tree.getChildren().size() > 1 || tree.getChildren(0).getChildren() != null){
if(!tree.getLeaf()){
for(int i = 0; i < tree.getChildren().size(); i++){
TreebankNode child = tree.getChildren(i);
if(child.getBegin() <= arg1.getBegin() && child.getEnd() >= arg1.getEnd()){
tree = child;
break; // break out of inner for-loop
}
}
}
}while(tree != lastTree);
TreebankNode newTree = null;
if(tree.getBegin() == arg1.getBegin() && tree.getEnd() == arg1.getEnd()){
while(tree.getParent() != null && tree.getParent().getBegin() == arg1.getBegin() && tree.getParent().getEnd() == arg1.getEnd()){
tree = tree.getParent();
}
// matches a node in tree, just insert one above it
newTree = new TreebankNode(jcas, tree.getBegin(), tree.getEnd());
newTree.setNodeType(nodeType);
newTree.setChildren(new FSArray(jcas, 1));
newTree.setChildren(0, tree);
newTree.setParent(tree.getParent());
TreeUtils.replaceChild(tree.getParent(), tree, newTree);
tree.setParent(newTree);
// newTree.setNodeType(tree.getNodeType());
// newTree.setChildren(tree.getChildren());
// newTree.setParent(tree);
// tree.setNodeType(nodeType);
// tree.setChildren(new FSArray(jcas, 1));
// tree.setChildren(0,newTree);
// newTree = tree;
}else{
// mismatch
int startChild = -1;
int endChild = -1;
if(!tree.getLeaf()){
// it can happen that the tree here is a terminal (pos tag:word) and thus has no children, in the case that the gold
// standard entities are tokenized correctly and the tokenizer is wrong. With automatic tokens and entities this shouldn't happen.
for(int i = 0; i < tree.getChildren().size(); i++){
if(startChild == -1){
if(tree.getChildren(i).getBegin() == arg1.getBegin()){
startChild = i;
}
}else if(tree.getChildren(i).getEnd() == arg1.getEnd()){
endChild = i;
break;
}
}
}
// here is where we insert if possible
if(startChild >= 0 && endChild >= 0){
newTree = new TreebankNode(jcas, tree.getChildren(startChild).getBegin(), tree.getChildren(endChild).getEnd());
newTree.setNodeType(nodeType);
newTree.setParent(tree);
int numStolenChildren = endChild-startChild+1;
newTree.setChildren(new FSArray(jcas, numStolenChildren));
// add new children to new intermediate node
for(int i = startChild; i <= endChild; i++){
newTree.setChildren(i-startChild, tree.getChildren(i));
}
// create new children array for top node (tree)
FSArray children = new FSArray(jcas, tree.getChildren().size() - numStolenChildren + 1);
for(int i = 0; i < startChild; i++){
children.set(i, tree.getChildren(i));
}
children.set(startChild, newTree);
for(int i = endChild+1; i < tree.getChildren().size(); i++){
children.set(i-numStolenChildren+1, tree.getChildren(i));
}
tree.setChildren(children);
}else{
// just put above here...
newTree = new TreebankNode(jcas, tree.getBegin(), tree.getEnd());
newTree.setNodeType(nodeType);
newTree.setChildren(new FSArray(jcas, 1));
newTree.setChildren(0, tree);
newTree.setParent(tree.getParent());
TreeUtils.replaceChild(tree.getParent(), tree, newTree);
tree.setParent(newTree);
// newTree.setNodeType(tree.getNodeType());
// newTree.setChildren(tree.getChildren());
// newTree.setParent(tree);