View Javadoc
1   /*
2    * Licensed under the Apache License, Version 2.0 (the "License");
3    * you may not use this file except in compliance with the License.
4    * You may obtain a copy of the License at
5    *
6    * http://www.apache.org/licenses/LICENSE-2.0
7    *
8    * Unless required by applicable law or agreed to in writing, software
9    * distributed under the License is distributed on an "AS IS" BASIS,
10   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11   * See the License for the specific language governing permissions and
12   * limitations under the License.
13   */
14  
15  package org.basepom.mojo.repack;
16  
17  import static com.google.common.base.Preconditions.checkNotNull;
18  
19  import java.io.File;
20  import java.io.IOException;
21  import java.util.Collection;
22  import java.util.HashSet;
23  import java.util.Map;
24  import java.util.Set;
25  
26  import com.google.common.collect.ImmutableMap;
27  import org.apache.maven.artifact.Artifact;
28  import org.apache.maven.project.MavenProject;
29  import org.springframework.boot.loader.tools.Libraries;
30  import org.springframework.boot.loader.tools.Library;
31  import org.springframework.boot.loader.tools.LibraryCallback;
32  import org.springframework.boot.loader.tools.LibraryCoordinates;
33  import org.springframework.boot.loader.tools.LibraryScope;
34  
35  /**
36   * {@link Libraries} backed by Maven {@link Artifact}s.
37   */
38  final class ArtifactsLibraries implements Libraries {
39  
40      private static final PluginLog LOG = new PluginLog(ArtifactsLibraries.class);
41  
42      private static final Map<String, LibraryScope> SCOPES = ImmutableMap.of(
43              Artifact.SCOPE_COMPILE, LibraryScope.COMPILE,
44              Artifact.SCOPE_RUNTIME, LibraryScope.RUNTIME,
45              Artifact.SCOPE_PROVIDED, LibraryScope.PROVIDED,
46              Artifact.SCOPE_SYSTEM, LibraryScope.PROVIDED);
47  
48      private final boolean quiet;
49      private final Set<Artifact> artifacts;
50      private final Set<Artifact> includedArtifacts;
51      private final Collection<MavenProject> localProjects;
52      private final Set<DependencyDefinition> runtimeUnpackedDependencies;
53      private final Set<String> duplicates = new HashSet<>();
54  
55      ArtifactsLibraries(boolean quiet,
56              Set<Artifact> artifacts,
57              Set<Artifact> includedArtifacts,
58              Collection<MavenProject> localProjects,
59              Set<DependencyDefinition> runtimeUnpackedDependencies) {
60          this.quiet = quiet;
61          this.artifacts = checkNotNull(artifacts, "artifacts is null");
62          this.includedArtifacts = checkNotNull(includedArtifacts, "includedArtifacts is null");
63          this.localProjects = checkNotNull(localProjects, "localProjects is null");
64          this.runtimeUnpackedDependencies = checkNotNull(runtimeUnpackedDependencies, "runtimeUnpackedDependencies is null");
65      }
66  
67      @Override
68      public void doWithLibraries(LibraryCallback callback) throws IOException {
69  
70          for (Artifact artifact : artifacts) {
71              String name = createFileName(artifact);
72              File file = artifact.getFile();
73  
74              LibraryScope scope = SCOPES.get(artifact.getScope());
75  
76              if (scope == null) {
77                  LOG.report(quiet, "Ignoring Dependency %s, scope is %s", artifact, artifact.getScope());
78                  Reporter.addExcluded(artifact, "scope");
79                  continue;
80              }
81  
82              if (file == null) {
83                  LOG.report(quiet, "Ignoring Dependency %s, no file found!", artifact);
84                  Reporter.addExcluded(artifact, "nofile");
85                  continue;
86              }
87  
88              if (duplicates.contains(name)) {
89                  LOG.warn("Ignoring Dependency %s, ignoring multiple inclusions!", artifact);
90                  continue;
91              }
92  
93              duplicates.add(name);
94  
95              LibraryCoordinates coordinates = new ArtifactLibraryCoordinates(artifact);
96              boolean runtimeUnpacked = isRuntimeUnpacked(artifact);
97              if (runtimeUnpacked) {
98                  Reporter.addRuntimeUnpacked(artifact);
99              }
100 
101             boolean local = isLocal(artifact);
102             boolean included = includedArtifacts.contains(artifact);
103 
104             if (included) {
105                 Reporter.addIncluded(artifact);
106             }
107 
108             callback.library(new Library(name, file, scope, coordinates, runtimeUnpacked, local, included));
109         }
110     }
111 
112     private boolean isRuntimeUnpacked(Artifact artifact) {
113         for (DependencyDefinition runtimeUnpackedDependency : runtimeUnpackedDependencies) {
114             if (runtimeUnpackedDependency.matches(artifact)) {
115                 return true;
116             }
117         }
118         return false;
119     }
120 
121     private boolean isLocal(Artifact artifact) {
122         for (MavenProject localProject : localProjects) {
123             if (localProject.getArtifact().equals(artifact)) {
124                 return true;
125             }
126             for (Artifact attachedArtifact : localProject.getAttachedArtifacts()) {
127                 if (attachedArtifact.equals(artifact)) {
128                     return true;
129                 }
130             }
131         }
132         return false;
133     }
134 
135     private static String createFileName(Artifact artifact) {
136         StringBuilder sb = new StringBuilder();
137         sb.append(artifact.getGroupId()).append('-');
138         sb.append(artifact.getArtifactId()).append('-');
139         sb.append(artifact.getBaseVersion());
140 
141         String classifier = artifact.getClassifier();
142         if (classifier != null) {
143             sb.append('-').append(classifier);
144         }
145         sb.append('.').append(artifact.getArtifactHandler().getExtension());
146 
147         return sb.toString();
148     }
149 
150     /**
151      * {@link LibraryCoordinates} backed by a Maven {@link Artifact}.
152      */
153     private static class ArtifactLibraryCoordinates implements LibraryCoordinates {
154 
155         private final Artifact artifact;
156 
157         ArtifactLibraryCoordinates(Artifact artifact) {
158             this.artifact = checkNotNull(artifact, "artifact is null");
159         }
160 
161         @Override
162         public String getGroupId() {
163             return artifact.getGroupId();
164         }
165 
166         @Override
167         public String getArtifactId() {
168             return artifact.getArtifactId();
169         }
170 
171         @Override
172         public String getVersion() {
173             return artifact.getBaseVersion();
174         }
175 
176         @Override
177         public String toString() {
178             return artifact.toString();
179         }
180     }
181 }