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.File; 23 import java.io.IOException; 24 import java.util.Collection; 25 import java.util.List; 26 import java.util.Map; 27 28 import org.apache.lucene.search.Query; 29 import org.apache.lucene.store.Directory; 30 import org.apache.maven.index.cli.NexusIndexerCli; 31 import org.apache.maven.index.context.ContextMemberProvider; 32 import org.apache.maven.index.context.IndexCreator; 33 import org.apache.maven.index.context.IndexingContext; 34 import org.apache.maven.index.context.UnsupportedExistingLuceneIndexException; 35 import org.apache.maven.index.expr.SearchExpression; 36 import org.apache.maven.index.packer.IndexPacker; 37 import org.apache.maven.index.updater.IndexUpdater; 38 39 /** 40 * The Nexus indexer is a statefull facade that maintains state of indexing contexts. 41 * <p> 42 * The following code snippet shows how to register indexing context, which should be done once on the application 43 * startup and Nexus indexer instance should be reused after that. 44 * 45 * <pre> 46 * NexusIndexer indexer; 47 * 48 * IndexingContext context = indexer.addIndexingContext( indexId, // index id (usually the same as repository id) 49 * repositoryId, // repository id 50 * directory, // Lucene directory where index is stored 51 * repositoryDir, // local repository dir or null for remote repo 52 * repositoryUrl, // repository url, used by index updater 53 * indexUpdateUrl, // index update url or null if derived from repositoryUrl 54 * false, false ); 55 * </pre> 56 * 57 * An indexing context could be populated using one of {@link #scan(IndexingContext)}, 58 * {@link #addArtifactToIndex(ArtifactContext, IndexingContext)} or 59 * {@link #deleteArtifactFromIndex(ArtifactContext, IndexingContext)} methods. 60 * <p> 61 * An {@link IndexUpdater} could be used to fetch indexes from remote repositories. These indexers could be created 62 * using the {@link NexusIndexerCli} command line tool or {@link IndexPacker} API. 63 * <p> 64 * Once index is populated you can perform search queries using field names declared in the {@link ArtifactInfo}: 65 * 66 * <pre> 67 * // run search query 68 * BooleanQuery q = new BooleanQuery(); 69 * q.add(indexer.constructQuery(ArtifactInfo.GROUP_ID, term), Occur.SHOULD); 70 * q.add(indexer.constructQuery(ArtifactInfo.ARTIFACT_ID, term), Occur.SHOULD); 71 * q.add(new PrefixQuery(new Term(ArtifactInfo.SHA1, term)), Occur.SHOULD); 72 * 73 * FlatSearchRequest request = new FlatSearchRequest(q); 74 * FlatSearchResponse response = indexer.searchFlat(request); 75 * ... 76 * </pre> 77 * 78 * Query could be also constructed using a convenience {@link NexusIndexer#constructQuery(Field, SearchExpression)} method that 79 * handles creation of the wildcard queries. Also see {@link DefaultQueryCreator} for more details on supported queries. 80 * 81 * @see IndexingContext 82 * @see IndexUpdater 83 * @see DefaultQueryCreator 84 * @author Jason van Zyl 85 * @author Tamas Cservenak 86 * @author Eugene Kuleshov 87 */ 88 public interface NexusIndexer 89 { 90 String ROLE = NexusIndexer.class.getName(); 91 92 /** 93 * Adds an indexing context to Nexus indexer. 94 * 95 * @param id the ID of the context. 96 * @param repositoryId the ID of the repository that this context represents. 97 * @param repository the location of the repository. 98 * @param indexDirectory the location of the Lucene indexes. 99 * @param repositoryUrl the location of the remote repository. 100 * @param indexUpdateUrl the alternate location of the remote repository indexes (if they are not in default place). 101 * @param indexers the set of indexers to apply to this context. 102 * @return 103 * @throws IOException in case of some serious IO problem. 104 * @throws UnsupportedExistingLuceneIndexException if a Lucene index already exists where location is specified, but 105 * it has no Nexus descriptor record or it has, but the embedded repoId differs from the repoId 106 * specified from the supplied one. 107 * @throws IllegalArgumentException in case the supplied list of IndexCreators are not satisfiable 108 */ 109 IndexingContext addIndexingContext( String id, String repositoryId, File repository, File indexDirectory, 110 String repositoryUrl, String indexUpdateUrl, 111 List<? extends IndexCreator> indexers ) 112 throws IOException, UnsupportedExistingLuceneIndexException; 113 114 /** 115 * Adds an indexing context to Nexus indexer. It "forces" this operation, thus no 116 * UnsupportedExistingLuceneIndexException is thrown. If it founds an existing lucene index, it will simply 117 * stomp-over and rewrite (or add) the Nexus index descriptor. 118 * 119 * @param id the ID of the context. 120 * @param repositoryId the ID of the repository that this context represents. 121 * @param repository the location of the repository. 122 * @param indexDirectory the location of the Lucene indexes. 123 * @param repositoryUrl the location of the remote repository. 124 * @param indexUpdateUrl the alternate location of the remote repository indexes (if they are not in default place). 125 * @param indexers the set of indexers to apply to this context. 126 * @return 127 * @throws IOException in case of some serious IO problem. 128 * @throws IllegalArgumentException in case the supplied list of IndexCreators are not satisfiable 129 */ 130 IndexingContext addIndexingContextForced( String id, String repositoryId, File repository, File indexDirectory, 131 String repositoryUrl, String indexUpdateUrl, 132 List<? extends IndexCreator> indexers ) 133 throws IOException; 134 135 /** 136 * Adds an indexing context to Nexus indexer. 137 * 138 * @param id the ID of the context. 139 * @param repositoryId the ID of the repository that this context represents. 140 * @param repository the location of the repository. 141 * @param directory the location of the Lucene indexes. 142 * @param repositoryUrl the location of the remote repository. 143 * @param indexUpdateUrl the alternate location of the remote repository indexes (if they are not in default place). 144 * @param indexers the set of indexers to apply to this context. 145 * @return 146 * @throws IOException in case of some serious IO problem. 147 * @throws UnsupportedExistingLuceneIndexException if a Lucene index already exists where location is specified, but 148 * it has no Nexus descriptor record or it has, but the embedded repoId differs from the repoId 149 * specified from the supplied one. 150 * @throws IllegalArgumentException in case the supplied list of IndexCreators are not satisfiable 151 */ 152 IndexingContext addIndexingContext( String id, String repositoryId, File repository, Directory directory, 153 String repositoryUrl, String indexUpdateUrl, 154 List<? extends IndexCreator> indexers ) 155 throws IOException, UnsupportedExistingLuceneIndexException; 156 157 /** 158 * Adds an indexing context to Nexus indexer. It "forces" this operation, thus no 159 * UnsupportedExistingLuceneIndexException is thrown. If it founds an existing lucene index, it will simply 160 * stomp-over and rewrite (or add) the Nexus index descriptor. 161 * 162 * @param id the ID of the context. 163 * @param repositoryId the ID of the repository that this context represents. 164 * @param repository the location of the repository. 165 * @param directory the location of the Lucene indexes. 166 * @param repositoryUrl the location of the remote repository. 167 * @param indexUpdateUrl the alternate location of the remote repository indexes (if they are not in default place). 168 * @param indexers the set of indexers to apply to this context. 169 * @return 170 * @throws IOException in case of some serious IO problem. 171 * @throws IllegalArgumentException in case the supplied list of IndexCreators are not satisfiable 172 */ 173 IndexingContext addIndexingContextForced( String id, String repositoryId, File repository, Directory directory, 174 String repositoryUrl, String indexUpdateUrl, 175 List<? extends IndexCreator> indexers ) 176 throws IOException; 177 178 IndexingContext addMergedIndexingContext( String id, String repositoryId, File repository, File indexDirectory, 179 boolean searchable, Collection<IndexingContext> contexts ) 180 throws IOException; 181 182 IndexingContext addMergedIndexingContext( String id, String repositoryId, File repository, File indexDirectory, 183 boolean searchable, ContextMemberProvider membersProvider ) 184 throws IOException; 185 186 IndexingContext addMergedIndexingContext( String id, String repositoryId, File repository, 187 Directory indexDirectory, boolean searchable, 188 Collection<IndexingContext> contexts ) 189 throws IOException; 190 191 IndexingContext addMergedIndexingContext( String id, String repositoryId, File repository, 192 Directory indexDirectory, boolean searchable, 193 ContextMemberProvider membersProvider ) 194 throws IOException; 195 196 /** 197 * Removes the indexing context from Nexus indexer, closes it and deletes (if specified) the index files. 198 * 199 * @param context 200 * @param deleteFiles 201 * @throws IOException 202 */ 203 void removeIndexingContext( IndexingContext context, boolean deleteFiles ) 204 throws IOException; 205 206 /** 207 * Returns the map of indexing contexts keyed by their ID. 208 */ 209 Map<String, IndexingContext> getIndexingContexts(); 210 211 // ---------------------------------------------------------------------------- 212 // Scanning 213 // ---------------------------------------------------------------------------- 214 /** 215 * Performs full scan (reindex) for the local repository belonging to supplied context. 216 * 217 * @param context 218 */ 219 void scan( IndexingContext context ) 220 throws IOException; 221 222 /** 223 * Performs full scan (reindex) for the local repository belonging to supplied context. ArtifactListener is used 224 * during that process. 225 * 226 * @param context 227 * @param listener 228 */ 229 void scan( IndexingContext context, ArtifactScanningListener listener ) 230 throws IOException; 231 232 /** 233 * Performs optionally incremental scan (reindex/full reindex) for the local repository belonging to the supplied 234 * context. 235 * 236 * @param context 237 * @param update if incremental reindex wanted, set true, otherwise false and full reindex will happenF 238 */ 239 void scan( IndexingContext context, boolean update ) 240 throws IOException; 241 242 /** 243 * Performs optionally incremental scan (reindex) for the local repository, with listener. 244 * 245 * @param context 246 * @param listener 247 * @param update if incremental reindex wanted, set true, otherwise false and full reindex will happenF 248 */ 249 void scan( IndexingContext context, ArtifactScanningListener listener, boolean update ) 250 throws IOException; 251 252 /** 253 * Performs optionally incremental scan (reindex) for the local repository. 254 * 255 * @param context 256 * @param fromPath a path segment if you want "sub-path" reindexing (ie. reindex just a given subfolder of a 257 * repository, ot whole repository from root. 258 * @param listener 259 * @param update if incremental reindex wanted, set true, otherwise false and full reindex will happenF 260 */ 261 void scan( IndexingContext context, String fromPath, ArtifactScanningListener listener, boolean update ) 262 throws IOException; 263 264 void artifactDiscovered( ArtifactContext ac, IndexingContext context ) 265 throws IOException; 266 267 // ---------------------------------------------------------------------------- 268 // Modifying 269 // ---------------------------------------------------------------------------- 270 271 void addArtifactToIndex( ArtifactContext ac, IndexingContext context ) 272 throws IOException; 273 274 void addArtifactsToIndex( Collection<ArtifactContext> acs, IndexingContext context ) 275 throws IOException; 276 277 void deleteArtifactFromIndex( ArtifactContext ac, IndexingContext context ) 278 throws IOException; 279 280 void deleteArtifactsFromIndex( Collection<ArtifactContext> acs, IndexingContext context ) 281 throws IOException; 282 283 // ---------------------------------------------------------------------------- 284 // Searching 285 // ---------------------------------------------------------------------------- 286 287 /** 288 * Searches according the request parameters. 289 * 290 * @param request 291 * @return 292 * @throws IOException 293 */ 294 FlatSearchResponse searchFlat( FlatSearchRequest request ) 295 throws IOException; 296 297 /** 298 * Searches according to request parameters. 299 * 300 * @param request 301 * @return 302 * @throws IOException 303 */ 304 IteratorSearchResponse searchIterator( IteratorSearchRequest request ) 305 throws IOException; 306 307 /** 308 * Searches according the request parameters. 309 * 310 * @param request 311 * @return 312 * @throws IOException 313 */ 314 GroupedSearchResponse searchGrouped( GroupedSearchRequest request ) 315 throws IOException; 316 317 // ---------------------------------------------------------------------------- 318 // Query construction 319 // ---------------------------------------------------------------------------- 320 321 /** 322 * Helper method to construct Lucene query for given field without need for knowledge (on caller side) HOW is a 323 * field indexed, and WHAT query is needed to achieve that. 324 * 325 * @param field 326 * @param query 327 * @param type 328 * @return 329 * @deprecated Use {@link #constructQuery(Field, SearchExpression)} instead. 330 */ 331 Query constructQuery( Field field, String query, SearchType type ) 332 throws IllegalArgumentException; 333 334 /** 335 * Helper method to construct Lucene query for given field without need for knowledge (on caller side) HOW is a 336 * field indexed, and WHAT query is needed to achieve that. 337 * 338 * @param field 339 * @param expression 340 * @return 341 */ 342 Query constructQuery( Field field, SearchExpression expression ) 343 throws IllegalArgumentException; 344 345 // ---------------------------------------------------------------------------- 346 // Identification 347 // Since 4.0: Indexer does not make any assumptions, it is caller call to decide what to do with multiple results 348 // ---------------------------------------------------------------------------- 349 350 Collection<ArtifactInfo> identify( Field field, String query ) 351 throws IllegalArgumentException, IOException; 352 353 Collection<ArtifactInfo> identify( File artifact ) 354 throws IOException; 355 356 Collection<ArtifactInfo> identify( File artifact, Collection<IndexingContext> contexts ) 357 throws IOException; 358 359 Collection<ArtifactInfo> identify( Query query ) 360 throws IOException; 361 362 Collection<ArtifactInfo> identify( Query query, Collection<IndexingContext> contexts ) 363 throws IOException; 364 365 }