View Javadoc

1   package org.apache.maven.index;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0    
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.IOException;
23  import java.util.HashMap;
24  import java.util.Map;
25  import java.util.Set;
26  
27  import org.apache.lucene.document.Document;
28  import org.apache.lucene.document.Field;
29  import org.apache.lucene.document.Fieldable;
30  import org.apache.lucene.index.IndexWriter;
31  import org.apache.lucene.index.Term;
32  import org.apache.lucene.search.IndexSearcher;
33  import org.apache.lucene.search.TermQuery;
34  import org.apache.lucene.search.TopDocs;
35  import org.apache.maven.index.context.IndexingContext;
36  import org.apache.maven.index.creator.MinimalArtifactInfoIndexCreator;
37  import org.codehaus.plexus.component.annotations.Component;
38  import org.codehaus.plexus.logging.AbstractLogEnabled;
39  
40  /**
41   * A default {@link IndexerEngine} implementation.
42   * 
43   * @author Tamas Cservenak
44   */
45  @Component( role = IndexerEngine.class )
46  public class DefaultIndexerEngine
47      extends AbstractLogEnabled
48      implements IndexerEngine
49  {
50  
51      public void index( IndexingContext context, ArtifactContext ac )
52          throws IOException
53      {
54          // skip artifacts not obeying repository layout (whether m1 or m2)
55          if ( ac != null && ac.getGav() != null )
56          {
57              Document d = ac.createDocument( context );
58  
59              if ( d != null )
60              {
61                  context.getIndexWriter().addDocument( d );
62  
63                  context.updateTimestamp();
64              }
65          }
66      }
67  
68      public void update( IndexingContext context, ArtifactContext ac )
69          throws IOException
70      {
71          if ( ac != null && ac.getGav() != null )
72          {
73              Document d = ac.createDocument( context );
74  
75              if ( d != null )
76              {
77                  Document old = getOldDocument( context, ac );
78  
79                  if ( !equals( d, old ) )
80                  {
81                      IndexWriter w = context.getIndexWriter();
82  
83                      w.updateDocument( new Term( ArtifactInfo.UINFO, ac.getArtifactInfo().getUinfo() ), d );
84  
85                      updateGroups( context, ac );
86  
87                      context.updateTimestamp();
88                  }
89              }
90          }
91      }
92  
93      public void remove( IndexingContext context, ArtifactContext ac )
94          throws IOException
95      {
96          if ( ac != null )
97          {
98              final String uinfo = ac.getArtifactInfo().getUinfo();
99  
100             // add artifact deletion marker
101             final Document doc = new Document();
102 
103             doc.add( new Field( ArtifactInfo.DELETED, uinfo, Field.Store.YES, Field.Index.NO ) );
104             doc.add( new Field( ArtifactInfo.LAST_MODIFIED, //
105                 Long.toString( System.currentTimeMillis() ), Field.Store.YES, Field.Index.NO ) );
106 
107             IndexWriter w = context.getIndexWriter();
108             w.addDocument( doc );
109             w.deleteDocuments( new Term( ArtifactInfo.UINFO, uinfo ) );
110             context.updateTimestamp();
111         }
112     }
113 
114     // ==
115 
116     private boolean equals( final Document d1, final Document d2 )
117     {
118         if ( d1 == null && d2 == null )
119         {
120             return true;
121         }
122         if ( d1 == null || d2 == null )
123         {
124             return false;
125         }
126 
127         final Map<String, String> m1 = toMap( d1 );
128         final Map<String, String> m2 = toMap( d2 );
129 
130         m1.remove( MinimalArtifactInfoIndexCreator.FLD_LAST_MODIFIED.getKey() );
131         m2.remove( MinimalArtifactInfoIndexCreator.FLD_LAST_MODIFIED.getKey() );
132 
133         return m1.equals( m2 );
134     }
135 
136     private Map<String, String> toMap( Document d )
137     {
138         final HashMap<String, String> result = new HashMap<String, String>();
139 
140         for ( Object o : d.getFields() )
141         {
142             Fieldable f = (Fieldable) o;
143             if ( f.isStored() )
144             {
145                 result.put( f.name(), f.stringValue() );
146             }
147         }
148 
149         return result;
150     }
151 
152     private Document getOldDocument( IndexingContext context, ArtifactContext ac )
153     {
154         try
155         {
156             final IndexSearcher indexSearcher = context.acquireIndexSearcher();
157             try
158             {
159                 TopDocs result =
160                     indexSearcher.search(
161                         new TermQuery( new Term( ArtifactInfo.UINFO, ac.getArtifactInfo().getUinfo() ) ), 2 );
162 
163                 if ( result.totalHits == 1 )
164                 {
165                     return indexSearcher.doc( result.scoreDocs[0].doc );
166                 }
167             }
168             finally
169             {
170                 context.releaseIndexSearcher( indexSearcher );
171             }
172         }
173         catch ( IOException e )
174         {
175             // huh?
176             throw new IllegalStateException( e );
177         }
178         return null;
179     }
180 
181     private void updateGroups( IndexingContext context, ArtifactContext ac )
182         throws IOException
183     {
184         String rootGroup = ac.getArtifactInfo().getRootGroup();
185         Set<String> rootGroups = context.getRootGroups();
186         if ( !rootGroups.contains( rootGroup ) )
187         {
188             rootGroups.add( rootGroup );
189             context.setRootGroups( rootGroups );
190         }
191 
192         Set<String> allGroups = context.getAllGroups();
193         if ( !allGroups.contains( ac.getArtifactInfo().groupId ) )
194         {
195             allGroups.add( ac.getArtifactInfo().groupId );
196             context.setAllGroups( allGroups );
197         }
198     }
199 }