View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
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
17   * under the License.
18   */
19  package org.eclipse.aether.util.repository;
20  
21  import java.io.File;
22  import java.nio.file.Files;
23  import java.nio.file.Path;
24  import java.util.List;
25  
26  import org.eclipse.aether.RepositorySystemSession;
27  import org.eclipse.aether.artifact.Artifact;
28  import org.eclipse.aether.metadata.Metadata;
29  import org.eclipse.aether.repository.LocalArtifactRegistration;
30  import org.eclipse.aether.repository.LocalArtifactRequest;
31  import org.eclipse.aether.repository.LocalArtifactResult;
32  import org.eclipse.aether.repository.LocalMetadataRegistration;
33  import org.eclipse.aether.repository.LocalMetadataRequest;
34  import org.eclipse.aether.repository.LocalMetadataResult;
35  import org.eclipse.aether.repository.LocalRepository;
36  import org.eclipse.aether.repository.LocalRepositoryManager;
37  import org.eclipse.aether.repository.RemoteRepository;
38  
39  import static java.util.Objects.requireNonNull;
40  import static java.util.stream.Collectors.toList;
41  
42  /**
43   * A local repository manager that chains multiple local repository managers: it directs all the write operations
44   * to chain head, while uses tail for {@link #find(RepositorySystemSession, LocalArtifactRequest)} and
45   * {@link #find(RepositorySystemSession, LocalMetadataRequest)} methods only. Hence, tail is used in resolving
46   * metadata and artifacts with or without (configurable) artifact availability tracking.
47   * <p>
48   * Implementation represents itself using the head local repository manager.
49   *
50   * @since 1.9.2
51   */
52  public final class ChainedLocalRepositoryManager implements LocalRepositoryManager {
53      private final LocalRepositoryManager head;
54  
55      private final List<LocalRepositoryManager> tail;
56  
57      private final boolean ignoreTailAvailability;
58  
59      public ChainedLocalRepositoryManager(
60              LocalRepositoryManager head, List<LocalRepositoryManager> tail, boolean ignoreTailAvailability) {
61          this.head = requireNonNull(head, "head cannot be null");
62          this.tail = requireNonNull(tail, "tail cannot be null");
63          this.ignoreTailAvailability = ignoreTailAvailability;
64      }
65  
66      @Override
67      public LocalRepository getRepository() {
68          return head.getRepository();
69      }
70  
71      @Override
72      public String getPathForLocalArtifact(Artifact artifact) {
73          return head.getPathForLocalArtifact(artifact);
74      }
75  
76      @Override
77      public String getPathForRemoteArtifact(Artifact artifact, RemoteRepository repository, String context) {
78          return head.getPathForRemoteArtifact(artifact, repository, context);
79      }
80  
81      @Override
82      public String getPathForLocalMetadata(Metadata metadata) {
83          return head.getPathForLocalMetadata(metadata);
84      }
85  
86      @Override
87      public String getPathForRemoteMetadata(Metadata metadata, RemoteRepository repository, String context) {
88          return head.getPathForRemoteMetadata(metadata, repository, context);
89      }
90  
91      @Override
92      public LocalArtifactResult find(RepositorySystemSession session, LocalArtifactRequest request) {
93          LocalArtifactResult result = head.find(session, request);
94          if (result.isAvailable()) {
95              return result;
96          }
97  
98          for (LocalRepositoryManager lrm : tail) {
99              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 }