001 package org.apache.archiva.admin.repository.group; 002 /* 003 * Licensed to the Apache Software Foundation (ASF) under one 004 * or more contributor license agreements. See the NOTICE file 005 * distributed with this work for additional information 006 * regarding copyright ownership. The ASF licenses this file 007 * to you under the Apache License, Version 2.0 (the 008 * "License"); you may not use this file except in compliance 009 * with the License. You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, 014 * software distributed under the License is distributed on an 015 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 016 * KIND, either express or implied. See the License for the 017 * specific language governing permissions and limitations 018 * under the License. 019 */ 020 021 import org.apache.archiva.admin.model.AuditInformation; 022 import org.apache.archiva.admin.model.RepositoryAdminException; 023 import org.apache.archiva.admin.model.beans.ManagedRepository; 024 import org.apache.archiva.admin.model.beans.RepositoryGroup; 025 import org.apache.archiva.admin.model.group.RepositoryGroupAdmin; 026 import org.apache.archiva.admin.model.managed.ManagedRepositoryAdmin; 027 import org.apache.archiva.admin.repository.AbstractRepositoryAdmin; 028 import org.apache.archiva.audit.AuditEvent; 029 import org.apache.archiva.configuration.Configuration; 030 import org.apache.archiva.configuration.RepositoryGroupConfiguration; 031 import org.apache.commons.lang.StringUtils; 032 import org.slf4j.Logger; 033 import org.slf4j.LoggerFactory; 034 import org.springframework.stereotype.Service; 035 036 import javax.inject.Inject; 037 import java.util.ArrayList; 038 import java.util.Arrays; 039 import java.util.HashMap; 040 import java.util.List; 041 import java.util.Map; 042 import java.util.regex.Matcher; 043 import java.util.regex.Pattern; 044 045 /** 046 * @author Olivier Lamy 047 */ 048 @Service("repositoryGroupAdmin#default") 049 public class DefaultRepositoryGroupAdmin 050 extends AbstractRepositoryAdmin 051 implements RepositoryGroupAdmin 052 { 053 054 private Logger log = LoggerFactory.getLogger( getClass() ); 055 056 private static final Pattern REPO_GROUP_ID_PATTERN = Pattern.compile( "[A-Za-z0-9\\._\\-]+" ); 057 058 @Inject 059 private ManagedRepositoryAdmin managedRepositoryAdmin; 060 061 public List<RepositoryGroup> getRepositoriesGroups() 062 throws RepositoryAdminException 063 { 064 List<RepositoryGroup> repositoriesGroups = 065 new ArrayList<RepositoryGroup>( getArchivaConfiguration().getConfiguration().getRepositoryGroups().size() ); 066 067 for ( RepositoryGroupConfiguration repositoryGroupConfiguration : getArchivaConfiguration().getConfiguration().getRepositoryGroups() ) 068 { 069 repositoriesGroups.add( new RepositoryGroup( repositoryGroupConfiguration.getId(), new ArrayList<String>( 070 repositoryGroupConfiguration.getRepositories() ) ).mergedIndexPath( 071 repositoryGroupConfiguration.getMergedIndexPath() ).mergedIndexTtl( repositoryGroupConfiguration.getMergedIndexTtl() ) ); 072 } 073 074 return repositoriesGroups; 075 } 076 077 public RepositoryGroup getRepositoryGroup( String repositoryGroupId ) 078 throws RepositoryAdminException 079 { 080 List<RepositoryGroup> repositoriesGroups = getRepositoriesGroups(); 081 for ( RepositoryGroup repositoryGroup : repositoriesGroups ) 082 { 083 if ( StringUtils.equals( repositoryGroupId, repositoryGroup.getId() ) ) 084 { 085 return repositoryGroup; 086 } 087 } 088 return null; 089 } 090 091 public Boolean addRepositoryGroup( RepositoryGroup repositoryGroup, AuditInformation auditInformation ) 092 throws RepositoryAdminException 093 { 094 validateRepositoryGroup( repositoryGroup, false ); 095 validateManagedRepositoriesExists( repositoryGroup.getRepositories() ); 096 097 RepositoryGroupConfiguration repositoryGroupConfiguration = new RepositoryGroupConfiguration(); 098 repositoryGroupConfiguration.setId( repositoryGroup.getId() ); 099 repositoryGroupConfiguration.setRepositories( repositoryGroup.getRepositories() ); 100 repositoryGroupConfiguration.setMergedIndexPath( repositoryGroup.getMergedIndexPath() ); 101 repositoryGroupConfiguration.setMergedIndexTtl( repositoryGroup.getMergedIndexTtl() ); 102 Configuration configuration = getArchivaConfiguration().getConfiguration(); 103 configuration.addRepositoryGroup( repositoryGroupConfiguration ); 104 saveConfiguration( configuration ); 105 triggerAuditEvent( repositoryGroup.getId(), null, AuditEvent.ADD_REPO_GROUP, auditInformation ); 106 return Boolean.TRUE; 107 } 108 109 public Boolean deleteRepositoryGroup( String repositoryGroupId, AuditInformation auditInformation ) 110 throws RepositoryAdminException 111 { 112 Configuration configuration = getArchivaConfiguration().getConfiguration(); 113 RepositoryGroupConfiguration repositoryGroupConfiguration = 114 configuration.getRepositoryGroupsAsMap().get( repositoryGroupId ); 115 if ( repositoryGroupConfiguration == null ) 116 { 117 throw new RepositoryAdminException( 118 "repositoryGroup with id " + repositoryGroupId + " doesn't not exists so cannot remove" ); 119 } 120 configuration.removeRepositoryGroup( repositoryGroupConfiguration ); 121 triggerAuditEvent( repositoryGroupId, null, AuditEvent.DELETE_REPO_GROUP, auditInformation ); 122 return Boolean.TRUE; 123 } 124 125 public Boolean updateRepositoryGroup( RepositoryGroup repositoryGroup, AuditInformation auditInformation ) 126 throws RepositoryAdminException 127 { 128 return updateRepositoryGroup( repositoryGroup, auditInformation, true ); 129 } 130 131 private Boolean updateRepositoryGroup( RepositoryGroup repositoryGroup, AuditInformation auditInformation, 132 boolean triggerAuditEvent ) 133 throws RepositoryAdminException 134 { 135 validateRepositoryGroup( repositoryGroup, true ); 136 validateManagedRepositoriesExists( repositoryGroup.getRepositories() ); 137 Configuration configuration = getArchivaConfiguration().getConfiguration(); 138 139 RepositoryGroupConfiguration repositoryGroupConfiguration = 140 configuration.getRepositoryGroupsAsMap().get( repositoryGroup.getId() ); 141 142 configuration.removeRepositoryGroup( repositoryGroupConfiguration ); 143 144 repositoryGroupConfiguration.setRepositories( repositoryGroup.getRepositories() ); 145 repositoryGroupConfiguration.setMergedIndexPath( repositoryGroup.getMergedIndexPath() ); 146 repositoryGroupConfiguration.setMergedIndexTtl( repositoryGroup.getMergedIndexTtl() ); 147 configuration.addRepositoryGroup( repositoryGroupConfiguration ); 148 149 saveConfiguration( configuration ); 150 if ( triggerAuditEvent ) 151 { 152 triggerAuditEvent( repositoryGroup.getId(), null, AuditEvent.MODIFY_REPO_GROUP, auditInformation ); 153 } 154 return Boolean.TRUE; 155 } 156 157 158 public Boolean addRepositoryToGroup( String repositoryGroupId, String repositoryId, 159 AuditInformation auditInformation ) 160 throws RepositoryAdminException 161 { 162 RepositoryGroup repositoryGroup = getRepositoryGroup( repositoryGroupId ); 163 if ( repositoryGroup == null ) 164 { 165 throw new RepositoryAdminException( 166 "repositoryGroup with id " + repositoryGroupId + " doesn't not exists so cannot add repository to it" ); 167 } 168 169 if ( repositoryGroup.getRepositories().contains( repositoryId ) ) 170 { 171 throw new RepositoryAdminException( 172 "repositoryGroup with id " + repositoryGroupId + " already contain repository with id" + repositoryId ); 173 } 174 validateManagedRepositoriesExists( Arrays.asList( repositoryId ) ); 175 176 repositoryGroup.addRepository( repositoryId ); 177 updateRepositoryGroup( repositoryGroup, auditInformation, false ); 178 triggerAuditEvent( repositoryGroup.getId(), null, AuditEvent.ADD_REPO_TO_GROUP, auditInformation ); 179 return Boolean.TRUE; 180 } 181 182 public Boolean deleteRepositoryFromGroup( String repositoryGroupId, String repositoryId, 183 AuditInformation auditInformation ) 184 throws RepositoryAdminException 185 { 186 RepositoryGroup repositoryGroup = getRepositoryGroup( repositoryGroupId ); 187 if ( repositoryGroup == null ) 188 { 189 throw new RepositoryAdminException( "repositoryGroup with id " + repositoryGroupId 190 + " doesn't not exists so cannot remove repository from it" ); 191 } 192 193 if ( !repositoryGroup.getRepositories().contains( repositoryId ) ) 194 { 195 throw new RepositoryAdminException( 196 "repositoryGroup with id " + repositoryGroupId + " doesn't not contains repository with id" 197 + repositoryId ); 198 } 199 200 repositoryGroup.removeRepository( repositoryId ); 201 updateRepositoryGroup( repositoryGroup, auditInformation, false ); 202 triggerAuditEvent( repositoryGroup.getId(), null, AuditEvent.DELETE_REPO_FROM_GROUP, auditInformation ); 203 return Boolean.TRUE; 204 } 205 206 public Map<String, RepositoryGroup> getRepositoryGroupsAsMap() 207 throws RepositoryAdminException 208 { 209 List<RepositoryGroup> repositoriesGroups = getRepositoriesGroups(); 210 Map<String, RepositoryGroup> map = new HashMap<String, RepositoryGroup>( repositoriesGroups.size() ); 211 for ( RepositoryGroup repositoryGroup : repositoriesGroups ) 212 { 213 map.put( repositoryGroup.getId(), repositoryGroup ); 214 } 215 return map; 216 } 217 218 public Map<String, List<String>> getGroupToRepositoryMap() 219 throws RepositoryAdminException 220 { 221 222 java.util.Map<String, java.util.List<String>> map = new java.util.HashMap<String, java.util.List<String>>(); 223 224 for ( ManagedRepository repo : getManagedRepositoryAdmin().getManagedRepositories() ) 225 { 226 for ( RepositoryGroup group : getRepositoriesGroups() ) 227 { 228 if ( !group.getRepositories().contains( repo.getId() ) ) 229 { 230 String groupId = group.getId(); 231 java.util.List<String> repos = map.get( groupId ); 232 if ( repos == null ) 233 { 234 repos = new ArrayList<String>(); 235 map.put( groupId, repos ); 236 } 237 repos.add( repo.getId() ); 238 } 239 } 240 } 241 return map; 242 } 243 244 public Map<String, List<String>> getRepositoryToGroupMap() 245 throws RepositoryAdminException 246 { 247 java.util.Map<String, java.util.List<String>> map = new java.util.HashMap<String, java.util.List<String>>(); 248 249 for ( RepositoryGroup group : getRepositoriesGroups() ) 250 { 251 for ( String repositoryId : group.getRepositories() ) 252 { 253 java.util.List<String> groups = map.get( repositoryId ); 254 if ( groups == null ) 255 { 256 groups = new ArrayList<String>(); 257 map.put( repositoryId, groups ); 258 } 259 groups.add( group.getId() ); 260 } 261 } 262 return map; 263 } 264 265 public Boolean validateRepositoryGroup( RepositoryGroup repositoryGroup, boolean updateMode ) 266 throws RepositoryAdminException 267 { 268 String repoGroupId = repositoryGroup.getId(); 269 if ( StringUtils.isBlank( repoGroupId ) ) 270 { 271 throw new RepositoryAdminException( "repositoryGroup id cannot be empty" ); 272 } 273 274 if ( repoGroupId.length() > 100 ) 275 { 276 throw new RepositoryAdminException( 277 "Identifier [" + repoGroupId + "] is over the maximum limit of 100 characters" ); 278 279 } 280 281 Matcher matcher = REPO_GROUP_ID_PATTERN.matcher( repoGroupId ); 282 if ( !matcher.matches() ) 283 { 284 throw new RepositoryAdminException( 285 "Invalid character(s) found in identifier. Only the following characters are allowed: alphanumeric, '.', '-' and '_'" ); 286 } 287 288 if ( repositoryGroup.getMergedIndexTtl() <= 0) 289 { 290 throw new RepositoryAdminException( "Merged Index TTL must be greater than 0." ); 291 } 292 293 Configuration configuration = getArchivaConfiguration().getConfiguration(); 294 295 if ( configuration.getRepositoryGroupsAsMap().containsKey( repoGroupId ) ) 296 { 297 if ( !updateMode ) 298 { 299 throw new RepositoryAdminException( "Unable to add new repository group with id [" + repoGroupId 300 + "], that id already exists as a repository group." ); 301 } 302 } 303 else if ( configuration.getManagedRepositoriesAsMap().containsKey( repoGroupId ) ) 304 { 305 throw new RepositoryAdminException( "Unable to add new repository group with id [" + repoGroupId 306 + "], that id already exists as a managed repository." ); 307 } 308 else if ( configuration.getRemoteRepositoriesAsMap().containsKey( repoGroupId ) ) 309 { 310 throw new RepositoryAdminException( "Unable to add new repository group with id [" + repoGroupId 311 + "], that id already exists as a remote repository." ); 312 } 313 314 return Boolean.TRUE; 315 } 316 317 private void validateManagedRepositoriesExists( List<String> managedRepositoriesIds ) 318 throws RepositoryAdminException 319 { 320 for ( String id : managedRepositoriesIds ) 321 { 322 if ( getManagedRepositoryAdmin().getManagedRepository( id ) == null ) 323 { 324 throw new RepositoryAdminException( 325 "managedRepository with id " + id + " not exists so cannot be used in a repositoryGroup" ); 326 } 327 } 328 } 329 330 public ManagedRepositoryAdmin getManagedRepositoryAdmin() 331 { 332 return managedRepositoryAdmin; 333 } 334 335 public void setManagedRepositoryAdmin( ManagedRepositoryAdmin managedRepositoryAdmin ) 336 { 337 this.managedRepositoryAdmin = managedRepositoryAdmin; 338 } 339 }