use of org.opensolaris.opengrok.search.Hit in project OpenGrok by OpenGrok.
the class Context method getContext.
/**
* ???.
* Closes the given <var>in</var> reader on return.
*
* @param in File to be matched
* @param out to write the context
* @param morePrefix to link to more... page
* @param path path of the file
* @param tags format to highlight defs.
* @param limit should the number of matching lines be limited?
* @return Did it get any matching context?
*/
public boolean getContext(Reader in, Writer out, String urlPrefix, String morePrefix, String path, Definitions tags, boolean limit, boolean isDefSearch, List<Hit> hits, Scopes scopes) {
alt = !alt;
if (m == null) {
IOUtils.close(in);
return false;
}
boolean anything = false;
TreeMap<Integer, String[]> matchingTags = null;
String urlPrefixE = (urlPrefix == null) ? "" : Util.URIEncodePath(urlPrefix);
String pathE = Util.URIEncodePath(path);
if (tags != null) {
matchingTags = new TreeMap<Integer, String[]>();
try {
for (Definitions.Tag tag : tags.getTags()) {
for (int i = 0; i < m.length; i++) {
if (m[i].match(tag.symbol) == LineMatcher.MATCHED) {
String scope = null;
String scopeUrl = null;
if (scopes != null) {
Scope scp = scopes.getScope(tag.line);
scope = scp.getName() + "()";
scopeUrl = "<a href=\"" + urlPrefixE + pathE + "#" + Integer.toString(scp.getLineFrom()) + "\">" + scope + "</a>";
}
/* desc[0] is matched symbol
* desc[1] is line number
* desc[2] is type
* desc[3] is matching line;
* desc[4] is scope
*/
String[] desc = { tag.symbol, Integer.toString(tag.line), tag.type, tag.text, scope };
if (in == null) {
if (out == null) {
Hit hit = new Hit(path, Util.htmlize(desc[3]).replace(desc[0], "<b>" + desc[0] + "</b>"), desc[1], false, alt);
hits.add(hit);
anything = true;
} else {
out.write("<a class=\"s\" href=\"");
out.write(urlPrefixE);
out.write(pathE);
out.write("#");
out.write(desc[1]);
out.write("\"><span class=\"l\">");
out.write(desc[1]);
out.write("</span> ");
out.write(Util.htmlize(desc[3]).replace(desc[0], "<b>" + desc[0] + "</b>"));
out.write("</a> ");
if (desc[4] != null) {
out.write("<span class=\"scope\"><a href\"");
out.write(scopeUrl);
out.write("\">in ");
out.write(desc[4]);
out.write("</a></span> ");
}
out.write("<i>");
out.write(desc[2]);
out.write("</i><br/>");
anything = true;
}
} else {
matchingTags.put(tag.line, desc);
}
break;
}
}
}
} catch (Exception e) {
if (hits != null) {
// @todo verify why we ignore all exceptions?
LOGGER.log(Level.WARNING, "Could not get context for " + path, e);
}
}
}
/**
* Just to get the matching tag send a null in
*/
if (in == null) {
return anything;
}
int charsRead = 0;
boolean truncated = false;
boolean lim = limit;
if (!RuntimeEnvironment.getInstance().isQuickContextScan()) {
lim = false;
}
if (lim) {
try {
charsRead = in.read(buffer);
if (charsRead == MAXFILEREAD) {
// we probably only read parts of the file, so set the
// truncated flag to enable the [all...] link that
// requests all matches
truncated = true;
// characters back)
for (int i = charsRead - 1; i > charsRead - 100; i--) {
if (buffer[i] == '\n') {
charsRead = i;
break;
}
}
}
} catch (IOException e) {
LOGGER.log(Level.WARNING, "An error occured while reading data", e);
return anything;
}
if (charsRead == 0) {
return anything;
}
tokens.reInit(buffer, charsRead, out, urlPrefixE + pathE + "#", matchingTags, scopes);
} else {
tokens.reInit(in, out, urlPrefixE + pathE + "#", matchingTags, scopes);
}
if (hits != null) {
tokens.setAlt(alt);
tokens.setHitList(hits);
tokens.setFilename(path);
}
try {
String token;
int matchState = LineMatcher.NOT_MATCHED;
int matchedLines = 0;
while ((token = tokens.yylex()) != null && (!lim || matchedLines < 10)) {
for (int i = 0; i < m.length; i++) {
matchState = m[i].match(token);
if (matchState == LineMatcher.MATCHED) {
if (!isDefSearch) {
tokens.printContext();
} else if (tokens.tags.containsKey(tokens.markedLine)) {
tokens.printContext();
}
matchedLines++;
//out.write("<br> <i>Matched " + token + " maxlines = " + matchedLines + "</i><br>");
break;
} else if (matchState == LineMatcher.WAIT) {
tokens.holdOn();
} else {
tokens.neverMind();
}
}
}
anything = matchedLines > 0;
tokens.dumpRest();
if (lim && (truncated || matchedLines == 10) && out != null) {
out.write("<a href=\"" + Util.URIEncodePath(morePrefix) + pathE + "?" + queryAsURI + "\">[all...]</a>");
}
} catch (IOException e) {
LOGGER.log(Level.WARNING, "Could not get context for " + path, e);
} finally {
IOUtils.close(in);
if (out != null) {
try {
out.flush();
} catch (IOException e) {
LOGGER.log(Level.WARNING, "Failed to flush stream: ", e);
}
}
}
return anything;
}
use of org.opensolaris.opengrok.search.Hit in project OpenGrok by OpenGrok.
the class HistoryContext method getHistoryContext.
/**
* Writes matching History log entries from 'in' to 'out' or to 'hits'
* @param in the history to fetch entries from
* @param out to write matched context
* @param path path to the file
* @param hits list of hits
* @param wcontext web context - beginning of url
*/
private boolean getHistoryContext(History in, String path, Writer out, List<Hit> hits, String wcontext) {
if ((out == null) == (hits == null)) {
// none or both are specified, it's a bug.
throw new IllegalArgumentException("Exactly one of out and hits should be non-null");
}
if (m == null) {
return false;
}
int matchedLines = 0;
Iterator<HistoryEntry> it = in.getHistoryEntries().iterator();
try {
HistoryEntry he;
HistoryEntry nhe = null;
String nrev;
while ((it.hasNext() || (nhe != null)) && matchedLines < 10) {
if (nhe == null) {
he = it.next();
} else //nhe is the lookahead revision
{
he = nhe;
}
String line = he.getLine();
String rev = he.getRevision();
if (//this prefetch mechanism is here because of the diff link generation
it.hasNext()) //this prefetch mechanism is here because of the diff link generation
{
nhe = it.next();
} else // we currently generate the diff to previous revision
{
nhe = null;
}
if (nhe == null) {
nrev = null;
} else {
nrev = nhe.getRevision();
}
tokens.reInit(line);
String token;
int matchState;
int start = -1;
while ((token = tokens.next()) != null) {
for (int i = 0; i < m.length; i++) {
matchState = m[i].match(token);
if (matchState == LineMatcher.MATCHED) {
if (start < 0) {
start = tokens.getMatchStart();
}
int end = tokens.getMatchEnd();
if (out == null) {
StringBuilder sb = new StringBuilder();
writeMatch(sb, line, start, end, true, path, wcontext, nrev, rev);
hits.add(new Hit(path, sb.toString(), "", false, false));
} else {
writeMatch(out, line, start, end, false, path, wcontext, nrev, rev);
}
matchedLines++;
break;
} else if (matchState == LineMatcher.WAIT) {
if (start < 0) {
start = tokens.getMatchStart();
}
} else {
start = -1;
}
}
}
}
} catch (Exception e) {
LOGGER.log(Level.WARNING, "Could not get history context for " + path, e);
}
return matchedLines > 0;
}
use of org.opensolaris.opengrok.search.Hit in project OpenGrok by OpenGrok.
the class ContextTest method testGetContext.
/**
* Helper method for testing various paths through the getContext() method.
*
* @param limit true if limited, quick context scan should be used
* @param hitList true if output should be written to a list instead of a
* writer
*/
private void testGetContext(boolean limit, boolean hitList) throws ParseException {
StringReader in = new StringReader("abc def ghi\n");
StringWriter out = hitList ? null : new StringWriter();
List<Hit> hits = hitList ? new ArrayList<>() : null;
RuntimeEnvironment.getInstance().setQuickContextScan(limit);
// Search freetext for the term "def"
QueryBuilder qb = new QueryBuilder().setFreetext("def");
Context c = new Context(qb.build(), qb.getQueries());
assertTrue(c.getContext(in, out, "", "", "", null, limit, qb.isDefSearch(), hits));
if (hitList) {
assertEquals(1, hits.size());
assertEquals("1", hits.get(0).getLineno());
}
String expectedOutput = hitList ? "abc <b>def</b> ghi" : "<a class=\"s\" href=\"#1\"><span class=\"l\">1</span> " + "abc <b>def</b> ghi</a><br/>";
String actualOutput = hitList ? hits.get(0).getLine() : out.toString();
assertEquals(expectedOutput, actualOutput);
// Search with definitions
Definitions defs = new Definitions();
defs.addTag(1, "def", "type", "text");
in = new StringReader("abc def ghi\n");
out = hitList ? null : new StringWriter();
hits = hitList ? new ArrayList<>() : null;
qb = new QueryBuilder().setDefs("def");
c = new Context(qb.build(), qb.getQueries());
assertTrue(c.getContext(in, out, "", "", "", defs, limit, qb.isDefSearch(), hits));
if (hitList) {
assertEquals(1, hits.size());
assertEquals("1", hits.get(0).getLineno());
}
expectedOutput = hitList ? "abc <b>def</b> ghi" : "<a class=\"s\" href=\"#1\"><span class=\"l\">1</span> " + "abc <b>def</b> ghi</a> <i> type</i> <br/>";
actualOutput = hitList ? hits.get(0).getLine() : out.toString();
assertEquals(expectedOutput, actualOutput);
in = new StringReader("abc def ghi\nbah def foobar");
out = hitList ? null : new StringWriter();
hits = hitList ? new ArrayList<>() : null;
assertTrue(c.getContext(in, out, "", "", "", defs, limit, qb.isDefSearch(), hits));
if (hitList) {
assertEquals(1, hits.size());
assertEquals("1", hits.get(0).getLineno());
}
//test case - if this is def search, don't show false results (defs
// weren't defined)
assertEquals(expectedOutput, actualOutput);
// Search with no input (will search definitions)
in = null;
out = hitList ? null : new StringWriter();
hits = hitList ? new ArrayList<>() : null;
qb = new QueryBuilder().setDefs("def");
c = new Context(qb.build(), qb.getQueries());
assertTrue(c.getContext(in, out, "", "", "", defs, limit, qb.isDefSearch(), hits));
if (hitList) {
assertEquals(1, hits.size());
assertEquals("1", hits.get(0).getLineno());
}
expectedOutput = hitList ? "text" : "<a class=\"s\" href=\"#1\"><span class=\"l\">1</span> " + "text</a> <i>type</i><br/>";
actualOutput = hitList ? hits.get(0).getLine() : out.toString();
assertEquals(expectedOutput, actualOutput);
defs = new Definitions();
defs.addTag(2, "def", "type", "text");
in = new StringReader("abc1 def ghi\nabc def ghi\nabc3 def ghi\n");
out = hitList ? null : new StringWriter();
hits = hitList ? new ArrayList<>() : null;
qb = new QueryBuilder().setDefs("def");
c = new Context(qb.build(), qb.getQueries());
assertTrue(c.getContext(in, out, "", "", "", defs, limit, qb.isDefSearch(), hits));
if (hitList) {
assertEquals(1, hits.size());
assertEquals("2", hits.get(0).getLineno());
}
expectedOutput = hitList ? "abc <b>def</b> ghi" : "<a class=\"s\" href=\"#2\"><span class=\"l\">2</span> " + "abc <b>def</b> ghi</a> <i> type</i> <br/>";
actualOutput = hitList ? hits.get(0).getLine() : out.toString();
assertEquals(expectedOutput, actualOutput);
// Search with no results
in = new StringReader("abc def ghi\n");
out = hitList ? null : new StringWriter();
hits = hitList ? new ArrayList<>() : null;
qb = new QueryBuilder().setFreetext("no_match");
c = new Context(qb.build(), qb.getQueries());
assertFalse(c.getContext(in, out, "", "", "", null, limit, qb.isDefSearch(), hits));
if (hitList) {
assertEquals(0, hits.size());
} else {
assertEquals("", out.toString());
}
// History search (should not show source context)
in = new StringReader("abc def ghi\n");
out = hitList ? null : new StringWriter();
hits = hitList ? new ArrayList<>() : null;
qb = new QueryBuilder().setHist("abc");
c = new Context(qb.build(), qb.getQueries());
assertFalse(c.getContext(in, out, "", "", "", null, limit, qb.isDefSearch(), hits));
if (hitList) {
assertEquals(0, hits.size());
} else {
assertEquals("", out.toString());
}
}
use of org.opensolaris.opengrok.search.Hit in project OpenGrok by OpenGrok.
the class HistoryContextTest method testGetContext_3args.
@Test
public void testGetContext_3args() throws Exception {
String path = "/mercurial/Makefile";
String filename = repositories.getSourceRoot() + path;
// Construct a query equivalent to hist:dummy
TermQuery q1 = new TermQuery(new Term("hist", "dummy"));
ArrayList<Hit> hits = new ArrayList<>();
assertTrue(new HistoryContext(q1).getContext(filename, path, hits));
assertEquals(1, hits.size());
assertTrue(hits.get(0).getLine().contains("Created a small <b>dummy</b> program"));
// Construct a query equivalent to hist:"dummy program"
PhraseQuery.Builder q2 = new PhraseQuery.Builder();
q2.add(new Term("hist", "dummy"));
q2.add(new Term("hist", "program"));
hits.clear();
assertTrue(new HistoryContext(q2.build()).getContext(filename, path, hits));
assertEquals(1, hits.size());
assertTrue(hits.get(0).getLine().contains("Created a small <b>dummy program</b>"));
// Search for a term that doesn't exist
TermQuery q3 = new TermQuery(new Term("hist", "term_does_not_exist"));
hits.clear();
assertFalse(new HistoryContext(q3).getContext(filename, path, hits));
assertEquals(0, hits.size());
// Search for term with multiple hits - hist:small OR hist:target
BooleanQuery.Builder q4 = new BooleanQuery.Builder();
q4.add(new TermQuery(new Term("hist", "small")), Occur.SHOULD);
q4.add(new TermQuery(new Term("hist", "target")), Occur.SHOULD);
hits.clear();
assertTrue(new HistoryContext(q4.build()).getContext(filename, path, hits));
assertEquals(2, hits.size());
assertTrue(hits.get(0).getLine().contains("Add lint make <b>target</b> and fix lint warnings"));
assertTrue(hits.get(1).getLine().contains("Created a <b>small</b> dummy program"));
}
use of org.opensolaris.opengrok.search.Hit in project OpenGrok by OpenGrok.
the class JSONSearchServlet method doGet.
@SuppressWarnings({ "unchecked", "deprecation" })
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
JSONObject result = new JSONObject();
SearchEngine engine = new SearchEngine();
boolean valid = false;
String freetext = req.getParameter(PARAM_FREETEXT);
String def = req.getParameter(PARAM_DEF);
String symbol = req.getParameter(PARAM_SYMBOL);
String path = req.getParameter(PARAM_PATH);
String hist = req.getParameter(PARAM_HIST);
if (freetext != null) {
freetext = URLDecoder.decode(freetext);
engine.setFreetext(freetext);
valid = true;
result.put(PARAM_FREETEXT, freetext);
}
if (def != null) {
def = URLDecoder.decode(def);
engine.setDefinition(def);
valid = true;
result.put(PARAM_DEF, def);
}
if (symbol != null) {
symbol = URLDecoder.decode(symbol);
engine.setSymbol(symbol);
valid = true;
result.put(PARAM_SYMBOL, symbol);
}
if (path != null) {
path = URLDecoder.decode(path);
engine.setFile(path);
valid = true;
result.put(PARAM_PATH, path);
}
if (hist != null) {
hist = URLDecoder.decode(hist);
engine.setHistory(hist);
valid = true;
result.put(PARAM_HIST, hist);
}
if (!valid) {
return;
}
try {
long start = System.currentTimeMillis();
int numResults = engine.search(req);
int maxResults = MAX_RESULTS;
String maxResultsParam = req.getParameter(PARAM_MAXRESULTS);
if (maxResultsParam != null) {
try {
maxResults = Integer.parseInt(maxResultsParam);
result.put(PARAM_MAXRESULTS, maxResults);
} catch (NumberFormatException ex) {
}
}
List<Hit> results = new ArrayList<>(maxResults);
engine.results(0, numResults > maxResults ? maxResults : numResults, results);
JSONArray resultsArray = new JSONArray();
for (Hit hit : results) {
JSONObject hitJson = new JSONObject();
hitJson.put(ATTRIBUTE_DIRECTORY, JSONObject.escape(hit.getDirectory()));
hitJson.put(ATTRIBUTE_FILENAME, JSONObject.escape(hit.getFilename()));
hitJson.put(ATTRIBUTE_LINENO, hit.getLineno());
hitJson.put(ATTRIBUTE_LINE, conv.encode(hit.getLine()));
hitJson.put(ATTRIBUTE_PATH, hit.getPath());
resultsArray.add(hitJson);
}
long duration = System.currentTimeMillis() - start;
result.put(ATTRIBUTE_DURATION, duration);
result.put(ATTRIBUTE_RESULT_COUNT, results.size());
result.put(ATTRIBUTE_RESULTS, resultsArray);
resp.getWriter().write(result.toString());
} finally {
engine.destroy();
}
}
Aggregations