001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.eclipse.aether.util.repository; 020 021import java.io.File; 022import java.nio.file.Files; 023import java.nio.file.Path; 024import java.util.List; 025 026import org.eclipse.aether.RepositorySystemSession; 027import org.eclipse.aether.artifact.Artifact; 028import org.eclipse.aether.metadata.Metadata; 029import org.eclipse.aether.repository.LocalArtifactRegistration; 030import org.eclipse.aether.repository.LocalArtifactRequest; 031import org.eclipse.aether.repository.LocalArtifactResult; 032import org.eclipse.aether.repository.LocalMetadataRegistration; 033import org.eclipse.aether.repository.LocalMetadataRequest; 034import org.eclipse.aether.repository.LocalMetadataResult; 035import org.eclipse.aether.repository.LocalRepository; 036import org.eclipse.aether.repository.LocalRepositoryManager; 037import org.eclipse.aether.repository.RemoteRepository; 038 039import static java.util.Objects.requireNonNull; 040import static java.util.stream.Collectors.toList; 041 042/** 043 * A local repository manager that chains multiple local repository managers: it directs all the write operations 044 * to chain head, while uses tail for {@link #find(RepositorySystemSession, LocalArtifactRequest)} and 045 * {@link #find(RepositorySystemSession, LocalMetadataRequest)} methods only. Hence, tail is used in resolving 046 * metadata and artifacts with or without (configurable) artifact availability tracking. 047 * <p> 048 * Implementation represents itself using the head local repository manager. 049 * 050 * @since 1.9.2 051 */ 052public final class ChainedLocalRepositoryManager implements LocalRepositoryManager { 053 private final LocalRepositoryManager head; 054 055 private final List<LocalRepositoryManager> tail; 056 057 private final boolean ignoreTailAvailability; 058 059 public ChainedLocalRepositoryManager( 060 LocalRepositoryManager head, List<LocalRepositoryManager> tail, boolean ignoreTailAvailability) { 061 this.head = requireNonNull(head, "head cannot be null"); 062 this.tail = requireNonNull(tail, "tail cannot be null"); 063 this.ignoreTailAvailability = ignoreTailAvailability; 064 } 065 066 @Override 067 public LocalRepository getRepository() { 068 return head.getRepository(); 069 } 070 071 @Override 072 public String getPathForLocalArtifact(Artifact artifact) { 073 return head.getPathForLocalArtifact(artifact); 074 } 075 076 @Override 077 public String getPathForRemoteArtifact(Artifact artifact, RemoteRepository repository, String context) { 078 return head.getPathForRemoteArtifact(artifact, repository, context); 079 } 080 081 @Override 082 public String getPathForLocalMetadata(Metadata metadata) { 083 return head.getPathForLocalMetadata(metadata); 084 } 085 086 @Override 087 public String getPathForRemoteMetadata(Metadata metadata, RemoteRepository repository, String context) { 088 return head.getPathForRemoteMetadata(metadata, repository, context); 089 } 090 091 @Override 092 public LocalArtifactResult find(RepositorySystemSession session, LocalArtifactRequest request) { 093 LocalArtifactResult result = head.find(session, request); 094 if (result.isAvailable()) { 095 return result; 096 } 097 098 for (LocalRepositoryManager lrm : tail) { 099 result = lrm.find(session, request); 100 if (result.getFile() != null) { 101 if (ignoreTailAvailability) { 102 result.setAvailable(true); 103 return result; 104 } else if (result.isAvailable()) { 105 return result; 106 } 107 } 108 } 109 return new LocalArtifactResult(request); 110 } 111 112 @Override 113 public void add(RepositorySystemSession session, LocalArtifactRegistration request) { 114 String artifactPath; 115 if (request.getRepository() != null) { 116 artifactPath = getPathForRemoteArtifact(request.getArtifact(), request.getRepository(), "check"); 117 } else { 118 artifactPath = getPathForLocalArtifact(request.getArtifact()); 119 } 120 121 Path file = new File(head.getRepository().getBasedir(), artifactPath).toPath(); 122 if (Files.isRegularFile(file)) { 123 head.add(session, request); 124 } 125 } 126 127 @Override 128 public LocalMetadataResult find(RepositorySystemSession session, LocalMetadataRequest request) { 129 LocalMetadataResult result = head.find(session, request); 130 if (result.getFile() != null) { 131 return result; 132 } 133 134 for (LocalRepositoryManager lrm : tail) { 135 result = lrm.find(session, request); 136 if (result.getFile() != null) { 137 return result; 138 } 139 } 140 return new LocalMetadataResult(request); 141 } 142 143 @Override 144 public void add(RepositorySystemSession session, LocalMetadataRegistration request) { 145 String metadataPath; 146 if (request.getRepository() != null) { 147 metadataPath = getPathForRemoteMetadata(request.getMetadata(), request.getRepository(), "check"); 148 } else { 149 metadataPath = getPathForLocalMetadata(request.getMetadata()); 150 } 151 152 Path file = new File(head.getRepository().getBasedir(), metadataPath).toPath(); 153 if (Files.isRegularFile(file)) { 154 head.add(session, request); 155 } 156 } 157 158 @Override 159 public String toString() { 160 return head.getRepository().toString() 161 + tail.stream().map(LocalRepositoryManager::getRepository).collect(toList()); 162 } 163}