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.internal.impl;
020
021import javax.inject.Inject;
022import javax.inject.Named;
023import javax.inject.Singleton;
024
025import java.util.ArrayList;
026import java.util.Collection;
027import java.util.List;
028import java.util.Map;
029import java.util.concurrent.ConcurrentHashMap;
030
031import org.eclipse.aether.Keys;
032import org.eclipse.aether.RepositorySystemSession;
033import org.eclipse.aether.artifact.Artifact;
034import org.eclipse.aether.collection.CollectRequest;
035import org.eclipse.aether.deployment.DeployRequest;
036import org.eclipse.aether.graph.Dependency;
037import org.eclipse.aether.impl.RepositorySystemValidator;
038import org.eclipse.aether.installation.InstallRequest;
039import org.eclipse.aether.metadata.Metadata;
040import org.eclipse.aether.repository.LocalRepository;
041import org.eclipse.aether.repository.RemoteRepository;
042import org.eclipse.aether.resolution.ArtifactDescriptorRequest;
043import org.eclipse.aether.resolution.ArtifactRequest;
044import org.eclipse.aether.resolution.DependencyRequest;
045import org.eclipse.aether.resolution.MetadataRequest;
046import org.eclipse.aether.resolution.VersionRangeRequest;
047import org.eclipse.aether.resolution.VersionRequest;
048import org.eclipse.aether.spi.validator.Validator;
049import org.eclipse.aether.spi.validator.ValidatorFactory;
050
051import static java.util.Objects.requireNonNull;
052
053@Singleton
054@Named
055public class DefaultRepositorySystemValidator implements RepositorySystemValidator {
056    private static final Object SESSION_VALIDATORS = Keys.of(DefaultRepositorySystemValidator.class, "validators");
057    private final Map<String, ValidatorFactory> validatorFactories;
058
059    @Inject
060    public DefaultRepositorySystemValidator(Map<String, ValidatorFactory> validatorFactories) {
061        this.validatorFactories = requireNonNull(validatorFactories, "validatorFactories cannot be null");
062    }
063
064    private void mayThrow(List<Exception> exceptions, String message) {
065        if (!exceptions.isEmpty()) {
066            IllegalArgumentException result = new IllegalArgumentException(message);
067            exceptions.forEach(result::addSuppressed);
068            throw result;
069        }
070    }
071
072    @SuppressWarnings("unchecked")
073    private Validator newInstance(RepositorySystemSession session, String name, ValidatorFactory factory) {
074        if (session.getCache() != null) {
075            return ((ConcurrentHashMap<String, Validator>)
076                            session.getCache().computeIfAbsent(session, SESSION_VALIDATORS, ConcurrentHashMap::new))
077                    .computeIfAbsent(name, k -> requireNonNull(factory.newInstance(session)));
078        } else {
079            return requireNonNull(factory.newInstance(session));
080        }
081    }
082
083    @Override
084    public void validateVersionRequest(RepositorySystemSession session, VersionRequest request) {
085        ArrayList<Exception> exceptions = new ArrayList<>();
086        for (Map.Entry<String, ValidatorFactory> entry : validatorFactories.entrySet()) {
087            Validator validator = newInstance(session, entry.getKey(), entry.getValue());
088            if (validator != ValidatorFactory.NOOP) {
089                try {
090                    validator.validateArtifact(request.getArtifact());
091                } catch (Exception e) {
092                    exceptions.add(e);
093                }
094                for (RemoteRepository repository : request.getRepositories()) {
095                    try {
096                        validator.validateRemoteRepository(repository);
097                    } catch (Exception e) {
098                        exceptions.add(e);
099                    }
100                }
101            }
102        }
103        mayThrow(exceptions, "Invalid Version Request: " + request);
104    }
105
106    @Override
107    public void validateVersionRangeRequest(RepositorySystemSession session, VersionRangeRequest request) {
108        ArrayList<Exception> exceptions = new ArrayList<>();
109        for (Map.Entry<String, ValidatorFactory> entry : validatorFactories.entrySet()) {
110            Validator validator = newInstance(session, entry.getKey(), entry.getValue());
111            if (validator != ValidatorFactory.NOOP) {
112                try {
113                    validator.validateArtifact(request.getArtifact());
114                } catch (Exception e) {
115                    exceptions.add(e);
116                }
117                for (RemoteRepository repository : request.getRepositories()) {
118                    try {
119                        validator.validateRemoteRepository(repository);
120                    } catch (Exception e) {
121                        exceptions.add(e);
122                    }
123                }
124            }
125        }
126        mayThrow(exceptions, "Invalid Version Range Request: " + request);
127    }
128
129    @Override
130    public void validateArtifactDescriptorRequest(RepositorySystemSession session, ArtifactDescriptorRequest request) {
131        ArrayList<Exception> exceptions = new ArrayList<>();
132        for (Map.Entry<String, ValidatorFactory> entry : validatorFactories.entrySet()) {
133            Validator validator = newInstance(session, entry.getKey(), entry.getValue());
134            if (validator != ValidatorFactory.NOOP) {
135                try {
136                    validator.validateArtifact(request.getArtifact());
137                } catch (Exception e) {
138                    exceptions.add(e);
139                }
140                for (RemoteRepository repository : request.getRepositories()) {
141                    try {
142                        validator.validateRemoteRepository(repository);
143                    } catch (Exception e) {
144                        exceptions.add(e);
145                    }
146                }
147            }
148        }
149        mayThrow(exceptions, "Invalid Artifact Descriptor Request: " + request);
150    }
151
152    @Override
153    public void validateArtifactRequests(
154            RepositorySystemSession session, Collection<? extends ArtifactRequest> requests) {
155        ArrayList<Exception> exceptions = new ArrayList<>();
156        for (Map.Entry<String, ValidatorFactory> entry : validatorFactories.entrySet()) {
157            Validator validator = newInstance(session, entry.getKey(), entry.getValue());
158            if (validator != ValidatorFactory.NOOP) {
159                for (ArtifactRequest request : requests) {
160                    try {
161                        validator.validateArtifact(request.getArtifact());
162                    } catch (Exception e) {
163                        exceptions.add(e);
164                    }
165                    for (RemoteRepository repository : request.getRepositories()) {
166                        try {
167                            validator.validateRemoteRepository(repository);
168                        } catch (Exception e) {
169                            exceptions.add(e);
170                        }
171                    }
172                }
173            }
174        }
175        mayThrow(exceptions, "Invalid Artifact Requests: " + requests);
176    }
177
178    @Override
179    public void validateMetadataRequests(
180            RepositorySystemSession session, Collection<? extends MetadataRequest> requests) {
181        ArrayList<Exception> exceptions = new ArrayList<>();
182        for (Map.Entry<String, ValidatorFactory> entry : validatorFactories.entrySet()) {
183            Validator validator = newInstance(session, entry.getKey(), entry.getValue());
184            if (validator != ValidatorFactory.NOOP) {
185                for (MetadataRequest request : requests) {
186                    try {
187                        validator.validateMetadata(request.getMetadata());
188                    } catch (Exception e) {
189                        exceptions.add(e);
190                    }
191                    try {
192                        if (request.getRepository() != null) {
193                            validator.validateRemoteRepository(request.getRepository());
194                        }
195                    } catch (Exception e) {
196                        exceptions.add(e);
197                    }
198                }
199            }
200        }
201        mayThrow(exceptions, "Invalid Metadata Requests: " + requests);
202    }
203
204    @Override
205    public void validateCollectRequest(RepositorySystemSession session, CollectRequest request) {
206        ArrayList<Exception> exceptions = new ArrayList<>();
207        for (Map.Entry<String, ValidatorFactory> entry : validatorFactories.entrySet()) {
208            Validator validator = newInstance(session, entry.getKey(), entry.getValue());
209            if (validator != ValidatorFactory.NOOP) {
210                if (request.getRootArtifact() != null) {
211                    try {
212                        validator.validateArtifact(request.getRootArtifact());
213                    } catch (Exception e) {
214                        exceptions.add(e);
215                    }
216                }
217                if (request.getRoot() != null) {
218                    try {
219                        validator.validateDependency(request.getRoot());
220                    } catch (Exception e) {
221                        exceptions.add(e);
222                    }
223                }
224                for (Dependency dependency : request.getDependencies()) {
225                    try {
226                        validator.validateDependency(dependency);
227                    } catch (Exception e) {
228                        exceptions.add(e);
229                    }
230                }
231                for (Dependency managedDependency : request.getManagedDependencies()) {
232                    try {
233                        validator.validateManagedDependency(managedDependency);
234                    } catch (Exception e) {
235                        exceptions.add(e);
236                    }
237                }
238                for (RemoteRepository repository : request.getRepositories()) {
239                    try {
240                        validator.validateRemoteRepository(repository);
241                    } catch (Exception e) {
242                        exceptions.add(e);
243                    }
244                }
245            }
246        }
247        mayThrow(exceptions, "Invalid Collect Request: " + request);
248    }
249
250    @Override
251    public void validateDependencyRequest(RepositorySystemSession session, DependencyRequest request) {
252        if (request.getCollectRequest() != null) {
253            try {
254                validateCollectRequest(session, request.getCollectRequest());
255            } catch (Exception e) {
256                throw new IllegalArgumentException("Invalid Dependency Request: " + request, e);
257            }
258        }
259    }
260
261    @Override
262    public void validateInstallRequest(RepositorySystemSession session, InstallRequest request) {
263        ArrayList<Exception> exceptions = new ArrayList<>();
264        for (Map.Entry<String, ValidatorFactory> entry : validatorFactories.entrySet()) {
265            Validator validator = newInstance(session, entry.getKey(), entry.getValue());
266            if (validator != ValidatorFactory.NOOP) {
267                for (Artifact artifact : request.getArtifacts()) {
268                    try {
269                        validator.validateArtifact(artifact);
270                    } catch (Exception e) {
271                        exceptions.add(e);
272                    }
273                }
274                for (Metadata metadata : request.getMetadata()) {
275                    try {
276                        validator.validateMetadata(metadata);
277                    } catch (Exception e) {
278                        exceptions.add(e);
279                    }
280                }
281            }
282        }
283        mayThrow(exceptions, "Invalid Install Request: " + request);
284    }
285
286    @Override
287    public void validateDeployRequest(RepositorySystemSession session, DeployRequest request) {
288        ArrayList<Exception> exceptions = new ArrayList<>();
289        for (Map.Entry<String, ValidatorFactory> entry : validatorFactories.entrySet()) {
290            Validator validator = newInstance(session, entry.getKey(), entry.getValue());
291            if (validator != ValidatorFactory.NOOP) {
292                for (Artifact artifact : request.getArtifacts()) {
293                    try {
294                        validator.validateArtifact(artifact);
295                    } catch (Exception e) {
296                        exceptions.add(e);
297                    }
298                }
299                for (Metadata metadata : request.getMetadata()) {
300                    try {
301                        validator.validateMetadata(metadata);
302                    } catch (Exception e) {
303                        exceptions.add(e);
304                    }
305                }
306                try {
307                    if (request.getRepository() != null) {
308                        validator.validateRemoteRepository(request.getRepository());
309                    }
310                } catch (Exception e) {
311                    exceptions.add(e);
312                }
313            }
314        }
315        mayThrow(exceptions, "Invalid Deploy Request: " + request);
316    }
317
318    @Override
319    public void validateLocalRepositories(RepositorySystemSession session, Collection<LocalRepository> repositories) {
320        ArrayList<Exception> exceptions = new ArrayList<>();
321        for (Map.Entry<String, ValidatorFactory> entry : validatorFactories.entrySet()) {
322            Validator validator = newInstance(session, entry.getKey(), entry.getValue());
323            if (validator != ValidatorFactory.NOOP) {
324                for (LocalRepository repository : repositories) {
325                    try {
326                        validator.validateLocalRepository(repository);
327                    } catch (Exception e) {
328                        exceptions.add(e);
329                    }
330                }
331            }
332        }
333        mayThrow(exceptions, "Invalid LocalRepositories: " + repositories);
334    }
335
336    @Override
337    public void validateRemoteRepositories(RepositorySystemSession session, Collection<RemoteRepository> repositories) {
338        ArrayList<Exception> exceptions = new ArrayList<>();
339        for (Map.Entry<String, ValidatorFactory> entry : validatorFactories.entrySet()) {
340            Validator validator = newInstance(session, entry.getKey(), entry.getValue());
341            if (validator != ValidatorFactory.NOOP) {
342                for (RemoteRepository repository : repositories) {
343                    try {
344                        validator.validateRemoteRepository(repository);
345                    } catch (Exception e) {
346                        exceptions.add(e);
347                    }
348                }
349            }
350        }
351        mayThrow(exceptions, "Invalid RemoteRepositories: " + repositories);
352    }
353}