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