View Javadoc
1   package org.apache.maven.index.context;
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.File;
23  import java.io.IOException;
24  import java.util.ArrayList;
25  import java.util.Collection;
26  import java.util.Date;
27  import java.util.HashSet;
28  import java.util.List;
29  import java.util.Set;
30  
31  import org.apache.lucene.analysis.Analyzer;
32  import org.apache.lucene.index.IndexWriter;
33  import org.apache.lucene.search.IndexSearcher;
34  import org.apache.lucene.store.Directory;
35  import org.apache.lucene.store.FSDirectory;
36  import org.apache.maven.index.artifact.GavCalculator;
37  import org.apache.maven.index.artifact.M2GavCalculator;
38  
39  /**
40   * A merged indexing context that offers read only "view" on multiple other indexing contexts merged and presented as
41   * one. Usable for searching and publishing, but all write operations are basically noop.
42   * 
43   * @author cstamas
44   */
45  public class MergedIndexingContext
46      extends AbstractIndexingContext
47  {
48      private final String id;
49  
50      private final String repositoryId;
51  
52      private final File repository;
53  
54      private final ContextMemberProvider membersProvider;
55  
56      private final GavCalculator gavCalculator;
57  
58      private final Directory directory;
59  
60      private File directoryFile;
61  
62      private boolean searchable;
63  
64      private MergedIndexingContext( ContextMemberProvider membersProvider, String id, String repositoryId,
65                                     File repository, Directory indexDirectory, boolean searchable )
66          throws IOException
67      {
68          this.id = id;
69          this.repositoryId = repositoryId;
70          this.repository = repository;
71          this.membersProvider = membersProvider;
72          this.gavCalculator = new M2GavCalculator();
73          this.directory = indexDirectory;
74          this.searchable = searchable;
75          setIndexDirectoryFile( null );
76      }
77  
78      public MergedIndexingContext( String id, String repositoryId, File repository, File indexDirectoryFile,
79                                    boolean searchable, ContextMemberProvider membersProvider )
80          throws IOException
81      {
82          this( membersProvider, id, repositoryId, repository, FSDirectory.open( indexDirectoryFile.toPath() ),
83                searchable );
84  
85          setIndexDirectoryFile( indexDirectoryFile );
86      }
87  
88      @Deprecated
89      public MergedIndexingContext( String id, String repositoryId, File repository, Directory indexDirectory,
90                                    boolean searchable, ContextMemberProvider membersProvider )
91          throws IOException
92      {
93          this( membersProvider, id, repositoryId, repository, indexDirectory, searchable );
94  
95          if ( indexDirectory instanceof FSDirectory )
96          {
97              setIndexDirectoryFile( ( (FSDirectory) indexDirectory ).getDirectory().toFile() );
98          }
99      }
100 
101     public Collection<IndexingContext> getMembers()
102     {
103         return membersProvider.getMembers();
104     }
105 
106     public String getId()
107     {
108         return id;
109     }
110 
111     public String getRepositoryId()
112     {
113         return repositoryId;
114     }
115 
116     public File getRepository()
117     {
118         return repository;
119     }
120 
121     public String getRepositoryUrl()
122     {
123         return null;
124     }
125 
126     public String getIndexUpdateUrl()
127     {
128         return null;
129     }
130 
131     public boolean isSearchable()
132     {
133         return searchable;
134     }
135 
136     public void setSearchable( boolean searchable )
137     {
138         this.searchable = searchable;
139     }
140 
141     public Date getTimestamp()
142     {
143         Date ts = null;
144 
145         for ( IndexingContext ctx : getMembers() )
146         {
147             Date cts = ctx.getTimestamp();
148 
149             if ( cts != null )
150             {
151                 if ( ts == null || cts.after( ts ) )
152                 {
153                     ts = cts;
154                 }
155             }
156         }
157 
158         return ts;
159     }
160 
161     public void updateTimestamp()
162         throws IOException
163     {
164         // noop
165     }
166 
167     public void updateTimestamp( boolean save )
168         throws IOException
169     {
170         // noop
171     }
172 
173     public void updateTimestamp( boolean save, Date date )
174         throws IOException
175     {
176         // noop
177     }
178 
179     public int getSize()
180         throws IOException
181     {
182         int size = 0;
183 
184         for ( IndexingContext ctx : getMembers() )
185         {
186             size += ctx.getSize();
187         }
188 
189         return size;
190     }
191 
192     public IndexSearcher acquireIndexSearcher()
193         throws IOException
194     {
195         final NexusIndexMultiReader mr = new NexusIndexMultiReader( getMembers() );
196         return new NexusIndexMultiSearcher( mr );
197     }
198 
199     public void releaseIndexSearcher( IndexSearcher indexSearcher )
200         throws IOException
201     {
202         if ( indexSearcher instanceof NexusIndexMultiSearcher )
203         {
204             ( (NexusIndexMultiSearcher) indexSearcher ).release();
205         }
206         else
207         {
208             throw new IllegalArgumentException( String.format(
209                 "Illegal argument to merged idexing context: it emits class %s but and cannot release class %s!",
210                 NexusIndexMultiSearcher.class.getName(), indexSearcher.getClass().getName() ) );
211         }
212 
213     }
214 
215     public IndexWriter getIndexWriter()
216         throws IOException
217     {
218         throw new UnsupportedOperationException( getClass().getName() + " indexing context is read-only!" );
219     }
220 
221     public List<IndexCreator> getIndexCreators()
222     {
223         HashSet<IndexCreator> creators = new HashSet<IndexCreator>();
224 
225         for ( IndexingContext ctx : getMembers() )
226         {
227             creators.addAll( ctx.getIndexCreators() );
228         }
229 
230         return new ArrayList<IndexCreator>( creators );
231     }
232 
233     public Analyzer getAnalyzer()
234     {
235         return new NexusAnalyzer();
236     }
237 
238     public void commit()
239         throws IOException
240     {
241         // noop
242     }
243 
244     public void rollback()
245         throws IOException
246     {
247         // noop
248     }
249 
250     public void optimize()
251         throws IOException
252     {
253         // noop
254     }
255 
256     public void close( boolean deleteFiles )
257         throws IOException
258     {
259         // noop
260     }
261 
262     public void purge()
263         throws IOException
264     {
265         // noop
266     }
267 
268     public void merge( Directory directory )
269         throws IOException
270     {
271         // noop
272     }
273 
274     public void merge( Directory directory, DocumentFilter filter )
275         throws IOException
276     {
277         // noop
278     }
279 
280     public void replace( Directory directory )
281         throws IOException
282     {
283         // noop
284     }
285 
286     public void replace( Directory directory, Set<String> allGroups, Set<String> rootGroups )
287         throws IOException
288     {
289         // noop
290     }
291 
292     public Directory getIndexDirectory()
293     {
294         return directory;
295     }
296 
297     public File getIndexDirectoryFile()
298     {
299         return directoryFile;
300     }
301 
302     /**
303      * Sets index location. As usually index is persistent (is on disk), this will point to that value, but in
304      * some circumstances (ie, using RAMDisk for index), this will point to an existing tmp directory.
305      */
306     protected void setIndexDirectoryFile( File dir )
307         throws IOException
308     {
309         if ( dir == null )
310         {
311             // best effort, to have a directory thru the life of a ctx
312             File tmpFile = File.createTempFile( "mindexer-ctx" + id, "tmp" );
313             tmpFile.deleteOnExit();
314             tmpFile.delete();
315             tmpFile.mkdirs();
316             this.directoryFile = tmpFile;
317         }
318         else
319         {
320             this.directoryFile = dir;
321         }
322     }
323 
324     public GavCalculator getGavCalculator()
325     {
326         return gavCalculator;
327     }
328 
329     public void setAllGroups( Collection<String> groups )
330         throws IOException
331     {
332         // noop
333     }
334 
335     public Set<String> getAllGroups()
336         throws IOException
337     {
338         HashSet<String> result = new HashSet<String>();
339 
340         for ( IndexingContext ctx : getMembers() )
341         {
342             result.addAll( ctx.getAllGroups() );
343         }
344 
345         return result;
346     }
347 
348     public void setRootGroups( Collection<String> groups )
349         throws IOException
350     {
351         // noop
352     }
353 
354     public Set<String> getRootGroups()
355         throws IOException
356     {
357         HashSet<String> result = new HashSet<String>();
358 
359         for ( IndexingContext ctx : getMembers() )
360         {
361             result.addAll( ctx.getRootGroups() );
362         }
363 
364         return result;
365     }
366 
367     public void rebuildGroups()
368         throws IOException
369     {
370         // noop
371     }
372 }