package org.jabref.logic.search;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.StringJoiner;
import java.util.regex.Pattern;
import com.google.common.eventbus.EventBus;
public class SearchQueryHighlightObservable {
private final EventBus eventBus = new EventBus();
private Optional<Pattern> pattern = Optional.empty();
/**
* Adds a SearchQueryHighlightListener to the search bar. The added listener is immediately informed about the current search.
* Subscribers will be notified about searches.
*
* @param newListener SearchQueryHighlightListener to be added
*/
public void addSearchListener(SearchQueryHighlightListener newListener) {
Objects.requireNonNull(newListener);
eventBus.register(newListener);
newListener.highlightPattern(pattern);
}
public void removeSearchListener(SearchQueryHighlightListener listener) {
Objects.requireNonNull(listener);
try {
eventBus.unregister(listener);
} catch (IllegalArgumentException e) {
// occurs if the event source has not been registered, should not prevent shutdown
}
}
/**
* Fires an event if a search was started (or cleared)
*
* @param searchQuery the search query
*/
public void fireSearchlistenerEvent(SearchQuery searchQuery) {
Objects.requireNonNull(searchQuery);
// Parse the search string to words
pattern = getPatternForWords(searchQuery.getSearchWords(), searchQuery.isRegularExpression(),
searchQuery.isCaseSensitive());
update();
}
public void reset() {
pattern = Optional.empty();
update();
}
private void update() {
// Fire an event for every listener
eventBus.post(pattern);
}
// Returns a regular expression pattern in the form (w1)|(w2)| ... wi are escaped if no regular expression search is enabled
public static Optional<Pattern> getPatternForWords(List<String> words, boolean useRegex, boolean isCaseSensitive) {
if ((words == null) || words.isEmpty() || words.get(0).isEmpty()) {
return Optional.empty();
}
// compile the words to a regular expression in the form (w1)|(w2)|(w3)
StringJoiner joiner = new StringJoiner(")|(", "(", ")");
for (String word : words) {
joiner.add(useRegex ? word : Pattern.quote(word));
}
String searchPattern = joiner.toString();
if (isCaseSensitive) {
return Optional.of(Pattern.compile(searchPattern));
} else {
return Optional.of(Pattern.compile(searchPattern, Pattern.CASE_INSENSITIVE));
}
}
}