001/*
002 * Copyright 2012-2017 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.boot.maven;
018
019import java.io.IOException;
020import java.util.Collection;
021import java.util.Collections;
022import java.util.HashMap;
023import java.util.HashSet;
024import java.util.Map;
025import java.util.Set;
026
027import org.apache.maven.artifact.Artifact;
028import org.apache.maven.model.Dependency;
029import org.apache.maven.plugin.logging.Log;
030
031import org.springframework.boot.loader.tools.Libraries;
032import org.springframework.boot.loader.tools.Library;
033import org.springframework.boot.loader.tools.LibraryCallback;
034import org.springframework.boot.loader.tools.LibraryScope;
035
036/**
037 * {@link Libraries} backed by Maven {@link Artifact}s.
038 *
039 * @author Phillip Webb
040 * @author Andy Wilkinson
041 * @author Stephane Nicoll
042 */
043public class ArtifactsLibraries implements Libraries {
044
045        private static final Map<String, LibraryScope> scopes;
046
047        static {
048                Map<String, LibraryScope> libraryScopes = new HashMap<String, LibraryScope>();
049                libraryScopes.put(Artifact.SCOPE_COMPILE, LibraryScope.COMPILE);
050                libraryScopes.put(Artifact.SCOPE_RUNTIME, LibraryScope.RUNTIME);
051                libraryScopes.put(Artifact.SCOPE_PROVIDED, LibraryScope.PROVIDED);
052                libraryScopes.put(Artifact.SCOPE_SYSTEM, LibraryScope.PROVIDED);
053                scopes = Collections.unmodifiableMap(libraryScopes);
054        }
055
056        private final Set<Artifact> artifacts;
057
058        private final Collection<Dependency> unpacks;
059
060        private final Log log;
061
062        public ArtifactsLibraries(Set<Artifact> artifacts, Collection<Dependency> unpacks,
063                        Log log) {
064                this.artifacts = artifacts;
065                this.unpacks = unpacks;
066                this.log = log;
067        }
068
069        @Override
070        public void doWithLibraries(LibraryCallback callback) throws IOException {
071                Set<String> duplicates = getDuplicates(this.artifacts);
072                for (Artifact artifact : this.artifacts) {
073                        LibraryScope scope = scopes.get(artifact.getScope());
074                        if (scope != null && artifact.getFile() != null) {
075                                String name = getFileName(artifact);
076                                if (duplicates.contains(name)) {
077                                        this.log.debug("Duplicate found: " + name);
078                                        name = artifact.getGroupId() + "-" + name;
079                                        this.log.debug("Renamed to: " + name);
080                                }
081                                callback.library(new Library(name, artifact.getFile(), scope,
082                                                isUnpackRequired(artifact)));
083                        }
084                }
085        }
086
087        private Set<String> getDuplicates(Set<Artifact> artifacts) {
088                Set<String> duplicates = new HashSet<String>();
089                Set<String> seen = new HashSet<String>();
090                for (Artifact artifact : artifacts) {
091                        String fileName = getFileName(artifact);
092                        if (artifact.getFile() != null && !seen.add(fileName)) {
093                                duplicates.add(fileName);
094                        }
095                }
096                return duplicates;
097        }
098
099        private boolean isUnpackRequired(Artifact artifact) {
100                if (this.unpacks != null) {
101                        for (Dependency unpack : this.unpacks) {
102                                if (artifact.getGroupId().equals(unpack.getGroupId())
103                                                && artifact.getArtifactId().equals(unpack.getArtifactId())) {
104                                        return true;
105                                }
106                        }
107                }
108                return false;
109        }
110
111        private String getFileName(Artifact artifact) {
112                StringBuilder sb = new StringBuilder();
113                sb.append(artifact.getArtifactId()).append("-").append(artifact.getBaseVersion());
114                String classifier = artifact.getClassifier();
115                if (classifier != null) {
116                        sb.append("-").append(classifier);
117                }
118                sb.append(".").append(artifact.getArtifactHandler().getExtension());
119                return sb.toString();
120        }
121
122}