View Javadoc
1   package org.apache.archiva.admin.repository.managed;
2   /*
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   */
20  
21  import org.apache.archiva.admin.model.AuditInformation;
22  import org.apache.archiva.admin.model.RepositoryAdminException;
23  import org.apache.archiva.admin.model.beans.ManagedRepository;
24  import org.apache.archiva.admin.model.managed.ManagedRepositoryAdmin;
25  import org.apache.archiva.admin.repository.AbstractRepositoryAdmin;
26  import org.apache.archiva.common.plexusbridge.MavenIndexerUtils;
27  import org.apache.archiva.common.plexusbridge.PlexusSisuBridge;
28  import org.apache.archiva.common.plexusbridge.PlexusSisuBridgeException;
29  import org.apache.archiva.configuration.Configuration;
30  import org.apache.archiva.configuration.ManagedRepositoryConfiguration;
31  import org.apache.archiva.configuration.ProxyConnectorConfiguration;
32  import org.apache.archiva.configuration.RepositoryGroupConfiguration;
33  import org.apache.archiva.metadata.model.facets.AuditEvent;
34  import org.apache.archiva.metadata.repository.MetadataRepository;
35  import org.apache.archiva.metadata.repository.MetadataRepositoryException;
36  import org.apache.archiva.metadata.repository.RepositorySession;
37  import org.apache.archiva.metadata.repository.RepositorySessionFactory;
38  import org.apache.archiva.metadata.repository.stats.RepositoryStatisticsManager;
39  import org.apache.archiva.redback.components.cache.Cache;
40  import org.apache.archiva.redback.components.taskqueue.TaskQueueException;
41  import org.apache.archiva.redback.role.RoleManager;
42  import org.apache.archiva.redback.role.RoleManagerException;
43  import org.apache.archiva.scheduler.repository.model.RepositoryArchivaTaskScheduler;
44  import org.apache.archiva.scheduler.repository.model.RepositoryTask;
45  import org.apache.archiva.security.common.ArchivaRoleConstants;
46  import org.apache.commons.io.FileUtils;
47  import org.apache.commons.lang.StringUtils;
48  import org.apache.maven.index.NexusIndexer;
49  import org.apache.maven.index.context.IndexCreator;
50  import org.apache.maven.index.context.IndexingContext;
51  import org.apache.maven.index.context.UnsupportedExistingLuceneIndexException;
52  import org.slf4j.Logger;
53  import org.slf4j.LoggerFactory;
54  import org.springframework.stereotype.Service;
55  
56  import javax.annotation.PostConstruct;
57  import javax.annotation.PreDestroy;
58  import javax.inject.Inject;
59  import javax.inject.Named;
60  import java.io.File;
61  import java.io.IOException;
62  import java.net.MalformedURLException;
63  import java.util.ArrayList;
64  import java.util.Collection;
65  import java.util.Collections;
66  import java.util.HashMap;
67  import java.util.List;
68  import java.util.Map;
69  
70  /**
71   * FIXME review the staging mechanism to have a per user session one
72   *
73   * @author Olivier Lamy
74   */
75  @Service("managedRepositoryAdmin#default")
76  public class DefaultManagedRepositoryAdmin
77      extends AbstractRepositoryAdmin
78      implements ManagedRepositoryAdmin
79  {
80  
81      private Logger log = LoggerFactory.getLogger( getClass() );
82  
83      public static final String STAGE_REPO_ID_END = "-stage";
84  
85      @Inject
86      @Named(value = "archivaTaskScheduler#repository")
87      private RepositoryArchivaTaskScheduler repositoryTaskScheduler;
88  
89      /**
90       * FIXME: this could be multiple implementations and needs to be configured.
91       */
92      @Inject
93      private RepositorySessionFactory repositorySessionFactory;
94  
95      @Inject
96      private RepositoryStatisticsManager repositoryStatisticsManager;
97  
98      @Inject
99      private PlexusSisuBridge plexusSisuBridge;
100 
101     @Inject
102     private MavenIndexerUtils mavenIndexerUtils;
103 
104     @Inject
105     protected RoleManager roleManager;
106 
107     @Inject
108     @Named(value = "cache#namespaces")
109     private Cache<String, Collection<String>> namespacesCache;
110 
111     // fields
112     List<? extends IndexCreator> indexCreators;
113 
114     NexusIndexer indexer;
115 
116     @PostConstruct
117     public void initialize()
118         throws RepositoryAdminException, RoleManagerException
119     {
120         try
121         {
122             indexCreators = mavenIndexerUtils.getAllIndexCreators();
123             indexer = plexusSisuBridge.lookup( NexusIndexer.class );
124         }
125         catch ( PlexusSisuBridgeException e )
126         {
127             throw new RepositoryAdminException( e.getMessage(), e );
128         }
129         // initialize index context on start and check roles here
130         for ( ManagedRepository managedRepository : getManagedRepositories() )
131         {
132             createIndexContext( managedRepository );
133             addRepositoryRoles( managedRepository.getId() );
134 
135         }
136     }
137 
138     @PreDestroy
139     public void shutdown()
140         throws RepositoryAdminException
141     {
142         try
143         {
144             // close index on shutdown
145             for ( ManagedRepository managedRepository : getManagedRepositories() )
146             {
147                 IndexingContext context = indexer.getIndexingContexts().get( managedRepository.getId() );
148                 if ( context != null )
149                 {
150                     indexer.removeIndexingContext( context, false );
151                 }
152             }
153         }
154         catch ( IOException e )
155         {
156             throw new RepositoryAdminException( e.getMessage(), e );
157         }
158     }
159 
160     @Override
161     public List<ManagedRepository> getManagedRepositories()
162         throws RepositoryAdminException
163     {
164         List<ManagedRepositoryConfiguration> managedRepoConfigs =
165             getArchivaConfiguration().getConfiguration().getManagedRepositories();
166 
167         if ( managedRepoConfigs == null )
168         {
169             return Collections.emptyList();
170         }
171 
172         List<ManagedRepository> managedRepos = new ArrayList<ManagedRepository>( managedRepoConfigs.size() );
173 
174         for ( ManagedRepositoryConfiguration repoConfig : managedRepoConfigs )
175         {
176             ManagedRepository repo =
177                 new ManagedRepository( repoConfig.getId(), repoConfig.getName(), repoConfig.getLocation(),
178                                        repoConfig.getLayout(), repoConfig.isSnapshots(), repoConfig.isReleases(),
179                                        repoConfig.isBlockRedeployments(), repoConfig.getRefreshCronExpression(),
180                                        repoConfig.getIndexDir(), repoConfig.isScanned(), repoConfig.getDaysOlder(),
181                                        repoConfig.getRetentionCount(), repoConfig.isDeleteReleasedSnapshots(),
182                                        repoConfig.isStageRepoNeeded() );
183             repo.setDescription( repoConfig.getDescription() );
184             repo.setSkipPackedIndexCreation( repoConfig.isSkipPackedIndexCreation() );
185             managedRepos.add( repo );
186         }
187 
188         return managedRepos;
189     }
190 
191     @Override
192     public Map<String, ManagedRepository> getManagedRepositoriesAsMap()
193         throws RepositoryAdminException
194     {
195         List<ManagedRepository> managedRepositories = getManagedRepositories();
196         Map<String, ManagedRepository> repositoriesMap = new HashMap<>( managedRepositories.size() );
197         for ( ManagedRepository managedRepository : managedRepositories )
198         {
199             repositoriesMap.put( managedRepository.getId(), managedRepository );
200         }
201         return repositoriesMap;
202     }
203 
204     @Override
205     public ManagedRepository getManagedRepository( String repositoryId )
206         throws RepositoryAdminException
207     {
208         List<ManagedRepository> repos = getManagedRepositories();
209         for ( ManagedRepository repo : repos )
210         {
211             if ( StringUtils.equals( repo.getId(), repositoryId ) )
212             {
213                 return repo;
214             }
215         }
216         return null;
217     }
218 
219     @Override
220     public Boolean addManagedRepository( ManagedRepository managedRepository, boolean needStageRepo,
221                                          AuditInformation auditInformation )
222         throws RepositoryAdminException
223     {
224 
225         getRepositoryCommonValidator().basicValidation( managedRepository, false );
226         getRepositoryCommonValidator().validateManagedRepository( managedRepository );
227         triggerAuditEvent( managedRepository.getId(), null, AuditEvent.ADD_MANAGED_REPO, auditInformation );
228         Boolean res =
229             addManagedRepository( managedRepository.getId(), managedRepository.getLayout(), managedRepository.getName(),
230                                   managedRepository.getLocation(), managedRepository.isBlockRedeployments(),
231                                   managedRepository.isReleases(), managedRepository.isSnapshots(), needStageRepo,
232                                   managedRepository.getCronExpression(), managedRepository.getIndexDirectory(),
233                                   managedRepository.getDaysOlder(), managedRepository.getRetentionCount(),
234                                   managedRepository.isDeleteReleasedSnapshots(), managedRepository.getDescription(),
235                                   managedRepository.isSkipPackedIndexCreation(), managedRepository.isScanned(),
236                                   auditInformation, getArchivaConfiguration().getConfiguration() ) != null;
237 
238         createIndexContext( managedRepository );
239         return res;
240 
241     }
242 
243     private ManagedRepositoryConfiguration addManagedRepository( String repoId, String layout, String name,
244                                                                  String location, boolean blockRedeployments,
245                                                                  boolean releasesIncluded, boolean snapshotsIncluded,
246                                                                  boolean stageRepoNeeded, String cronExpression,
247                                                                  String indexDir, int daysOlder, int retentionCount,
248                                                                  boolean deteleReleasedSnapshots, String description,
249                                                                  boolean skipPackedIndexCreation, boolean scanned,
250                                                                  AuditInformation auditInformation,
251                                                                  Configuration config )
252         throws RepositoryAdminException
253     {
254 
255         ManagedRepositoryConfiguration repository = new ManagedRepositoryConfiguration();
256 
257         repository.setId( repoId );
258         repository.setBlockRedeployments( blockRedeployments );
259         repository.setReleases( releasesIncluded );
260         repository.setSnapshots( snapshotsIncluded );
261         repository.setScanned( scanned );
262         repository.setName( name );
263         repository.setLocation( getRepositoryCommonValidator().removeExpressions( location ) );
264         repository.setLayout( layout );
265         repository.setRefreshCronExpression( cronExpression );
266         repository.setIndexDir( indexDir );
267         repository.setDaysOlder( daysOlder );
268         repository.setRetentionCount( retentionCount );
269         repository.setDeleteReleasedSnapshots( deteleReleasedSnapshots );
270         repository.setIndexDir( indexDir );
271         repository.setDescription( description );
272         repository.setSkipPackedIndexCreation( skipPackedIndexCreation );
273         repository.setStageRepoNeeded( stageRepoNeeded );
274 
275         try
276         {
277             addRepository( repository, config );
278             addRepositoryRoles( repository.getId() );
279 
280             if ( stageRepoNeeded )
281             {
282                 ManagedRepositoryConfiguration stagingRepository = getStageRepoConfig( repository );
283                 addRepository( stagingRepository, config );
284                 addRepositoryRoles( stagingRepository.getId() );
285                 triggerAuditEvent( stagingRepository.getId(), null, AuditEvent.ADD_MANAGED_REPO, auditInformation );
286             }
287         }
288         catch ( RoleManagerException e )
289         {
290             throw new RepositoryAdminException( "failed to add repository roles " + e.getMessage(), e );
291         }
292         catch ( IOException e )
293         {
294             throw new RepositoryAdminException( "failed to add repository " + e.getMessage(), e );
295         }
296 
297         saveConfiguration( config );
298 
299         //MRM-1342 Repository statistics report doesn't appear to be working correctly
300         //scan repository when adding of repository is successful
301         try
302         {
303             if ( scanned )
304             {
305                 scanRepository( repoId, true );
306             }
307 
308             // TODO need a better to define scanning or not for staged repo
309             if ( stageRepoNeeded && scanned )
310             {
311                 ManagedRepositoryConfiguration stagingRepository = getStageRepoConfig( repository );
312                 scanRepository( stagingRepository.getId(), true );
313             }
314         }
315         catch ( Exception e )
316         {
317             log.warn( new StringBuilder( "Unable to scan repository [" ).append( repoId ).append( "]: " ).append(
318                 e.getMessage() ).toString(), e );
319         }
320 
321         return repository;
322     }
323 
324     @Override
325     public Boolean deleteManagedRepository( String repositoryId, AuditInformation auditInformation,
326                                             boolean deleteContent )
327         throws RepositoryAdminException
328     {
329         Configuration config = getArchivaConfiguration().getConfiguration();
330 
331         ManagedRepositoryConfiguration repository = config.findManagedRepositoryById( repositoryId );
332 
333         if ( repository == null )
334         {
335             throw new RepositoryAdminException( "A repository with that id does not exist" );
336         }
337 
338         triggerAuditEvent( repositoryId, null, AuditEvent.DELETE_MANAGED_REPO, auditInformation );
339 
340         deleteManagedRepository( repository, deleteContent, config, false );
341 
342         // stage repo exists ?
343         ManagedRepositoryConfiguration stagingRepository =
344             getArchivaConfiguration().getConfiguration().findManagedRepositoryById( repositoryId + STAGE_REPO_ID_END );
345         if ( stagingRepository != null )
346         {
347             // do not trigger event when deleting the staged one
348             deleteManagedRepository( stagingRepository, deleteContent, config, true );
349         }
350 
351         try
352         {
353             saveConfiguration( config );
354         }
355         catch ( Exception e )
356         {
357             throw new RepositoryAdminException( "Error saving configuration for delete action" + e.getMessage(), e );
358         }
359 
360         return Boolean.TRUE;
361     }
362 
363     private Boolean deleteManagedRepository( ManagedRepositoryConfiguration repository, boolean deleteContent,
364                                              Configuration config, boolean stagedOne )
365         throws RepositoryAdminException
366     {
367 
368         try
369         {
370             NexusIndexer nexusIndexer = plexusSisuBridge.lookup( NexusIndexer.class );
371 
372             IndexingContext context = nexusIndexer.getIndexingContexts().get( repository.getId() );
373             if ( context != null )
374             {
375                 // delete content only if directory exists
376                 nexusIndexer.removeIndexingContext( context,
377                                                     deleteContent && context.getIndexDirectoryFile().exists() );
378             }
379         }
380         catch ( PlexusSisuBridgeException e )
381         {
382             throw new RepositoryAdminException( e.getMessage(), e );
383         }
384         catch ( IOException e )
385         {
386             throw new RepositoryAdminException( e.getMessage(), e );
387         }
388         if ( !stagedOne )
389         {
390             RepositorySession repositorySession = getRepositorySessionFactory().createSession();
391             try
392             {
393                 MetadataRepository metadataRepository = repositorySession.getRepository();
394                 metadataRepository.removeRepository( repository.getId() );
395                 //invalidate cache
396                 namespacesCache.remove( repository.getId() );
397                 log.debug( "call repositoryStatisticsManager.deleteStatistics" );
398                 getRepositoryStatisticsManager().deleteStatistics( metadataRepository, repository.getId() );
399                 repositorySession.save();
400             }
401             catch ( MetadataRepositoryException e )
402             {
403                 //throw new RepositoryAdminException( e.getMessage(), e );
404                 log.warn( "skip error during removing repository from MetadataRepository:{}", e.getMessage(), e );
405             }
406             finally
407             {
408                 repositorySession.close();
409             }
410         }
411         config.removeManagedRepository( repository );
412 
413         if ( deleteContent )
414         {
415             // TODO could be async ? as directory can be huge
416             File dir = new File( repository.getLocation() );
417             if ( !FileUtils.deleteQuietly( dir ) )
418             {
419                 throw new RepositoryAdminException( "Cannot delete repository " + dir );
420             }
421         }
422 
423         // olamy: copy list for reading as a unit test in webapp fail with ConcurrentModificationException
424         List<ProxyConnectorConfiguration> proxyConnectors = new ArrayList<>( config.getProxyConnectors() );
425         for ( ProxyConnectorConfiguration proxyConnector : proxyConnectors )
426         {
427             if ( StringUtils.equals( proxyConnector.getSourceRepoId(), repository.getId() ) )
428             {
429                 config.removeProxyConnector( proxyConnector );
430             }
431         }
432 
433         Map<String, List<String>> repoToGroupMap = config.getRepositoryToGroupMap();
434         if ( repoToGroupMap != null )
435         {
436             if ( repoToGroupMap.containsKey( repository.getId() ) )
437             {
438                 List<String> repoGroups = repoToGroupMap.get( repository.getId() );
439                 for ( String repoGroup : repoGroups )
440                 {
441                     // copy to prevent UnsupportedOperationException
442                     RepositoryGroupConfiguration repositoryGroupConfiguration =
443                         config.findRepositoryGroupById( repoGroup );
444                     List<String> repos = new ArrayList<>( repositoryGroupConfiguration.getRepositories() );
445                     config.removeRepositoryGroup( repositoryGroupConfiguration );
446                     repos.remove( repository.getId() );
447                     repositoryGroupConfiguration.setRepositories( repos );
448                     config.addRepositoryGroup( repositoryGroupConfiguration );
449                 }
450             }
451         }
452 
453         try
454         {
455             removeRepositoryRoles( repository );
456         }
457         catch ( RoleManagerException e )
458         {
459             throw new RepositoryAdminException(
460                 "fail to remove repository roles for repository " + repository.getId() + " : " + e.getMessage(), e );
461         }
462 
463         saveConfiguration( config );
464 
465         return Boolean.TRUE;
466     }
467 
468 
469     @Override
470     public Boolean updateManagedRepository( ManagedRepository managedRepository, boolean needStageRepo,
471                                             AuditInformation auditInformation, boolean resetStats )
472         throws RepositoryAdminException
473     {
474 
475         log.debug( "updateManagedConfiguration repo {} needStage {} resetStats {} ", managedRepository, needStageRepo,
476                    resetStats );
477 
478         // Ensure that the fields are valid.
479 
480         getRepositoryCommonValidator().basicValidation( managedRepository, true );
481 
482         getRepositoryCommonValidator().validateManagedRepository( managedRepository );
483 
484         Configuration configuration = getArchivaConfiguration().getConfiguration();
485 
486         ManagedRepositoryConfiguration toremove = configuration.findManagedRepositoryById( managedRepository.getId() );
487 
488         boolean updateIndexContext = false;
489 
490         if ( toremove != null )
491         {
492             configuration.removeManagedRepository( toremove );
493 
494             updateIndexContext = !StringUtils.equals( toremove.getIndexDir(), managedRepository.getIndexDirectory() );
495         }
496 
497         ManagedRepositoryConfiguration stagingRepository = getStageRepoConfig( toremove );
498 
499         // TODO remove content from old if path has changed !!!!!
500 
501         if ( stagingRepository != null )
502         {
503             configuration.removeManagedRepository( stagingRepository );
504         }
505 
506         ManagedRepositoryConfiguration managedRepositoryConfiguration =
507             addManagedRepository( managedRepository.getId(), managedRepository.getLayout(), managedRepository.getName(),
508                                   managedRepository.getLocation(), managedRepository.isBlockRedeployments(),
509                                   managedRepository.isReleases(), managedRepository.isSnapshots(), needStageRepo,
510                                   managedRepository.getCronExpression(), managedRepository.getIndexDirectory(),
511                                   managedRepository.getDaysOlder(), managedRepository.getRetentionCount(),
512                                   managedRepository.isDeleteReleasedSnapshots(), managedRepository.getDescription(),
513                                   managedRepository.isSkipPackedIndexCreation(), managedRepository.isScanned(),
514                                   auditInformation, getArchivaConfiguration().getConfiguration() );
515 
516         // Save the repository configuration.
517         RepositorySession repositorySession = getRepositorySessionFactory().createSession();
518 
519         try
520         {
521             triggerAuditEvent( managedRepositoryConfiguration.getId(), null, AuditEvent.MODIFY_MANAGED_REPO,
522                                auditInformation );
523 
524             saveConfiguration( this.getArchivaConfiguration().getConfiguration() );
525             if ( resetStats )
526             {
527                 log.debug( "call repositoryStatisticsManager.deleteStatistics" );
528                 getRepositoryStatisticsManager().deleteStatistics( repositorySession.getRepository(),
529                                                                    managedRepositoryConfiguration.getId() );
530                 repositorySession.save();
531             }
532 
533         }
534         catch ( MetadataRepositoryException e )
535         {
536             throw new RepositoryAdminException( e.getMessage(), e );
537         }
538         finally
539         {
540             repositorySession.close();
541         }
542 
543         if ( updateIndexContext )
544         {
545             try
546             {
547                 IndexingContext indexingContext = indexer.getIndexingContexts().get( managedRepository.getId() );
548                 if ( indexingContext != null )
549                 {
550                     indexer.removeIndexingContext( indexingContext, true );
551                 }
552 
553                 // delete directory too as only content is deleted
554                 File indexDirectory = indexingContext.getIndexDirectoryFile();
555                 FileUtils.deleteDirectory( indexDirectory );
556 
557                 createIndexContext( managedRepository );
558             }
559             catch ( IOException e )
560             {
561                 throw new RepositoryAdminException( e.getMessage(), e );
562             }
563         }
564 
565         return true;
566     }
567 
568     //--------------------------
569     // utils methods
570     //--------------------------
571 
572 
573     protected void addRepository( ManagedRepositoryConfiguration repository, Configuration configuration )
574         throws RepositoryAdminException, IOException
575     {
576         // Normalize the path
577         File file = new File( repository.getLocation() );
578         if ( !file.isAbsolute() )
579         {
580             // add appserver.base/repositories
581             file = new File( getRegistry().getString( "appserver.base" ) + File.separatorChar + "repositories",
582                              repository.getLocation() );
583         }
584         repository.setLocation( file.getCanonicalPath() );
585         if ( !file.exists() )
586         {
587             file.mkdirs();
588         }
589         if ( !file.exists() || !file.isDirectory() )
590         {
591             throw new RepositoryAdminException(
592                 "Unable to add repository - no write access, can not create the root directory: " + file );
593         }
594 
595         configuration.addManagedRepository( repository );
596 
597     }
598 
599     @Override
600     public IndexingContext createIndexContext( ManagedRepository repository )
601         throws RepositoryAdminException
602     {
603 
604         IndexingContext context = indexer.getIndexingContexts().get( repository.getId() );
605 
606         if ( context != null )
607         {
608             log.debug( "skip creating repository indexingContent with id {} as already exists", repository.getId() );
609             return context;
610         }
611 
612         // take care first about repository location as can be relative
613         File repositoryDirectory = new File( repository.getLocation() );
614 
615         if ( !repositoryDirectory.isAbsolute() )
616         {
617             repositoryDirectory =
618                 new File( getRegistry().getString( "appserver.base" ) + File.separatorChar + "repositories",
619                           repository.getLocation() );
620         }
621 
622         if ( !repositoryDirectory.exists() )
623         {
624             repositoryDirectory.mkdirs();
625         }
626 
627         try
628         {
629 
630             String indexDir = repository.getIndexDirectory();
631             //File managedRepository = new File( repository.getLocation() );
632 
633             File indexDirectory = null;
634             if ( StringUtils.isNotBlank( indexDir ) )
635             {
636                 indexDirectory = new File( repository.getIndexDirectory() );
637                 // not absolute so create it in repository directory
638                 if ( !indexDirectory.isAbsolute() )
639                 {
640                     indexDirectory = new File( repositoryDirectory, repository.getIndexDirectory() );
641                 }
642                 repository.setIndexDirectory( indexDirectory.getAbsolutePath() );
643             }
644             else
645             {
646                 indexDirectory = new File( repositoryDirectory, ".indexer" );
647                 if ( !repositoryDirectory.isAbsolute() )
648                 {
649                     indexDirectory = new File( repositoryDirectory, ".indexer" );
650                 }
651                 repository.setIndexDirectory( indexDirectory.getAbsolutePath() );
652             }
653 
654             if ( !indexDirectory.exists() )
655             {
656                 indexDirectory.mkdirs();
657             }
658 
659             context = indexer.getIndexingContexts().get( repository.getId() );
660 
661             if ( context == null )
662             {
663                 context = indexer.addIndexingContext( repository.getId(), repository.getId(), repositoryDirectory,
664                                                       indexDirectory,
665                                                       repositoryDirectory.toURI().toURL().toExternalForm(),
666                                                       indexDirectory.toURI().toURL().toString(), indexCreators );
667 
668                 context.setSearchable( repository.isScanned() );
669             }
670             return context;
671         }
672         catch ( MalformedURLException e )
673         {
674             throw new RepositoryAdminException( e.getMessage(), e );
675         }
676         catch ( IOException e )
677         {
678             throw new RepositoryAdminException( e.getMessage(), e );
679         }
680         catch ( UnsupportedExistingLuceneIndexException e )
681         {
682             throw new RepositoryAdminException( e.getMessage(), e );
683         }
684     }
685 
686     private ManagedRepositoryConfiguration getStageRepoConfig( ManagedRepositoryConfiguration repository )
687     {
688         ManagedRepositoryConfiguration stagingRepository = new ManagedRepositoryConfiguration();
689         stagingRepository.setId( repository.getId() + STAGE_REPO_ID_END );
690         stagingRepository.setLayout( repository.getLayout() );
691         stagingRepository.setName( repository.getName() + STAGE_REPO_ID_END );
692         stagingRepository.setBlockRedeployments( repository.isBlockRedeployments() );
693         stagingRepository.setDaysOlder( repository.getDaysOlder() );
694         stagingRepository.setDeleteReleasedSnapshots( repository.isDeleteReleasedSnapshots() );
695 
696         String path = repository.getLocation();
697         int lastIndex = path.replace( '\\', '/' ).lastIndexOf( '/' );
698         stagingRepository.setLocation( path.substring( 0, lastIndex ) + "/" + stagingRepository.getId() );
699 
700         if ( StringUtils.isNotBlank( repository.getIndexDir() ) )
701         {
702             File indexDir = new File( repository.getIndexDir() );
703             // in case of absolute dir do not use the same
704             if ( indexDir.isAbsolute() )
705             {
706                 stagingRepository.setIndexDir( stagingRepository.getLocation() + "/.index" );
707             }
708             else
709             {
710                 stagingRepository.setIndexDir( repository.getIndexDir() );
711             }
712         }
713         stagingRepository.setRefreshCronExpression( repository.getRefreshCronExpression() );
714         stagingRepository.setReleases( repository.isReleases() );
715         stagingRepository.setRetentionCount( repository.getRetentionCount() );
716         stagingRepository.setScanned( repository.isScanned() );
717         stagingRepository.setSnapshots( repository.isSnapshots() );
718         stagingRepository.setSkipPackedIndexCreation( repository.isSkipPackedIndexCreation() );
719         // do not duplicate description
720         //stagingRepository.getDescription("")
721         return stagingRepository;
722     }
723 
724     public Boolean scanRepository( String repositoryId, boolean fullScan )
725     {
726         if ( getRepositoryTaskScheduler().isProcessingRepositoryTask( repositoryId ) )
727         {
728             log.info( "scanning of repository with id {} already scheduled", repositoryId );
729         }
730         RepositoryTask task = new RepositoryTask();
731         task.setRepositoryId( repositoryId );
732         task.setScanAll( fullScan );
733         try
734         {
735             getRepositoryTaskScheduler().queueTask( task );
736         }
737         catch ( TaskQueueException e )
738         {
739             log.error( "failed to schedule scanning of repo with id {}", repositoryId, e );
740             return false;
741         }
742         return true;
743     }
744 
745 
746     private void addRepositoryRoles( String repoId )
747         throws RoleManagerException
748     {
749         // TODO: double check these are configured on start up
750         // TODO: belongs in the business logic
751 
752         if ( !getRoleManager().templatedRoleExists( ArchivaRoleConstants.TEMPLATE_REPOSITORY_OBSERVER, repoId ) )
753         {
754             getRoleManager().createTemplatedRole( ArchivaRoleConstants.TEMPLATE_REPOSITORY_OBSERVER, repoId );
755         }
756 
757         if ( !getRoleManager().templatedRoleExists( ArchivaRoleConstants.TEMPLATE_REPOSITORY_MANAGER, repoId ) )
758         {
759             getRoleManager().createTemplatedRole( ArchivaRoleConstants.TEMPLATE_REPOSITORY_MANAGER, repoId );
760         }
761     }
762 
763     protected void removeRepositoryRoles( ManagedRepositoryConfiguration existingRepository )
764         throws RoleManagerException
765     {
766         String repoId = existingRepository.getId();
767 
768         if ( getRoleManager().templatedRoleExists( ArchivaRoleConstants.TEMPLATE_REPOSITORY_MANAGER, repoId ) )
769         {
770             getRoleManager().removeTemplatedRole( ArchivaRoleConstants.TEMPLATE_REPOSITORY_MANAGER, repoId );
771         }
772 
773         if ( getRoleManager().templatedRoleExists( ArchivaRoleConstants.TEMPLATE_REPOSITORY_OBSERVER, repoId ) )
774         {
775             getRoleManager().removeTemplatedRole( ArchivaRoleConstants.TEMPLATE_REPOSITORY_OBSERVER, repoId );
776         }
777 
778         log.debug( "removed user roles associated with repository {}", repoId );
779     }
780 
781     //--------------------------
782     // setters/getters
783     //--------------------------
784 
785 
786     public RoleManager getRoleManager()
787     {
788         return roleManager;
789     }
790 
791     public void setRoleManager( RoleManager roleManager )
792     {
793         this.roleManager = roleManager;
794     }
795 
796     public RepositoryStatisticsManager getRepositoryStatisticsManager()
797     {
798         return repositoryStatisticsManager;
799     }
800 
801     public void setRepositoryStatisticsManager( RepositoryStatisticsManager repositoryStatisticsManager )
802     {
803         this.repositoryStatisticsManager = repositoryStatisticsManager;
804     }
805 
806     public RepositorySessionFactory getRepositorySessionFactory()
807     {
808         return repositorySessionFactory;
809     }
810 
811     public void setRepositorySessionFactory( RepositorySessionFactory repositorySessionFactory )
812     {
813         this.repositorySessionFactory = repositorySessionFactory;
814     }
815 
816 
817     public RepositoryArchivaTaskScheduler getRepositoryTaskScheduler()
818     {
819         return repositoryTaskScheduler;
820     }
821 
822     public void setRepositoryTaskScheduler( RepositoryArchivaTaskScheduler repositoryTaskScheduler )
823     {
824         this.repositoryTaskScheduler = repositoryTaskScheduler;
825     }
826 
827     public PlexusSisuBridge getPlexusSisuBridge()
828     {
829         return plexusSisuBridge;
830     }
831 
832     public void setPlexusSisuBridge( PlexusSisuBridge plexusSisuBridge )
833     {
834         this.plexusSisuBridge = plexusSisuBridge;
835     }
836 
837     public MavenIndexerUtils getMavenIndexerUtils()
838     {
839         return mavenIndexerUtils;
840     }
841 
842     public void setMavenIndexerUtils( MavenIndexerUtils mavenIndexerUtils )
843     {
844         this.mavenIndexerUtils = mavenIndexerUtils;
845     }
846 
847     public NexusIndexer getIndexer()
848     {
849         return indexer;
850     }
851 
852     public void setIndexer( NexusIndexer indexer )
853     {
854         this.indexer = indexer;
855     }
856 
857     public List<? extends IndexCreator> getIndexCreators()
858     {
859         return indexCreators;
860     }
861 
862     public void setIndexCreators( List<? extends IndexCreator> indexCreators )
863     {
864         this.indexCreators = indexCreators;
865     }
866 }