use of org.opensolaris.opengrok.analysis.Definitions 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.analysis.Definitions in project OpenGrok by OpenGrok.
the class SearchEngine method results.
/**
* get results , if no search was started before, no results are returned
* this method will requery if end is more than first query from search,
* hence performance hit applies, if you want results in later pages than
* number of cachePages also end has to be bigger than start !
*
* @param start start of the hit list
* @param end end of the hit list
* @param ret list of results from start to end or null/empty if no search
* was started
*/
public void results(int start, int end, List<Hit> ret) {
//return if no start search() was done
if (hits == null || (end < start)) {
ret.clear();
return;
}
ret.clear();
//TODO check if below fits for if end=old hits.length, or it should include it
if (end > hits.length & !allCollected) {
//do the requery, we want more than 5 pages
collector = TopScoreDocCollector.create(totalHits);
try {
searcher.search(query, collector);
} catch (Exception e) {
// this exception should never be hit, since search() will hit this before
LOGGER.log(Level.WARNING, SEARCH_EXCEPTION_MSG, e);
}
hits = collector.topDocs().scoreDocs;
Document d = null;
for (int i = start; i < hits.length; i++) {
int docId = hits[i].doc;
try {
d = searcher.doc(docId);
} catch (Exception e) {
LOGGER.log(Level.SEVERE, SEARCH_EXCEPTION_MSG, e);
}
docs.add(d);
}
allCollected = true;
}
// the only problem is that count of docs is usually smaller than number of results
for (int ii = start; ii < end; ++ii) {
boolean alt = (ii % 2 == 0);
boolean hasContext = false;
try {
Document doc = docs.get(ii);
String filename = doc.get(QueryBuilder.PATH);
Genre genre = Genre.get(doc.get(QueryBuilder.T));
Definitions tags = null;
IndexableField tagsField = doc.getField(QueryBuilder.TAGS);
if (tagsField != null) {
tags = Definitions.deserialize(tagsField.binaryValue().bytes);
}
Scopes scopes = null;
IndexableField scopesField = doc.getField(QueryBuilder.SCOPES);
if (scopesField != null) {
scopes = Scopes.deserialize(scopesField.binaryValue().bytes);
}
int nhits = docs.size();
if (sourceContext != null) {
try {
if (Genre.PLAIN == genre && (source != null)) {
hasContext = sourceContext.getContext(new InputStreamReader(new FileInputStream(source + filename)), null, null, null, filename, tags, nhits > 100, false, ret, scopes);
} else if (Genre.XREFABLE == genre && data != null && summarizer != null) {
int l;
try (Reader r = RuntimeEnvironment.getInstance().isCompressXref() ? new HTMLStripCharFilter(new BufferedReader(new InputStreamReader(new GZIPInputStream(new FileInputStream(data + Prefix.XREF_P + filename + ".gz"))))) : new HTMLStripCharFilter(new BufferedReader(new FileReader(data + Prefix.XREF_P + filename)))) {
l = r.read(content);
}
//TODO FIX below fragmenter according to either summarizer or context (to get line numbers, might be hard, since xref writers will need to be fixed too, they generate just one line of html code now :( )
Summary sum = summarizer.getSummary(new String(content, 0, l));
Fragment[] fragments = sum.getFragments();
for (int jj = 0; jj < fragments.length; ++jj) {
String match = fragments[jj].toString();
if (match.length() > 0) {
if (!fragments[jj].isEllipsis()) {
Hit hit = new Hit(filename, fragments[jj].toString(), "", true, alt);
ret.add(hit);
}
hasContext = true;
}
}
} else {
LOGGER.log(Level.WARNING, "Unknown genre: {0} for {1}", new Object[] { genre, filename });
hasContext |= sourceContext.getContext(null, null, null, null, filename, tags, false, false, ret, scopes);
}
} catch (FileNotFoundException exp) {
LOGGER.log(Level.WARNING, "Couldn''t read summary from {0} ({1})", new Object[] { filename, exp.getMessage() });
hasContext |= sourceContext.getContext(null, null, null, null, filename, tags, false, false, ret, scopes);
}
}
if (historyContext != null) {
hasContext |= historyContext.getContext(source + filename, filename, ret);
}
if (!hasContext) {
ret.add(new Hit(filename, "...", "", false, alt));
}
} catch (IOException | ClassNotFoundException | HistoryException e) {
LOGGER.log(Level.WARNING, SEARCH_EXCEPTION_MSG, e);
}
}
}
use of org.opensolaris.opengrok.analysis.Definitions in project OpenGrok by OpenGrok.
the class SearchHelper method executeQuery.
/**
* Start the search prepared by {@link #prepareExec(SortedSet)}. It does
* nothing if {@link #redirect} or {@link #errorMsg} have a
* none-{@code null} value.
* <p>
* Parameters which should be populated/set at this time: <ul> <li>all
* fields required for and populated by
* {@link #prepareExec(SortedSet)})</li> <li>{@link #start} (default:
* 0)</li> <li>{@link #maxItems} (default: 0)</li>
* <li>{@link #isCrossRefSearch} (default: false)</li> </ul> Populates/sets:
* <ul> <li>{@link #hits} (see {@link TopFieldDocs#scoreDocs})</li>
* <li>{@link #totalHits} (see {@link TopFieldDocs#totalHits})</li>
* <li>{@link #contextPath}</li> <li>{@link #errorMsg} if an error
* occurs</li> <li>{@link #redirect} if certain conditions are met</li>
* </ul>
*
* @return this instance
*/
public SearchHelper executeQuery() {
if (redirect != null || errorMsg != null) {
return this;
}
try {
TopFieldDocs fdocs = searcher.search(query, start + maxItems, sort);
totalHits = fdocs.totalHits;
hits = fdocs.scoreDocs;
// Bug #3900: Check if this is a search for a single term, and that
// term is a definition. If that's the case, and we only have one match,
// we'll generate a direct link instead of a listing.
boolean isSingleDefinitionSearch = (query instanceof TermQuery) && (builder.getDefs() != null);
// Attempt to create a direct link to the definition if we search for
// one single definition term AND we have exactly one match AND there
// is only one definition of that symbol in the document that matches.
boolean uniqueDefinition = false;
if (isSingleDefinitionSearch && hits != null && hits.length == 1) {
Document doc = searcher.doc(hits[0].doc);
if (doc.getField(QueryBuilder.TAGS) != null) {
byte[] rawTags = doc.getField(QueryBuilder.TAGS).binaryValue().bytes;
Definitions tags = Definitions.deserialize(rawTags);
String symbol = ((TermQuery) query).getTerm().text();
if (tags.occurrences(symbol) == 1) {
uniqueDefinition = true;
}
}
}
// instead of returning a page with just _one_ entry in....
if (uniqueDefinition && hits != null && hits.length > 0 && isCrossRefSearch) {
redirect = contextPath + Prefix.XREF_P + Util.URIEncodePath(searcher.doc(hits[0].doc).get(QueryBuilder.PATH)) + '#' + Util.URIEncode(((TermQuery) query).getTerm().text());
}
} catch (BooleanQuery.TooManyClauses e) {
errorMsg = "Too many results for wildcard!";
} catch (IOException | ClassNotFoundException e) {
errorMsg = e.getMessage();
}
return this;
}
use of org.opensolaris.opengrok.analysis.Definitions in project OpenGrok by OpenGrok.
the class ClojureAnalyzerFactoryTest method testScopeAnalyzer.
/**
* Test of writeXref method, of class CAnalyzerFactory.
*
* @throws java.lang.Exception
*/
@Test
public void testScopeAnalyzer() throws Exception {
String path = repository.getSourceRoot() + "/clojure/sample.clj";
File f = new File(path);
if (!(f.canRead() && f.isFile())) {
fail("clojure testfile " + f + " not found");
}
Document doc = new Document();
doc.add(new Field(QueryBuilder.FULLPATH, path, string_ft_nstored_nanalyzed_norms));
StringWriter xrefOut = new StringWriter();
analyzer.setCtags(ctags);
analyzer.analyze(doc, getStreamSource(path), xrefOut);
Definitions definitions = Definitions.deserialize(doc.getField(QueryBuilder.TAGS).binaryValue().bytes);
String[] type = new String[1];
assertTrue(definitions.hasDefinitionAt("opengrok", 4, type));
assertThat(type[0], is("namespace"));
assertTrue(definitions.hasDefinitionAt("power-set", 8, type));
assertThat(type[0], is("function"));
assertTrue(definitions.hasDefinitionAt("power-set-private", 14, type));
assertThat(type[0], is("private function"));
assertTrue(definitions.hasDefinitionAt("author", 19, type));
assertThat(type[0], is("struct"));
assertTrue(definitions.hasDefinitionAt("author-first-name", 22, type));
assertThat(type[0], is("definition"));
assertTrue(definitions.hasDefinitionAt("Farid", 24, type));
assertThat(type[0], is("definition"));
}
use of org.opensolaris.opengrok.analysis.Definitions in project OpenGrok by OpenGrok.
the class ContextTest method bug17582.
/**
* Helper method which does the work for {@link #bug17582()}.
*
* @param builder builder for the query we want to test
* @param lines the expected line numbers in the hit list
* @param tags the expected tags in the hit list
*/
private void bug17582(QueryBuilder builder, int[] lines, String[] tags) throws Exception {
assertEquals(lines.length, tags.length);
StringReader in = new StringReader("abc\nbug17582\nBug17582\n");
Definitions defs = new Definitions();
defs.addTag(2, "bug17582", "type1", "text1");
defs.addTag(3, "Bug17582", "type2", "text2");
Context context = new Context(builder.build(), builder.getQueries());
ArrayList<Hit> hits = new ArrayList<>();
assertEquals(lines.length != 0, context.getContext(in, null, "", "", "", defs, false, builder.isDefSearch(), hits));
assertEquals("Unexpected number of hits", lines.length, hits.size());
for (int i = 0; i < lines.length; i++) {
assertEquals(Integer.toString(lines[i]), hits.get(i).getLineno());
assertEquals(tags[i], hits.get(i).getTag());
}
}
Aggregations