001package org.apache.archiva.repository; 002 003/* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022import org.apache.archiva.configuration.ArchivaConfiguration; 023import org.apache.archiva.configuration.ConfigurationNames; 024import org.apache.archiva.components.registry.Registry; 025import org.apache.archiva.components.registry.RegistryListener; 026import org.springframework.context.ApplicationContext; 027import org.springframework.stereotype.Service; 028 029import javax.annotation.PostConstruct; 030import javax.inject.Inject; 031import java.util.List; 032import java.util.Map; 033import java.util.concurrent.ConcurrentHashMap; 034 035/** 036 * RepositoryContentRequest 037 */ 038@Service( "repositoryContentFactory#default" ) 039public class RepositoryContentFactory 040 implements RegistryListener 041{ 042 /** 043 * 044 */ 045 @Inject 046 private ArchivaConfiguration archivaConfiguration; 047 048 @Inject 049 private ApplicationContext applicationContext; 050 051 @Inject 052 private List<RepositoryContentProvider> repositoryContentProviders; 053 054 private final Map<String, ManagedRepositoryContent> managedContentMap; 055 056 private final Map<String, RemoteRepositoryContent> remoteContentMap; 057 058 059 public RepositoryContentFactory( ) 060 { 061 managedContentMap = new ConcurrentHashMap<String, ManagedRepositoryContent>( ); 062 remoteContentMap = new ConcurrentHashMap<String, RemoteRepositoryContent>( ); 063 } 064 065 /** 066 * Get the ManagedRepositoryContent object for the repository Id specified. 067 * 068 * @param repoId the repository id to fetch. 069 * @return the ManagedRepositoryContent object associated with the repository id. 070 * @throws RepositoryNotFoundException if the repository id does not exist within the configuration. 071 * @throws RepositoryException the repository content object cannot be loaded due to configuration issue. 072 */ 073 public ManagedRepositoryContent getManagedRepositoryContent( String repoId ) 074 throws RepositoryException 075 { 076 ManagedRepositoryContent repo = managedContentMap.get( repoId ); 077 078 if ( repo != null ) 079 { 080 return repo; 081 } 082 else 083 { 084 throw new RepositoryNotFoundException( 085 "Unable to find managed repository configuration for id " + repoId ); 086 } 087 088 } 089 090 private RepositoryContentProvider getProvider(final String layout, final RepositoryType repoType) throws RepositoryException 091 { 092 return repositoryContentProviders.stream().filter(p->p.supports( repoType ) && p.supportsLayout( layout )). 093 findFirst().orElseThrow( ( ) -> new RepositoryException( "Could not find content provider for repository type "+repoType+" and layout "+layout ) ); 094 } 095 096 public ManagedRepositoryContent getManagedRepositoryContent( org.apache.archiva.repository.ManagedRepository mRepo ) 097 throws RepositoryException 098 { 099 final String id = mRepo.getId(); 100 ManagedRepositoryContent content = managedContentMap.get( id ); 101 102 if ( content != null && content.getRepository()==mRepo) 103 { 104 return content; 105 } 106 107 RepositoryContentProvider contentProvider = getProvider( mRepo.getLayout( ), mRepo.getType( ) ); 108 content = contentProvider.createManagedContent( mRepo ); 109 if (content==null) { 110 throw new RepositoryException( "Could not create repository content instance for "+mRepo.getId() ); 111 } 112 ManagedRepositoryContent previousContent = managedContentMap.put( id, content ); 113 if (previousContent!=null) { 114 previousContent.setRepository( null ); 115 } 116 117 return content; 118 } 119 120 public RemoteRepositoryContent getRemoteRepositoryContent( String repoId ) 121 throws RepositoryException 122 { 123 RemoteRepositoryContent repo = remoteContentMap.get( repoId ); 124 125 if ( repo != null ) 126 { 127 return repo; 128 } 129 else 130 { 131 throw new RepositoryNotFoundException( 132 "Unable to find remote repository configuration for id:" + repoId ); 133 } 134 135 } 136 137 public RemoteRepositoryContent getRemoteRepositoryContent( RemoteRepository mRepo ) 138 throws RepositoryException 139 { 140 final String id = mRepo.getId(); 141 RemoteRepositoryContent content = remoteContentMap.get( id ); 142 143 if ( content != null && content.getRepository()==mRepo) 144 { 145 return content; 146 } 147 148 RepositoryContentProvider contentProvider = getProvider( mRepo.getLayout( ), mRepo.getType( ) ); 149 content = contentProvider.createRemoteContent( mRepo ); 150 if (content==null) { 151 throw new RepositoryException( "Could not create repository content instance for "+mRepo.getId() ); 152 } 153 RemoteRepositoryContent previousContent = remoteContentMap.put( id, content ); 154 if (previousContent!=null) { 155 previousContent.setRepository( null ); 156 } 157 return content; 158 } 159 160 161 @Override 162 public void afterConfigurationChange( Registry registry, String propertyName, Object propertyValue ) 163 { 164 if ( ConfigurationNames.isManagedRepositories( propertyName ) || ConfigurationNames.isRemoteRepositories( 165 propertyName ) ) 166 { 167 initMaps( ); 168 } 169 } 170 171 @Override 172 public void beforeConfigurationChange( Registry registry, String propertyName, Object propertyValue ) 173 { 174 /* do nothing */ 175 } 176 177 @PostConstruct 178 public void initialize( ) 179 { 180 archivaConfiguration.addChangeListener( this ); 181 } 182 183 private void initMaps( ) 184 { 185 // olamy we use concurent so no need of synchronize 186 //synchronized ( managedContentMap ) 187 //{ 188 managedContentMap.clear( ); 189 //} 190 191 //synchronized ( remoteContentMap ) 192 //{ 193 remoteContentMap.clear( ); 194 //} 195 } 196 197 public ArchivaConfiguration getArchivaConfiguration( ) 198 { 199 return archivaConfiguration; 200 } 201 202 public void setArchivaConfiguration( ArchivaConfiguration archivaConfiguration ) 203 { 204 this.archivaConfiguration = archivaConfiguration; 205 } 206 207 public void setRepositoryContentProviders(List<RepositoryContentProvider> providers) { 208 this.repositoryContentProviders = providers; 209 } 210 211 public List<RepositoryContentProvider> getRepositoryContentProviders() { 212 return repositoryContentProviders; 213 } 214}