package com.niklim.clicktrace.service;
import java.util.List;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.niklim.clicktrace.controller.ActiveSession;
import com.niklim.clicktrace.model.ScreenShot;
import com.niklim.clicktrace.model.Session;
@Singleton
public class SearchService {
@Inject
private SessionManager sessionManager;
@Inject
private ActiveSession activeSession;
/**
* Method searches for {#link ScreenShot}s which have label, filename or
* description containing given text.
*
* @param text text to be found
* @param allSessions true when search should be performed in all sessions,
* false when we search in active session only
* @param matchCase true when we should match letter case
* @return pairs of {#link ScreenShot} and line containing found text
*/
public List<SearchResult> search(String text, boolean allSessions, boolean matchCase) {
List<Session> sessions;
if (allSessions) {
sessions = sessionManager.loadAll();
} else {
sessions = Lists.newArrayList(activeSession.getSession());
}
if (!matchCase) {
text = text.toUpperCase();
}
List<SearchResult> results = Lists.newArrayList();
for (Session session : sessions) {
for (ScreenShot shot : session.getShots()) {
ShotSearchResult result = findText(shot, text, matchCase);
if (result != null) {
results.add(result);
}
}
SessionSearchResult result = findText(session, text, matchCase);
if (result != null) {
results.add(result);
}
}
return results;
}
ShotSearchResult findText(ScreenShot shot, String text, boolean matchCase) {
String description = Strings.nullToEmpty(shot.getDescription());
String label = Strings.nullToEmpty(shot.getLabel());
String filename = Strings.nullToEmpty(shot.getFilename());
if (!matchCase) {
description = description.toUpperCase();
label = label.toUpperCase();
}
if (description.contains(text)) {
String descFragment = findLine(Strings.nullToEmpty(shot.getDescription()), text, matchCase);
return new ShotSearchResult(shot, descFragment);
} else if (label.contains(text)) {
return new ShotSearchResult(shot, shot.getLabel());
} else if (filename.contains(text)) {
return new ShotSearchResult(shot, shot.getFilename());
} else {
return null;
}
}
SessionSearchResult findText(Session session, String text, boolean matchCase) {
String description = Strings.nullToEmpty(session.getDescription());
if (!matchCase) {
description = description.toUpperCase();
}
if (description.contains(text)) {
String descFragment = findLine(Strings.nullToEmpty(session.getDescription()), text, matchCase);
return new SessionSearchResult(session, descFragment);
} else {
return null;
}
}
String findLine(String description, String text, boolean matchCase) {
for (String line : description.split("\n")) {
String l = line;
if (!matchCase) {
l = line.toUpperCase();
}
if (l.contains(text)) {
return line;
}
}
return null;
}
public static abstract class SearchResult {
public final String highlight;
public SearchResult(String highlight) {
this.highlight = highlight;
}
}
public static class ShotSearchResult extends SearchResult {
public final ScreenShot shot;
public ShotSearchResult(ScreenShot shot, String highlight) {
super(highlight);
this.shot = shot;
}
@Override
public String toString() {
return shot.toString();
}
}
public static class SessionSearchResult extends SearchResult {
public final Session session;
public SessionSearchResult(Session session, String highlight) {
super(highlight);
this.session = session;
}
@Override
public String toString() {
return session.toString() + " - session";
}
}
}