001package org.eclipse.aether.util.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 java.io.File; 023import java.nio.file.Files; 024import java.nio.file.Path; 025import java.util.List; 026 027import org.eclipse.aether.RepositorySystemSession; 028import org.eclipse.aether.artifact.Artifact; 029import org.eclipse.aether.metadata.Metadata; 030import org.eclipse.aether.repository.LocalArtifactRegistration; 031import org.eclipse.aether.repository.LocalArtifactRequest; 032import org.eclipse.aether.repository.LocalArtifactResult; 033import org.eclipse.aether.repository.LocalMetadataRegistration; 034import org.eclipse.aether.repository.LocalMetadataRequest; 035import org.eclipse.aether.repository.LocalMetadataResult; 036import org.eclipse.aether.repository.LocalRepository; 037import org.eclipse.aether.repository.LocalRepositoryManager; 038import org.eclipse.aether.repository.RemoteRepository; 039 040import static java.util.Objects.requireNonNull; 041import static java.util.stream.Collectors.toList; 042 043/** 044 * A local repository manager that chains multiple local repository managers: it directs all the write operations 045 * to chain head, while uses tail for {@link #find(RepositorySystemSession, LocalArtifactRequest)} and 046 * {@link #find(RepositorySystemSession, LocalMetadataRequest)} methods only. Hence, tail is used in resolving 047 * metadata and artifacts with or without (configurable) artifact availability tracking. 048 * <p> 049 * Implementation represents itself using the head local repository manager. 050 * 051 * @since 1.9.2 052 */ 053public final class ChainedLocalRepositoryManager 054 implements LocalRepositoryManager 055{ 056 private final LocalRepositoryManager head; 057 058 private final List<LocalRepositoryManager> tail; 059 060 private final boolean ignoreTailAvailability; 061 062 public ChainedLocalRepositoryManager( LocalRepositoryManager head, 063 List<LocalRepositoryManager> tail, 064 boolean ignoreTailAvailability ) 065 { 066 this.head = requireNonNull( head, "head cannot be null" ); 067 this.tail = requireNonNull( tail, "tail cannot be null" ); 068 this.ignoreTailAvailability = ignoreTailAvailability; 069 } 070 071 @Override 072 public LocalRepository getRepository() 073 { 074 return head.getRepository(); 075 } 076 077 @Override 078 public String getPathForLocalArtifact( Artifact artifact ) 079 { 080 return head.getPathForLocalArtifact( artifact ); 081 } 082 083 @Override 084 public String getPathForRemoteArtifact( Artifact artifact, RemoteRepository repository, String context ) 085 { 086 return head.getPathForRemoteArtifact( artifact, repository, context ); 087 } 088 089 @Override 090 public String getPathForLocalMetadata( Metadata metadata ) 091 { 092 return head.getPathForLocalMetadata( metadata ); 093 } 094 095 @Override 096 public String getPathForRemoteMetadata( Metadata metadata, RemoteRepository repository, String context ) 097 { 098 return head.getPathForRemoteMetadata( metadata, repository, context ); 099 } 100 101 @Override 102 public LocalArtifactResult find( RepositorySystemSession session, LocalArtifactRequest request ) 103 { 104 LocalArtifactResult result = head.find( session, request ); 105 if ( result.isAvailable() ) 106 { 107 return result; 108 } 109 110 for ( LocalRepositoryManager lrm : tail ) 111 { 112 result = lrm.find( session, request ); 113 if ( result.getFile() != null ) 114 { 115 if ( ignoreTailAvailability ) 116 { 117 result.setAvailable( true ); 118 return result; 119 } 120 else if ( result.isAvailable() ) 121 { 122 return result; 123 } 124 } 125 } 126 return new LocalArtifactResult( request ); 127 } 128 129 @Override 130 public void add( RepositorySystemSession session, LocalArtifactRegistration request ) 131 { 132 String artifactPath; 133 if ( request.getRepository() != null ) 134 { 135 artifactPath = getPathForRemoteArtifact( request.getArtifact(), request.getRepository(), "check" ); 136 } 137 else 138 { 139 artifactPath = getPathForLocalArtifact( request.getArtifact() ); 140 } 141 142 Path file = new File( head.getRepository().getBasedir(), artifactPath ).toPath(); 143 if ( Files.isRegularFile( file ) ) 144 { 145 head.add( session, request ); 146 } 147 } 148 149 @Override 150 public LocalMetadataResult find( RepositorySystemSession session, LocalMetadataRequest request ) 151 { 152 LocalMetadataResult result = head.find( session, request ); 153 if ( result.getFile() != null ) 154 { 155 return result; 156 } 157 158 for ( LocalRepositoryManager lrm : tail ) 159 { 160 result = lrm.find( session, request ); 161 if ( result.getFile() != null ) 162 { 163 return result; 164 } 165 } 166 return new LocalMetadataResult( request ); 167 } 168 169 @Override 170 public void add( RepositorySystemSession session, LocalMetadataRegistration request ) 171 { 172 String metadataPath; 173 if ( request.getRepository() != null ) 174 { 175 metadataPath = getPathForRemoteMetadata( request.getMetadata(), request.getRepository(), "check" ); 176 } 177 else 178 { 179 metadataPath = getPathForLocalMetadata( request.getMetadata() ); 180 } 181 182 Path file = new File( head.getRepository().getBasedir(), metadataPath ).toPath(); 183 if ( Files.isRegularFile( file ) ) 184 { 185 head.add( session, request ); 186 } 187 } 188 189 @Override 190 public String toString() 191 { 192 return head.getRepository().toString() 193 + tail.stream().map( LocalRepositoryManager::getRepository ).collect( toList() ); 194 } 195}