blob: 36360c5a036d4b501479ae44a1a44e60fa203ae8 [file] [log] [blame]
package de.ids_mannheim.korap.response.match;
import de.ids_mannheim.korap.response.Match;
import de.ids_mannheim.korap.response.match.HighlightCombinatorElement;
import java.util.*;
import java.io.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/*
Public class for combining highlighting elements
*/
public class HighlightCombinator {
// Logger (use the Match class)
private final static Logger log = LoggerFactory.getLogger(Match.class);
// This advices the java compiler to ignore all loggings
public static final boolean DEBUG = false;
private LinkedList<HighlightCombinatorElement> combine;
private Stack<Integer> balanceStack = new Stack<>();
private Stack<Integer> tempStack = new Stack<>();
// Empty constructor
public HighlightCombinator () {
this.combine = new LinkedList<>();
};
// Return the combination list
public LinkedList<HighlightCombinatorElement> list () {
return this.combine;
};
// get the first element (without removing)
public HighlightCombinatorElement getFirst () {
return this.combine.getFirst();
};
// get the last element (without removing)
public HighlightCombinatorElement getLast () {
return this.combine.getLast();
};
// get an element by index (without removing)
public HighlightCombinatorElement get (int index) {
return this.combine.get(index);
};
// Get the size of the combinator stack
public short size () {
return (short) this.combine.size();
};
// Add primary data to the stack
public void addString (String characters) {
this.combine.add(new HighlightCombinatorElement(characters));
if (DEBUG) {
log.trace("Add string \"{}\" to stack", characters);
};
};
// Add opening highlight combinator to the stack
public void addOpen (int number) {
this.combine.add(new HighlightCombinatorElement((byte) 1, number));
this.balanceStack.push(number);
if (DEBUG)
log.trace("Add opening {} to stack", number);
};
// Add empty highlight to the stack
public void addEmpty (int pagenumber) {
this.combine.add(new HighlightCombinatorElement((byte) 3, pagenumber));
};
// Add closing highlight combinator to the stack
public void addClose (int number) {
HighlightCombinatorElement lastComb;
// Clean up temporary stack
this.tempStack.clear();
// Check if there is an opening tag at least
if (this.balanceStack.empty()) {
if (DEBUG)
log.trace("The balance stack is empty");
return;
};
// Just some debug information
if (DEBUG) {
StringBuilder sb = new StringBuilder(
"Stack for checking with number ");
sb.append(number).append(" is ");
for (int s : this.balanceStack) {
sb.append('[').append(s).append(']');
};
log.trace(sb.toString());
};
// class number of the last element
// It's already ensured the stack is not empty
int eold = this.balanceStack.pop();
// the closing element is not balanced, i.e. the last element differs
while (eold != number) {
// Retrieve last combinator on stack
lastComb = this.combine.peekLast();
if (DEBUG)
log.trace(
"Closing element is unbalanced - {} "
+ "!= {} with lastComb {}|{}|{}",
eold,
number,
lastComb.type,
lastComb.number,
lastComb.characters);
// combinator is opening and the number is not equal to the last
// element on the balanceStack
if (lastComb.type == 1 && lastComb.number == eold) {
// Remove the last element - it's empty and uninteresting!
this.combine.removeLast();
}
// Last element is empty
else if (lastComb.type == 3) {
log.error(
"The last element was empty -- and this is not correctly handled yet"
);
}
// combinator is either closing (??) or another opener
else {
if (DEBUG)
log.trace("close element a) {}", eold);
// Add a closer for the old element (this has following elements)
this.combine.add(
new HighlightCombinatorElement((byte) 2, eold, false));
};
// add this element number temporarily on the stack
tempStack.push(eold);
// There are no more elements on the balance stack
if (this.balanceStack.empty())
break;
// Check next element
eold = this.balanceStack.pop();
};
// Get last combinator on the stack
lastComb = this.combine.peekLast();
if (DEBUG) {
log.trace("Stack for checking 2: {}|{}|{}|{}", lastComb.type,
lastComb.number, lastComb.characters, number);
};
if (lastComb.type == 1 && lastComb.number == number) {
while (lastComb.type == 1 && lastComb.number == number) {
// Remove the damn thing - It's empty and uninteresting!
this.combine.removeLast();
lastComb = this.combine.peekLast();
};
}
else if (lastComb.type == 3) {
System.err.println("öööööööööööööööööööööööö");
}
else {
if (DEBUG)
log.trace("close element b) {}", number);
// Add a closer
this.combine.add(new HighlightCombinatorElement((byte) 2, number));
};
// Fetch everything from the tempstack and reopen it
for (int e : tempStack) {
if (DEBUG)
log.trace("Reopen element {}", e);
combine.add(new HighlightCombinatorElement((byte) 1, e));
balanceStack.push(e);
};
};
// Get all combined elements as a string
public String toString () {
StringBuilder sb = new StringBuilder();
for (HighlightCombinatorElement e : combine) {
sb.append(e.toString()).append("\n");
};
return sb.toString();
};
};