1 package org.apache.archiva.repository.base;
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
11 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
20 import org.apache.archiva.components.registry.RegistryException;
21 import org.apache.archiva.configuration.model.AbstractRepositoryConfiguration;
22 import org.apache.archiva.configuration.model.Configuration;
23 import org.apache.archiva.configuration.provider.IndeterminateConfigurationException;
24 import org.apache.archiva.event.Event;
25 import org.apache.archiva.event.EventManager;
26 import org.apache.archiva.event.EventType;
27 import org.apache.archiva.repository.EditableRepository;
28 import org.apache.archiva.repository.Repository;
29 import org.apache.archiva.repository.RepositoryException;
30 import org.apache.archiva.repository.RepositoryHandler;
31 import org.apache.archiva.repository.RepositoryProvider;
32 import org.apache.archiva.repository.RepositoryState;
33 import org.apache.archiva.repository.RepositoryType;
34 import org.apache.archiva.repository.event.LifecycleEvent;
35 import org.apache.archiva.repository.validation.CheckedResult;
36 import org.apache.archiva.repository.validation.CombinedValidator;
37 import org.apache.archiva.repository.validation.RepositoryChecker;
38 import org.apache.archiva.repository.validation.RepositoryValidator;
39 import org.apache.archiva.repository.validation.ValidationError;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
43 import java.util.Collection;
44 import java.util.Collections;
45 import java.util.HashMap;
46 import java.util.List;
48 import java.util.stream.Collectors;
51 * Base abstract class for repository handlers.
53 * @author Martin Stockhammer <martin_s@apache.org>
55 public abstract class AbstractRepositoryHandler<R extends Repository, C extends AbstractRepositoryConfiguration> implements RepositoryHandler<R, C>
58 private static final Logger log = LoggerFactory.getLogger( AbstractRepositoryHandler.class );
60 protected final Map<RepositoryType, RepositoryProvider> providerMap = new HashMap<>( );
61 private CombinedValidator<R> combinedValidator;
62 private final Class<R> repositoryClazz;
63 private final Class<C> configurationClazz;
64 private final EventManager eventManager;
65 private final Map<String, R> repositoryMap = new HashMap<>( );
66 private final ConfigurationHandler configurationHandler;
68 public AbstractRepositoryHandler(Class<R> repositoryClazz, Class<C> configurationClazz, ConfigurationHandler configurationHandler) {
69 this.repositoryClazz = repositoryClazz;
70 this.configurationClazz = configurationClazz;
71 this.eventManager = new EventManager( this );
72 this.configurationHandler = configurationHandler;
75 protected List<RepositoryValidator<R>> initValidators( Class<R> clazz, List<RepositoryValidator<? extends Repository>> repositoryGroupValidatorList )
77 if ( repositoryGroupValidatorList != null && repositoryGroupValidatorList.size( ) > 0 )
79 return repositoryGroupValidatorList.stream( ).filter(
80 v -> v.isFlavour( clazz )
81 ).map( v -> v.narrowTo( clazz ) ).collect( Collectors.toList( ) );
85 return Collections.emptyList( );
89 protected CombinedValidator<R> getCombinedValidator( Class<R> clazz, List<RepositoryValidator<? extends Repository>> repositoryGroupValidatorList )
91 return new CombinedValidator<>( clazz, initValidators( clazz, repositoryGroupValidatorList ) );
94 protected void setLastState( R repo, RepositoryState state )
96 RepositoryState currentState = repo.getLastState( );
97 if ( repo instanceof EditableRepository )
99 if ( state.getOrderNumber( ) > repo.getLastState( ).getOrderNumber( ) )
101 ( (EditableRepository) repo ).setLastState( state );
106 log.error( "Found a not editable repository instance: {}, {}", repo.getId( ), repo.getClass( ).getName( ) );
108 if (state == RepositoryState.REGISTERED && state != currentState ) {
109 pushEvent( LifecycleEvent.REGISTERED, repo );
110 } else if (state == RepositoryState.UNREGISTERED && state != currentState) {
111 pushEvent( LifecycleEvent.UNREGISTERED, repo );
116 public void setRepositoryProviders( List<RepositoryProvider> providers )
118 if ( providers != null )
120 for ( RepositoryProvider provider : providers )
122 for ( RepositoryType type : provider.provides( ) )
124 providerMap.put( type, provider );
130 protected RepositoryProvider getProvider(RepositoryType type) {
131 return providerMap.get( type );
135 public void setRepositoryValidator( List<RepositoryValidator<? extends Repository>> repositoryValidatorList )
137 this.combinedValidator = getCombinedValidator( repositoryClazz, repositoryValidatorList );
140 protected CombinedValidator<R> getCombinedValidator() {
141 return this.combinedValidator;
145 public Class<R> getVariant( )
147 return this.repositoryClazz;
151 public Class<C> getConfigurationVariant( )
153 return this.configurationClazz;
157 public void processOtherVariantRemoval( Repository repository )
159 // Default: do nothing
162 protected void pushEvent( Event event )
164 eventManager.fireEvent( event );
167 protected void pushEvent(EventType<? extends LifecycleEvent> event, R repo) {
168 pushEvent( new LifecycleEvent( event, this, repo ) );
171 protected Map<String, R> getRepositories() {
172 return repositoryMap;
175 protected ConfigurationHandler getConfigurationHandler() {
176 return configurationHandler;
180 public void activateRepository( R repository )
186 public void deactivateRepository( R repository )
192 public abstract R newInstance( C repositoryConfiguration ) throws RepositoryException;
195 public <D> CheckedResult<R, D> putWithCheck( C repositoryConfiguration, RepositoryChecker<R, D> checker ) throws RepositoryException
197 final String id = repositoryConfiguration.getId( );
198 R currentRepository = getRepositories().get( id );
199 R managedRepository = newInstance( repositoryConfiguration );
200 CheckedResult<R, D> result;
201 if ( currentRepository == null )
203 result = checker.apply( managedRepository );
207 result = checker.applyForUpdate( managedRepository );
209 if ( result.isValid( ) )
211 put( result.getRepository() );
218 public CheckedResult<R, Map<String, List<ValidationError>>> putWithCheck( C repositoryConfiguration ) throws RepositoryException
220 return putWithCheck( repositoryConfiguration, getValidator( ) );
223 protected abstract C findRepositoryConfiguration( Configuration configuration, String id);
225 protected abstract void removeRepositoryConfiguration(Configuration configuration, C repoConfiguration );
227 protected abstract void addRepositoryConfiguration( Configuration configuration, C repoConfiguration );
230 * Removes a repository group from the registry and configuration, if it exists.
231 * The change is saved to the configuration immediately.
233 * @param id the id of the repository group to remove
234 * @throws RepositoryException if an error occurs during configuration save
237 public void remove( String id ) throws RepositoryException
244 repo = getRepositories().remove( id );
247 deactivateRepository( repo );
248 Configuration configuration = this.configurationHandler.getBaseConfiguration( );
249 C cfg = findRepositoryConfiguration( configuration, id );
252 removeRepositoryConfiguration( configuration, cfg );
254 this.configurationHandler.save( configuration, ConfigurationHandler.REGISTRY_EVENT_TAG );
255 setLastState( repo, RepositoryState.UNREGISTERED );
259 catch ( RegistryException | IndeterminateConfigurationException e )
262 log.error( "Could not save config after repository removal: {}", e.getMessage( ), e );
263 getRepositories().put( repo.getId( ), repo );
264 throw new RepositoryException( "Could not save configuration after repository removal: " + e.getMessage( ) );
270 public void remove( String id, Configuration configuration ) throws RepositoryException
272 R repo = getRepositories().get( id );
275 repo = getRepositories().remove( id );
278 deactivateRepository( repo );
280 setLastState( repo, RepositoryState.UNREGISTERED );
282 C cfg = findRepositoryConfiguration(configuration, id );
285 removeRepositoryConfiguration(configuration, cfg );
290 public R get( String groupId )
292 return getRepositories().get( groupId );
296 public Collection<R> getAll( )
298 return Collections.unmodifiableCollection( getRepositories( ).values( ) );
302 public RepositoryValidator<R> getValidator( )
304 return getCombinedValidator();
308 public CheckedResult<R, Map<String, List<ValidationError>>> validateRepository( R repository )
310 return getCombinedValidator( ).apply( repository );
315 public CheckedResult<R,Map<String, List<ValidationError>>> validateRepositoryForUpdate( R repository )
317 return getCombinedValidator().applyForUpdate( repository );
320 public boolean hasRepository( String id )
322 return getRepositories().containsKey( id );
329 for ( R repository : getRepositories().values( ) )
333 deactivateRepository( repository );
335 catch ( Throwable e )
337 log.error( "Could not close repository {}: {}", repository.getId( ), e.getMessage( ) );
340 getRepositories().clear( );
343 protected void registerNewRepository( C repositoryGroupConfiguration, R currentRepository, Configuration configuration, boolean updated ) throws IndeterminateConfigurationException, RegistryException, RepositoryException
345 final String id = repositoryGroupConfiguration.getId( );
346 getConfigurationHandler().save( configuration, ConfigurationHandler.REGISTRY_EVENT_TAG );
347 updateReferences( currentRepository, repositoryGroupConfiguration );
350 setLastState( currentRepository, RepositoryState.REFERENCES_SET );
352 activateRepository( currentRepository );
353 getRepositories().put( id, currentRepository );
354 setLastState( currentRepository, RepositoryState.REGISTERED );
359 protected void rollback( Configuration configuration, R oldRepository, Exception e, C oldCfg ) throws RepositoryException
361 final String id = oldRepository.getId( );
362 replaceOrAddRepositoryConfig( oldCfg, configuration );
365 getConfigurationHandler().save( configuration, ConfigurationHandler.REGISTRY_EVENT_TAG );
367 catch ( IndeterminateConfigurationException | RegistryException indeterminateConfigurationException )
369 log.error( "Fatal error, config save during rollback failed: {}", e.getMessage( ), e );
371 updateReferences( oldRepository, oldCfg );
372 setLastState( oldRepository, RepositoryState.REFERENCES_SET );
373 activateRepository( oldRepository );
374 getRepositories().put( id, oldRepository );
375 setLastState( oldRepository, RepositoryState.REGISTERED );
378 protected void replaceOrAddRepositoryConfig( C repositoryGroupConfiguration, Configuration configuration )
380 C oldCfg = findRepositoryConfiguration( configuration, repositoryGroupConfiguration.getId( ) );
381 if ( oldCfg != null )
383 removeRepositoryConfiguration(configuration, oldCfg );
385 addRepositoryConfiguration( configuration, repositoryGroupConfiguration );