package com.sap.furcas.runtime.textblocks.validation;
import static com.sap.furcas.runtime.textblocks.TbNavigationUtil.getSubNodes;
import static com.sap.furcas.runtime.textblocks.TbUtil.getAbsoluteOffset;
import java.util.Iterator;
import java.util.List;
import com.sap.furcas.metamodel.FURCAS.textblocks.AbstractToken;
import com.sap.furcas.metamodel.FURCAS.textblocks.Bostoken;
import com.sap.furcas.metamodel.FURCAS.textblocks.DocumentNode;
import com.sap.furcas.metamodel.FURCAS.textblocks.Eostoken;
import com.sap.furcas.metamodel.FURCAS.textblocks.TextBlock;
import com.sap.furcas.runtime.textblocks.TbUtil;
import com.sap.furcas.runtime.textblocks.model.TextBlocksModel;
public class TbValidationUtil {
public static void assertTextBlockConsistency(TextBlock currentTextBlock) {
if (currentTextBlock.getOffset() < 0) {
throw new IllegalTextBlocksStateException("TextBlock offset is negative: " + currentTextBlock.getOffset(), currentTextBlock);
}
if (currentTextBlock.getLength() < 0) {
throw new IllegalTextBlocksStateException("TextBlock length is negative: " + currentTextBlock.getOffset(), currentTextBlock);
}
List<? extends DocumentNode> subnodes = getSubNodes(currentTextBlock);
int lastEnd = getAbsoluteOffset(currentTextBlock); // implicitly checks for offset < 0
int tokenLengthSum = 0;
for (Iterator<? extends DocumentNode> iterator = subnodes.iterator(); iterator.hasNext();) {
DocumentNode documentNode = iterator.next();
int nodeOffSet = getAbsoluteOffset(documentNode);
tokenLengthSum += documentNode.getLength();
if (documentNode.getLength() < 0 ) {
if (! (documentNode instanceof Bostoken) && ! (documentNode instanceof Eostoken) ) {
throw new IllegalTextBlocksStateException("Subnode of length < 0 in block: " + documentNode, currentTextBlock);
}
}
if ( nodeOffSet > lastEnd ) {
// if(! (documentNode instanceof Eostoken) ) {
throw new IllegalTextBlocksStateException("TextBlock with gap between subnodes created : " + lastEnd +" after " + nodeOffSet, currentTextBlock);
// }
}
if (nodeOffSet < lastEnd ) {
// if (! (documentNode instanceof Eostoken) ) {
throw new IllegalTextBlocksStateException("TextBlock with overlapping subnodes created : " + nodeOffSet +" before " + lastEnd, currentTextBlock);
// }
}
lastEnd = nodeOffSet + documentNode.getLength();
}
if (tokenLengthSum != currentTextBlock.getLength()) {
throw new IllegalTextBlocksStateException("TextBlock length " + currentTextBlock.getLength() + " != "+ tokenLengthSum, currentTextBlock);
}
}
public static void assertTextBlockConsistencyRecursive(TextBlock currentTextBlock) {
for(DocumentNode subNode : currentTextBlock.getSubNodes()) {
if (subNode instanceof TextBlock) {
assertTextBlockConsistencyRecursive((TextBlock) subNode);
}
}
assertTextBlockConsistency(currentTextBlock);
}
public static void assertCacheIsUpToDate(TextBlock rootBlock) {
TextBlocksModel model = new TextBlocksModel(rootBlock);
model.setUsecache(true);
String cached = model.get(0, model.getLength());
model.setUsecache(false);
String uncached = model.get(0, model.getLength());
if (!cached.equals(uncached)) {
System.out.println("Uncached");
System.out.println(uncached);
System.out.println("Cached");
System.out.println(cached);
throw new IllegalTextBlocksStateException("TextBlock and its cache are not in Sync", rootBlock);
}
}
public static boolean hasGap(AbstractToken abstractToken, TextBlock currentTextBlock) {
return (TbUtil.getAbsoluteOffset(abstractToken) + abstractToken.getLength()) != TbUtil.getAbsoluteOffset(currentTextBlock);
}
}