<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Sonatype Blog &#187; indexer</title>
	<atom:link href="http://www.sonatype.com/people/tag/indexer/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.sonatype.com/people</link>
	<description>Sonatype is transforming software development with tools, information and services that enable organizations to build better software, faster, using open-source components.</description>
	<lastBuildDate>Thu, 09 Feb 2012 15:48:42 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.2</generator>
		<item>
		<title>Nexus Indexer API: Part 2</title>
		<link>http://www.sonatype.com/people/2009/06/nexus-indexer-api-part-2/</link>
		<comments>http://www.sonatype.com/people/2009/06/nexus-indexer-api-part-2/#comments</comments>
		<pubDate>Sun, 07 Jun 2009 16:16:23 +0000</pubDate>
		<dc:creator>Damian Bradicich</dc:creator>
				<category><![CDATA[Nexus]]></category>
		<category><![CDATA[Sonatype]]></category>
		<category><![CDATA[indexer]]></category>

		<guid isPermaLink="false">http://www.sonatype.com/people/?p=2423</guid>
		<description><![CDATA[This series of Nexus Indexer posts will focus on integrating the Nexus Indexer into your own application. If you have an application that needs to search for an artifact by GAV coordinates, or by class name, you can use the Nexus Index format and the Nexus Indexer API to very easily search and locate artifacts [...]]]></description>
			<content:encoded><![CDATA[<p>This series of Nexus Indexer posts will focus on integrating the Nexus Indexer into your own application.    If you have an application that needs to search for an artifact by GAV coordinates, or by class name, you can use the Nexus Index format and the Nexus Indexer API to very easily search and locate artifacts in any repository that creates a Nexus Index.  There are four main functions that are exposed in the Nexus Indexer API.</p>

<ul>
    <li><a href="http://www.sonatype.com/people/2009/06/nexus-indexer-api-part-1/">Indexing (Part 1)</a></li>
    <li>Searching</li>
    <li>Packing</li>
    <li>Updating</li>
</ul>

<p>This post will focus on Searching and provide you with some concrete code examples that show you how to use the indexer search capabilities in your application.
<span id="more-2423"></span></p>

<h1>Searching</h1>

<p>The Nexus Indexer uses Apache Lucene to handle storage and searching of the index data, and provides a very simple method to search against fields in the index.  Below I have extended my plexus component from the Part 1 of this blog series, to include search functionality.</p>


<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">org.damian</span><span style="color: #339933;">;</span>
...
<span style="color: #008000; font-style: italic; font-weight: bold;">/**
 * Sample app to show how to integrate with the nexus indexer.  Note that this is a simple plexus
 * component extending the SampleApp interface
 *
 * public interface SampleApp
 * {
 *    void index()
 *        throws IOException;
 *
 *    Set searchIndexFlat( String field, String value )
 *        throws IOException;
 *
 *    Set searchIndexFlat( Query query )
 *        throws IOException;
 *
 *    Map searchIndexGrouped( String field, String value )
 *        throws IOException;
 *
 *    Map searchIndexGrouped( String field, String value, Grouping grouping )
 *        throws IOException;
 *
 *    Map searchIndexGrouped( Query q, Grouping grouping )
 *        throws IOException;
 * }
 *
 * @author Damian
 *
 */</span>
@<span style="color: #003399;">Component</span><span style="color: #009900;">&#40;</span> role <span style="color: #339933;">=</span> SampleApp.<span style="color: #000000; font-weight: bold;">class</span> <span style="color: #009900;">&#41;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> DefaultSampleApp
    <span style="color: #000000; font-weight: bold;">implements</span> SampleApp,
        Initializable,
        Disposable
<span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// The nexus indexer</span>
    @Requirement
    <span style="color: #000000; font-weight: bold;">private</span> NexusIndexer indexer<span style="color: #339933;">;</span>
&nbsp;
    ...
&nbsp;
    <span style="color: #666666; font-style: italic;">// search for artifacts</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">Set</span> searchIndexFlat<span style="color: #009900;">&#40;</span> <span style="color: #003399;">String</span> field, <span style="color: #003399;">String</span> value <span style="color: #009900;">&#41;</span>
        <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">IOException</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">// Build a query that will search the documents for the field set to the supplied value</span>
        <span style="color: #666666; font-style: italic;">// This uses predefined logic to define the query</span>
        <span style="color: #666666; font-style: italic;">// See http://svn.sonatype.org/nexus/trunk/nexus-indexer/src/main/java/org/sonatype/nexus/index/DefaultQueryCreator.java</span>
        <span style="color: #666666; font-style: italic;">// for details</span>
        Query query <span style="color: #339933;">=</span> indexer.<span style="color: #006633;">constructQuery</span><span style="color: #009900;">&#40;</span> field, value <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">return</span> searchIndexFlat<span style="color: #009900;">&#40;</span> query <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// search for artifacts using pre-built query</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">Set</span> searchIndexFlat<span style="color: #009900;">&#40;</span> Query query <span style="color: #009900;">&#41;</span>
        <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">IOException</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">// Build the request</span>
        FlatSearchRequest request <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> FlatSearchRequest<span style="color: #009900;">&#40;</span> query <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// Perform the search</span>
        FlatSearchResponse response <span style="color: #339933;">=</span> indexer.<span style="color: #006633;">searchFlat</span><span style="color: #009900;">&#40;</span> request <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// Return the artifact info objects</span>
        <span style="color: #000000; font-weight: bold;">return</span> response.<span style="color: #006633;">getResults</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">Map</span> searchIndexGrouped<span style="color: #009900;">&#40;</span> <span style="color: #003399;">String</span> field, <span style="color: #003399;">String</span> value <span style="color: #009900;">&#41;</span>
        <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">IOException</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">// We will simply use the GAV grouping, meaning that each groupId/artifactId/version/classifier</span>
        <span style="color: #666666; font-style: italic;">// will have its own entry in the returned map</span>
        <span style="color: #000000; font-weight: bold;">return</span> searchIndexGrouped<span style="color: #009900;">&#40;</span> field, value, <span style="color: #000000; font-weight: bold;">new</span> GAVGrouping<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">Map</span> searchIndexGrouped<span style="color: #009900;">&#40;</span> <span style="color: #003399;">String</span> field, <span style="color: #003399;">String</span> value, Grouping grouping <span style="color: #009900;">&#41;</span>
        <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">IOException</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">// Build a query that will search the documents for the field set to the supplied value</span>
        <span style="color: #666666; font-style: italic;">// This uses predefined logic to define the query</span>
        <span style="color: #666666; font-style: italic;">// See http://svn.sonatype.org/nexus/trunk/nexus-indexer/src/main/java/org/sonatype/nexus/index/DefaultQueryCreator.java</span>
        <span style="color: #666666; font-style: italic;">// for details</span>
        Query query <span style="color: #339933;">=</span> indexer.<span style="color: #006633;">constructQuery</span><span style="color: #009900;">&#40;</span> field, value <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">return</span> searchIndexGrouped<span style="color: #009900;">&#40;</span> query, grouping <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">Map</span> searchIndexGrouped<span style="color: #009900;">&#40;</span> Query q, Grouping grouping <span style="color: #009900;">&#41;</span>
        <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">IOException</span>
    <span style="color: #009900;">&#123;</span>
        GroupedSearchRequest request <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> GroupedSearchRequest<span style="color: #009900;">&#40;</span> q, grouping <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        GroupedSearchResponse response <span style="color: #339933;">=</span> indexer.<span style="color: #006633;">searchGrouped</span><span style="color: #009900;">&#40;</span> request <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">return</span> response.<span style="color: #006633;">getResults</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>


<p>As you can see, there are 2 ways to handle how the search is performed.  The first is to use the nexus indexer to decide what type of lucene Query to create, based upon the input string.  The second is to pass in your own lucene Query object, you can use any object that extends the org.apache.lucene.search.Query abstract class.  If you choose to let the nexus indexer build your query, the following rules will apply to the search term:</p>

<ul>
    <li>string converted to lowercase</li>
    <li>if first character is &#8216;^&#8217; drop it</li>
    <li>if first character anything other than &#8216;^&#8217; prepend string with &#8216;*&#8217;</li>
    <li>if last character is &#8216; &#8216;, &#8216;&lt;&#8217; or &#8216;$&#8217; drop it</li>
    <li>if last character anything other than &#8216; &#8216;, &#8216;&lt;&#8217; or &#8216;$&#8217; append &#8216;*&#8217; to end of string</li>
    <li>if modified string does not contain &#8216;*&#8217; then a TermQuery is used (exact match)</li>
    <li>if modified string contains &#8216;*&#8217; in last position, then a PrefixQuery is used (and &#8216;*&#8217; is dropped from string)</li>
    <li>if modified string contains &#8216;*&#8217; in any other position, then a WildcardQuery is used</li>
</ul>

<p>There will probably be occassions where this list of rules doesn&#8217;t apply to your use case, so you instead will want to give the Indexer your own Query object, that leaves you to choose from the many Query objects that lucene provides, or even to make your own if necessary.</p>

<p>You will also notice that there are 2 different types of result sets you can get back, flat or grouped.  Flat results are simply a Set of ArtifactInfo objects for each match in the index.  Grouped results will combine results based upon the Grouping you request (in my sample, the default is GAVGrouping which will group items together that share the same groupId/artifactId/version/classifier).</p>

<p>Here are some samples from a unit test in the project source code, that do the different kinds of searching.</p>


<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> testSampleSearch<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
        <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">Exception</span>
    <span style="color: #009900;">&#123;</span>
        app.<span style="color: #006633;">index</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #003399;">Set</span> artifacts <span style="color: #339933;">=</span> app.<span style="color: #006633;">searchIndexFlat</span><span style="color: #009900;">&#40;</span> SampleIndexCreator.<span style="color: #006633;">MY_FIELD</span>, <span style="color: #0000ff;">&quot;value&quot;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        assertNotNull<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;returned artifacts is null&quot;</span>, artifacts <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        assertFalse<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;returned artifacts is empty&quot;</span>, artifacts.<span style="color: #006633;">isEmpty</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span> ArtifactInfo ai <span style="color: #339933;">:</span> artifacts <span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
            assertEquals<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;returned artifact has invalid data&quot;</span>, <span style="color: #0000ff;">&quot;value&quot;</span>, ai.<span style="color: #006633;">getAttributes</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span> SampleIndexCreator.<span style="color: #006633;">MY_FIELD</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> testSampleSearchWithTermQuery<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
        <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">Exception</span>
    <span style="color: #009900;">&#123;</span>
        app.<span style="color: #006633;">index</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// This type of query will be totally built outside of nexus indexer, and will not</span>
        <span style="color: #666666; font-style: italic;">// be tied to constraints defined in</span>
        <span style="color: #666666; font-style: italic;">// http://svn.sonatype.org/nexus/trunk/nexus-indexer/src/main/java/org/sonatype/nexus/index/DefaultQueryCreator.java</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// A TermQuery matches equal strings</span>
        Query q <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> TermQuery<span style="color: #009900;">&#40;</span> <span style="color: #000000; font-weight: bold;">new</span> Term<span style="color: #009900;">&#40;</span> SampleIndexCreator.<span style="color: #006633;">MY_FIELD</span>, <span style="color: #0000ff;">&quot;value&quot;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #003399;">Set</span> artifacts <span style="color: #339933;">=</span> app.<span style="color: #006633;">searchIndexFlat</span><span style="color: #009900;">&#40;</span> q <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        assertNotNull<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;returned artifacts is null&quot;</span>, artifacts <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        assertFalse<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;returned artifacts is empty&quot;</span>, artifacts.<span style="color: #006633;">isEmpty</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span> ArtifactInfo ai <span style="color: #339933;">:</span> artifacts <span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
            assertEquals<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;returned artifact has invalid data&quot;</span>, <span style="color: #0000ff;">&quot;value&quot;</span>, ai.<span style="color: #006633;">getAttributes</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span> SampleIndexCreator.<span style="color: #006633;">MY_FIELD</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> testSampleSearchWithPrefixQuery<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
        <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">Exception</span>
    <span style="color: #009900;">&#123;</span>
        app.<span style="color: #006633;">index</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// This type of query will be totally built outside of nexus indexer, and will not</span>
        <span style="color: #666666; font-style: italic;">// be tied to constraints defined in</span>
        <span style="color: #666666; font-style: italic;">// http://svn.sonatype.org/nexus/trunk/nexus-indexer/src/main/java/org/sonatype/nexus/index/DefaultQueryCreator.java</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// A PrefixQuery will look for any documents containing the MY_FIELD term that starts with val</span>
        Query q <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> PrefixQuery<span style="color: #009900;">&#40;</span> <span style="color: #000000; font-weight: bold;">new</span> Term<span style="color: #009900;">&#40;</span> SampleIndexCreator.<span style="color: #006633;">MY_FIELD</span>, <span style="color: #0000ff;">&quot;val&quot;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #003399;">Set</span> artifacts <span style="color: #339933;">=</span> app.<span style="color: #006633;">searchIndexFlat</span><span style="color: #009900;">&#40;</span> q <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        assertNotNull<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;returned artifacts is null&quot;</span>, artifacts <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        assertFalse<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;returned artifacts is empty&quot;</span>, artifacts.<span style="color: #006633;">isEmpty</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span> ArtifactInfo ai <span style="color: #339933;">:</span> artifacts <span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
            assertEquals<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;returned artifact has invalid data&quot;</span>, <span style="color: #0000ff;">&quot;value&quot;</span>, ai.<span style="color: #006633;">getAttributes</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span> SampleIndexCreator.<span style="color: #006633;">MY_FIELD</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> testSampleSearchWithWildcardQuery<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
        <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">Exception</span>
    <span style="color: #009900;">&#123;</span>
        app.<span style="color: #006633;">index</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// This type of query will be totally built outside of nexus indexer, and will not</span>
        <span style="color: #666666; font-style: italic;">// be tied to constraints defined in</span>
        <span style="color: #666666; font-style: italic;">// http://svn.sonatype.org/nexus/trunk/nexus-indexer/src/main/java/org/sonatype/nexus/index/DefaultQueryCreator.java</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// A WildcardQuery supports the * and ? wildcard characters</span>
        Query q <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> WildcardQuery<span style="color: #009900;">&#40;</span> <span style="color: #000000; font-weight: bold;">new</span> Term<span style="color: #009900;">&#40;</span> SampleIndexCreator.<span style="color: #006633;">MY_FIELD</span>, <span style="color: #0000ff;">&quot;*alue&quot;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #003399;">Set</span> artifacts <span style="color: #339933;">=</span> app.<span style="color: #006633;">searchIndexFlat</span><span style="color: #009900;">&#40;</span> q <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        assertNotNull<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;returned artifacts is null&quot;</span>, artifacts <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        assertFalse<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;returned artifacts is empty&quot;</span>, artifacts.<span style="color: #006633;">isEmpty</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span> ArtifactInfo ai <span style="color: #339933;">:</span> artifacts <span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
            assertEquals<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;returned artifact has invalid data&quot;</span>, <span style="color: #0000ff;">&quot;value&quot;</span>, ai.<span style="color: #006633;">getAttributes</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span> SampleIndexCreator.<span style="color: #006633;">MY_FIELD</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// A WildcardQuery supports the * and ? wildcard characters</span>
        q <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> WildcardQuery<span style="color: #009900;">&#40;</span> <span style="color: #000000; font-weight: bold;">new</span> Term<span style="color: #009900;">&#40;</span> SampleIndexCreator.<span style="color: #006633;">MY_FIELD</span>, <span style="color: #0000ff;">&quot;v?lue&quot;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        artifacts <span style="color: #339933;">=</span> app.<span style="color: #006633;">searchIndexFlat</span><span style="color: #009900;">&#40;</span> q <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        assertNotNull<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;returned artifacts is null&quot;</span>, artifacts <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        assertFalse<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;returned artifacts is empty&quot;</span>, artifacts.<span style="color: #006633;">isEmpty</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span> ArtifactInfo ai <span style="color: #339933;">:</span> artifacts <span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
            assertEquals<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;returned artifact has invalid data&quot;</span>, <span style="color: #0000ff;">&quot;value&quot;</span>, ai.<span style="color: #006633;">getAttributes</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span> SampleIndexCreator.<span style="color: #006633;">MY_FIELD</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// A WildcardQuery supports the * and ? wildcard characters</span>
        q <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> WildcardQuery<span style="color: #009900;">&#40;</span> <span style="color: #000000; font-weight: bold;">new</span> Term<span style="color: #009900;">&#40;</span> SampleIndexCreator.<span style="color: #006633;">MY_FIELD</span>, <span style="color: #0000ff;">&quot;val*&quot;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        artifacts <span style="color: #339933;">=</span> app.<span style="color: #006633;">searchIndexFlat</span><span style="color: #009900;">&#40;</span> q <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        assertNotNull<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;returned artifacts is null&quot;</span>, artifacts <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        assertFalse<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;returned artifacts is empty&quot;</span>, artifacts.<span style="color: #006633;">isEmpty</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span> ArtifactInfo ai <span style="color: #339933;">:</span> artifacts <span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
            assertEquals<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;returned artifact has invalid data&quot;</span>, <span style="color: #0000ff;">&quot;value&quot;</span>, ai.<span style="color: #006633;">getAttributes</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span> SampleIndexCreator.<span style="color: #006633;">MY_FIELD</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> testSampleSearchGroup<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
        <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">Exception</span>
    <span style="color: #009900;">&#123;</span>
        app.<span style="color: #006633;">index</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #003399;">Map</span> groupedArtifacts <span style="color: #339933;">=</span> app.<span style="color: #006633;">searchIndexGrouped</span><span style="color: #009900;">&#40;</span> SampleIndexCreator.<span style="color: #006633;">MY_FIELD</span>, <span style="color: #0000ff;">&quot;value&quot;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        assertNotNull<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;returned groupedArtifacts is null&quot;</span>, groupedArtifacts <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        assertFalse<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;returned groupedArtifacts should not be empty&quot;</span>, groupedArtifacts.<span style="color: #006633;">isEmpty</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span> ArtifactInfoGroup artifactGroup <span style="color: #339933;">:</span> groupedArtifacts.<span style="color: #006633;">values</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
            <span style="color: #003399;">String</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> parts <span style="color: #339933;">=</span> artifactGroup.<span style="color: #006633;">getGroupKey</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">split</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;:&quot;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #666666; font-style: italic;">//1st part groupId</span>
            <span style="color: #666666; font-style: italic;">//2nd part artifactId</span>
            <span style="color: #666666; font-style: italic;">//3rd part version</span>
            <span style="color: #666666; font-style: italic;">//4th part classifier</span>
            assertEquals<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;should be 4 parts to the group key&quot;</span>, <span style="color: #cc66cc;">4</span>, parts.<span style="color: #006633;">length</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            assertFalse<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;each group should contain at least 1 artifact&quot;</span>, artifactGroup.<span style="color: #006633;">getArtifactInfos</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">isEmpty</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> testSampleSearchGroupNewGrouping<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
        <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">Exception</span>
    <span style="color: #009900;">&#123;</span>
        app.<span style="color: #006633;">index</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// Search using my own grouping, which will group based upon the MY_FIELD parameter</span>
        <span style="color: #003399;">Map</span> groupedArtifacts <span style="color: #339933;">=</span> app.<span style="color: #006633;">searchIndexGrouped</span><span style="color: #009900;">&#40;</span>
            SampleIndexCreator.<span style="color: #006633;">MY_FIELD</span>,
            <span style="color: #0000ff;">&quot;value&quot;</span>,
            <span style="color: #000000; font-weight: bold;">new</span> AbstractGrouping<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
            <span style="color: #009900;">&#123;</span>
                @Override
                <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #003399;">String</span> getGroupKey<span style="color: #009900;">&#40;</span> ArtifactInfo artifactInfo <span style="color: #009900;">&#41;</span>
                <span style="color: #009900;">&#123;</span>
                    <span style="color: #000000; font-weight: bold;">return</span> artifactInfo.<span style="color: #006633;">getAttributes</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span> SampleIndexCreator.<span style="color: #006633;">MY_FIELD</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #009900;">&#125;</span>
            <span style="color: #009900;">&#125;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        assertNotNull<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;returned groupedArtifacts is null&quot;</span>, groupedArtifacts <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        assertEquals<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;returned groupedArtifacts should have 1 entry&quot;</span>, <span style="color: #cc66cc;">1</span>, groupedArtifacts.<span style="color: #006633;">size</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        assertEquals<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;group key should be value&quot;</span>, <span style="color: #0000ff;">&quot;value&quot;</span>, groupedArtifacts.<span style="color: #006633;">values</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">iterator</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">next</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getGroupKey</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>


<p>As you can see from the last test method, you can create your own Grouping object, to group things anyway you see fit, in this case, the results will be grouped using the MY_FIELD parameter.</p>

<p>That&#8217;s all for now, next time we will get into packing up indexes for publishing.</p>

<p>Sample Maven project can be found here <a href="http://svn.sonatype.org/nexus/trunk/sandbox/nexus-indexer-sample">http://svn.sonatype.org/nexus/trunk/sandbox/nexus-indexer-sample</a> and will be updated periodically as I put together more details for the blog posts.</p>
<div style="float: right; margin-left: 10px;"><a href="http://twitter.com/share?url=http://www.sonatype.com/people/2009/06/nexus-indexer-api-part-2/&via=SonatypeCM&text=Nexus Indexer API: Part 2&related=:&lang=en&count=horizontal" class="twitter-share-button">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script></div>]]></content:encoded>
			<wfw:commentRss>http://www.sonatype.com/people/2009/06/nexus-indexer-api-part-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Nexus Indexer API: Part 1</title>
		<link>http://www.sonatype.com/people/2009/06/nexus-indexer-api-part-1/</link>
		<comments>http://www.sonatype.com/people/2009/06/nexus-indexer-api-part-1/#comments</comments>
		<pubDate>Mon, 01 Jun 2009 10:00:46 +0000</pubDate>
		<dc:creator>Damian Bradicich</dc:creator>
				<category><![CDATA[Nexus]]></category>
		<category><![CDATA[indexer]]></category>

		<guid isPermaLink="false">http://www.sonatype.com/people/?p=2318</guid>
		<description><![CDATA[This series of Nexus Indexer posts will focus on integrating the Nexus Indexer into your own application.  If you have an application that needs to search for an artifact by GAV coordinates, or by class name, you can use the Nexus Index format and the Nexus Indexer API to very easily search and locate artifacts [...]]]></description>
			<content:encoded><![CDATA[<p>This series of Nexus Indexer posts will focus on integrating the Nexus Indexer into your own application.    If you have an application that needs to search for an artifact by GAV coordinates, or by class name, you can use the Nexus Index format and the Nexus Indexer API to very easily search and locate artifacts in any repository that creates a Nexus Index.  There are four main functions that are exposed in the Nexus Indexer API.</p>

<ul>
    <li>Indexing</li>
    <li>Searching</li>
    <li>Packing</li>
    <li>Updating</li>
</ul>

<p>This post will focus on Indexing and provide you with some concrete code examples that show you how to integrate the Nexus Indexer into your own application.</p>

<p><span id="more-2318"></span></p>

<h1>Indexing</h1>

<p>The Nexus Indexer is responsible for looking at a maven repository directory layout, and generating a searchable index of the contents of that repository.  Below I have a very simple Plexus component that uses the Nexus Indexer to index a directory:</p>


<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">org.damian</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.io.File</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.io.IOException</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.util.List</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.codehaus.plexus.component.annotations.Component</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.codehaus.plexus.component.annotations.Configuration</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.codehaus.plexus.component.annotations.Requirement</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.codehaus.plexus.personality.plexus.lifecycle.phase.Disposable</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.sonatype.nexus.index.NexusIndexer</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.sonatype.nexus.index.context.IndexCreator</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.sonatype.nexus.index.context.IndexingContext</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.sonatype.nexus.index.context.UnsupportedExistingLuceneIndexException</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #008000; font-style: italic; font-weight: bold;">/**
 * Sample app to show how to integrate with the nexus indexer.  Note that this is a simple plexus
 * component extending the SampleApp interface
 *
 * public interface SampleApp
 * {
 *    void index()
 *        throws IOException;
 * }
 *
 * @author Damian
 *
 */</span>
@<span style="color: #003399;">Component</span><span style="color: #009900;">&#40;</span> role <span style="color: #339933;">=</span> SampleApp.<span style="color: #000000; font-weight: bold;">class</span> <span style="color: #009900;">&#41;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> DefaultSampleApp
    <span style="color: #000000; font-weight: bold;">implements</span> SampleApp,
        Initializable,
        Disposable
<span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// The nexus indexer</span>
    @Requirement
    <span style="color: #000000; font-weight: bold;">private</span> NexusIndexer indexer<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// The list of index creators we will be using (all of them)</span>
    @Requirement<span style="color: #009900;">&#40;</span> role <span style="color: #339933;">=</span> IndexCreator.<span style="color: #000000; font-weight: bold;">class</span> <span style="color: #009900;">&#41;</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">List</span> indexCreators<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// The indexing context</span>
    <span style="color: #000000; font-weight: bold;">private</span> IndexingContext context <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// The path to the repository to index, value will be pulled from</span>
    <span style="color: #666666; font-style: italic;">// the plexus context</span>
    @Configuration<span style="color: #009900;">&#40;</span> value <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;${repository.path}&quot;</span> <span style="color: #009900;">&#41;</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">File</span> repositoryDirectoryPath<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// The path to store index files, value will be pulled from</span>
    <span style="color: #666666; font-style: italic;">// the plexus context</span>
    @Configuration<span style="color: #009900;">&#40;</span> value <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;${index.path}&quot;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">File</span> indexDirectoryPath<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// Initialize the index context</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> initialize<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
        <span style="color: #000000; font-weight: bold;">throws</span> InitializationException
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">try</span>
        <span style="color: #009900;">&#123;</span>
            <span style="color: #666666; font-style: italic;">// Add the indexing context</span>
            context <span style="color: #339933;">=</span> indexer.<span style="color: #006633;">addIndexingContext</span><span style="color: #009900;">&#40;</span>
                <span style="color: #666666; font-style: italic;">// id of the context</span>
                <span style="color: #0000ff;">&quot;sample&quot;</span>,
                <span style="color: #666666; font-style: italic;">// id of the repository</span>
                <span style="color: #0000ff;">&quot;sampleRepo&quot;</span>,
                <span style="color: #666666; font-style: italic;">// directory containing repository</span>
                repositoryDirectoryPath,
                <span style="color: #666666; font-style: italic;">// directory where index will be stored</span>
                indexDirectoryPath,
                <span style="color: #666666; font-style: italic;">// remote repository url...not in this example</span>
                <span style="color: #000066; font-weight: bold;">null</span>,
                <span style="color: #666666; font-style: italic;">// index update url...not in this example</span>
                <span style="color: #000066; font-weight: bold;">null</span>,
                <span style="color: #666666; font-style: italic;">// list of index creators</span>
                indexCreators <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span> UnsupportedExistingLuceneIndexException e <span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> InitializationException<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;Error initializing IndexingContext&quot;</span>, e <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span> <span style="color: #003399;">IOException</span> e <span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> InitializationException<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;Error initializing IndexingContext&quot;</span>, e <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// clean up the context</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> dispose<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> context <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span> <span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
            <span style="color: #666666; font-style: italic;">// Remove the index files, typically would not want to remove the index files, so</span>
            <span style="color: #666666; font-style: italic;">// would pass in false, but this is just a test app...</span>
            <span style="color: #000000; font-weight: bold;">try</span>
            <span style="color: #009900;">&#123;</span>
                indexer.<span style="color: #006633;">removeIndexingContext</span><span style="color: #009900;">&#40;</span> context, <span style="color: #000066; font-weight: bold;">true</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
            <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span> <span style="color: #003399;">IOException</span> e <span style="color: #009900;">&#41;</span>
            <span style="color: #009900;">&#123;</span>
                e.<span style="color: #006633;">printStackTrace</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// index the repository</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> index<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
        <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">IOException</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">// Perform the scan, which will index all artifacts in the repository directory</span>
        <span style="color: #666666; font-style: italic;">// once this is done, searching will be available</span>
        indexer.<span style="color: #006633;">scan</span><span style="color: #009900;">&#40;</span> context <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>


<p>As you can see, there isn&#8217;t much code required to properly manage indexes of your Maven 2 repository.  This is the simplest case, where you don&#8217;t have anything you want to add to the indexer, but suppose you want to index additional data.</p>

<p>The Nexus Indexer uses a set of IndexCreator Plexus components to create the Lucene indexes that store the data.  The Nexus Indexer has 2 by default, the MinimalArtifactInfoIndexCreator (min) and the JarFileContentsIndexCreator (jar).  The min creator takes common items from an artifact and pom (will do best guess if a pom isn&#8217;t available) such as groupId, artifactId, version, packaging, classifier and puts those in the index as searchable fields.  The jar creator simply puts all class names into the index as searchable fields.  Of course you can create your own IndexCreator Plexus component that can index whatever you see fit.</p>

<p>I will now show a sample creator that will explain how to add a new IndexCreator (Note that nexus-indexer-2.0.1-SNAPSHOT is required for this sample to run properly)</p>


<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">org.sonatype.nexus.index.creator</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.io.IOException</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.apache.lucene.document.Document</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.apache.lucene.document.Field</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.codehaus.plexus.component.annotations.Component</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.sonatype.nexus.index.ArtifactContext</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.sonatype.nexus.index.ArtifactInfo</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.sonatype.nexus.index.context.IndexCreator</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #008000; font-style: italic; font-weight: bold;">/**
 * A Sample Index Creator that will show how to properly create your own IndexCreator component
 * @author Damian
 *
 */</span>
<span style="color: #666666; font-style: italic;">// Define the plexus component, and the hint that plexus will use to load it</span>
@<span style="color: #003399;">Component</span><span style="color: #009900;">&#40;</span> role <span style="color: #339933;">=</span> IndexCreator.<span style="color: #000000; font-weight: bold;">class</span>, hint <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;sample&quot;</span> <span style="color: #009900;">&#41;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> SampleIndexCreator
    <span style="color: #000000; font-weight: bold;">extends</span> AbstractIndexCreator
<span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// The name of my sample field</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">String</span> MY_FIELD <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;myfield&quot;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #008000; font-style: italic; font-weight: bold;">/**
     * Populate ArtifactInfo with data specific to your application.  Note that the
     * artifactContext contains other useful objects, which may come in handy.
     */</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> populateArtifactInfo<span style="color: #009900;">&#40;</span> ArtifactContext artifactContext <span style="color: #009900;">&#41;</span>
        <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">IOException</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">// Add the data to the ArtifactInfo</span>
        artifactContext.<span style="color: #006633;">getArtifactInfo</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">addAttribute</span><span style="color: #009900;">&#40;</span> MY_FIELD, <span style="color: #0000ff;">&quot;value&quot;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #008000; font-style: italic; font-weight: bold;">/**
     * Popluate ArtifactInfo from exisiting lucene index document, will want to populate the
     * same fields that you populate in populateArtifactInfo
     */</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">boolean</span> updateArtifactInfo<span style="color: #009900;">&#40;</span> <span style="color: #003399;">Document</span> document, ArtifactInfo artifactInfo <span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">// Add the data to the ArtifactInfo</span>
        artifactInfo.<span style="color: #006633;">addAttribute</span><span style="color: #009900;">&#40;</span> MY_FIELD, document.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span> MY_FIELD <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">//Note that returning false here will notify calling party of failure</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">true</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #008000; font-style: italic; font-weight: bold;">/**
     * Add data from the artifactInfo to the index
     */</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> updateDocument<span style="color: #009900;">&#40;</span> ArtifactInfo artifactInfo, <span style="color: #003399;">Document</span> document <span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        document.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span>
            <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Field</span><span style="color: #009900;">&#40;</span>
                <span style="color: #666666; font-style: italic;">//Field name, should be unique across all IndexCreator objects</span>
                MY_FIELD,
                <span style="color: #666666; font-style: italic;">// get your new data and add to the index</span>
                artifactInfo.<span style="color: #006633;">getAttribute</span><span style="color: #009900;">&#40;</span> MY_FIELD <span style="color: #009900;">&#41;</span>,
                <span style="color: #666666; font-style: italic;">// Whether the data should be stored (YES or NO)</span>
                <span style="color: #003399;">Field</span>.<span style="color: #006633;">Store</span>.<span style="color: #006633;">YES</span>,
                <span style="color: #666666; font-style: italic;">// Whether the field should be indexed (NO, TOKENIZED, UNTOKENIZED)</span>
                <span style="color: #003399;">Field</span>.<span style="color: #006633;">Index</span>.<span style="color: #006633;">UN_TOKENIZED</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>


<p>Simply pass this creator in with the list of creators when adding an index context, and it will now be available.  And that&#8217;s it for this entry, next time we&#8217;ll get to searching the nexus index.</p>

<p>Sample Maven project can be found here <a href="http://svn.sonatype.org/nexus/trunk/sandbox/nexus-indexer-sample" target="_new">http://svn.sonatype.org/nexus/trunk/sandbox/nexus-indexer-sample</a> and will be updated periodically as I put together more details for the blog posts.</p>
<div style="float: right; margin-left: 10px;"><a href="http://twitter.com/share?url=http://www.sonatype.com/people/2009/06/nexus-indexer-api-part-1/&via=SonatypeCM&text=Nexus Indexer API: Part 1&related=:&lang=en&count=horizontal" class="twitter-share-button">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script></div>]]></content:encoded>
			<wfw:commentRss>http://www.sonatype.com/people/2009/06/nexus-indexer-api-part-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

