1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package com.github.maven_nar;
21
22 import java.io.File;
23 import java.io.IOException;
24 import java.util.ArrayList;
25 import java.util.List;
26 import java.util.jar.JarFile;
27
28 import org.apache.maven.artifact.Artifact;
29 import org.apache.maven.artifact.repository.ArtifactRepository;
30 import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
31 import org.apache.maven.artifact.resolver.ArtifactResolutionException;
32 import org.apache.maven.artifact.resolver.ArtifactResolver;
33 import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
34 import org.apache.maven.plugin.MojoExecutionException;
35 import org.apache.maven.plugin.MojoFailureException;
36 import org.apache.maven.plugin.logging.Log;
37 import org.apache.maven.project.MavenProject;
38 import org.codehaus.plexus.archiver.manager.ArchiverManager;
39
40
41
42
43 public class NarManager {
44
45 private final Log log;
46
47 private final MavenProject project;
48
49 private final ArtifactRepository repository;
50
51 private final AOL defaultAOL;
52
53 private final String linkerName;
54
55 private final String[] narTypes = {
56 NarConstants.NAR_NO_ARCH, Library.STATIC, Library.SHARED, Library.JNI, Library.PLUGIN
57 };
58
59 public NarManager(final Log log, final ArtifactRepository repository, final MavenProject project,
60 final String architecture, final String os, final Linker linker)
61 throws MojoFailureException, MojoExecutionException {
62 this.log = log;
63 this.repository = repository;
64 this.project = project;
65 this.defaultAOL = NarUtil.getAOL(project, architecture, os, linker, null, log);
66 this.linkerName = NarUtil.getLinkerName(project, architecture, os, linker, log);
67 }
68
69 public final void downloadAttachedNars(final List
70 final ArtifactResolver resolver, final String classifier) throws MojoExecutionException, MojoFailureException {
71
72
73 final List dependencies = getAttachedNarDependencies(narArtifacts, classifier);
74
75 this.log.debug("Download called with classifier: " + classifier + " for NarDependencies {");
76 for (final Object dependency2 : dependencies) {
77 this.log.debug(" - " + dependency2);
78 }
79 this.log.debug("}");
80
81 for (final Object dependency1 : dependencies) {
82 final Artifact dependency = (Artifact) dependency1;
83 try {
84 this.log.debug("Resolving " + dependency);
85 resolver.resolve(dependency, remoteRepositories, this.repository);
86 } catch (final ArtifactNotFoundException e) {
87 final String message = "nar not found " + dependency.getId();
88 throw new MojoExecutionException(message, e);
89 } catch (final ArtifactResolutionException e) {
90 final String message = "nar cannot resolve " + dependency.getId();
91 throw new MojoExecutionException(message, e);
92 }
93 }
94 }
95
96 private List
97 final String type) throws MojoExecutionException, MojoFailureException {
98 AOL aol = archOsLinker;
99 this.log.debug("GetNarDependencies for " + dependency + ", aol: " + aol + ", type: " + type);
100 final List artifactList = new ArrayList();
101 final NarInfo narInfo = getNarInfo(dependency);
102 final String[] nars = narInfo.getAttachedNars(aol, type);
103
104 if (nars != null) {
105 for (final String nar2 : nars) {
106 this.log.debug(" Checking: " + nar2);
107 if (nar2.equals("")) {
108 continue;
109 }
110 final String[] nar = nar2.split(":", 5);
111 if (nar.length >= 4) {
112 try {
113 final String groupId = nar[0].trim();
114 final String artifactId = nar[1].trim();
115 final String ext = nar[2].trim();
116 String classifier = nar[3].trim();
117
118 aol = narInfo.getAOL(aol);
119 if (aol != null) {
120 classifier = NarUtil.replace("${aol}", aol.toString(), classifier);
121 }
122 final String version = nar.length >= 5 ? nar[4].trim() : dependency.getBaseVersion();
123 artifactList.add(new AttachedNarArtifact(groupId, artifactId, version, dependency.getScope(), ext,
124 classifier, dependency.isOptional(), dependency.getFile()));
125 } catch (final InvalidVersionSpecificationException e) {
126 throw new MojoExecutionException("Error while reading nar file for dependency " + dependency, e);
127 }
128 } else {
129 this.log.warn("nars property in " + dependency.getArtifactId() + " contains invalid field: '" + nar2
130 + "' for type: " + type);
131 }
132 }
133 }
134 return artifactList;
135 }
136
137 public final List
138 * <
139 * NarArtifacts
140 * >
141 */narArtifacts)
142 throws MojoExecutionException, MojoFailureException {
143 return getAttachedNarDependencies(narArtifacts, (String) null);
144 }
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164 public final List
165 * <
166 * NarArtifacts
167 * >
168 */narArtifacts,
169 final AOL archOsLinker, final String type) throws MojoExecutionException, MojoFailureException {
170 boolean noarch = false;
171 AOL aol = archOsLinker;
172 if (aol == null) {
173 noarch = true;
174 aol = this.defaultAOL;
175 }
176
177 final List artifactList = new ArrayList();
178 for (final Object narArtifact : narArtifacts) {
179 final Artifact dependency = (Artifact) narArtifact;
180 final NarInfo narInfo = getNarInfo(dependency);
181 if (noarch) {
182 artifactList.addAll(getAttachedNarDependencies(dependency, null, NarConstants.NAR_NO_ARCH));
183 }
184
185
186 final String binding = narInfo.getBinding(aol, type != null ? type : Library.STATIC);
187
188
189 if (aol.equals(NarConstants.NAR_NO_ARCH)) {
190
191 artifactList.addAll(getAttachedNarDependencies(dependency, null, NarConstants.NAR_NO_ARCH));
192 } else {
193 artifactList.addAll(getAttachedNarDependencies(dependency, aol, binding));
194 }
195 }
196 return artifactList;
197 }
198
199 public final List
200 * <
201 * NarArtifacts
202 * >
203 */narArtifacts,
204 final String classifier) throws MojoExecutionException, MojoFailureException {
205 AOL aol = null;
206 String type = null;
207 if (classifier != null) {
208 final int dash = classifier.lastIndexOf('-');
209 if (dash < 0) {
210 aol = new AOL(classifier);
211 } else {
212 aol = new AOL(classifier.substring(0, dash));
213 type = classifier.substring(dash + 1);
214 }
215 }
216 return getAttachedNarDependencies(narArtifacts, aol, type);
217 }
218
219 public final List
220 * <
221 * NarArtifacts
222 * >
223 */narArtifacts,
224 final String[] classifiers) throws MojoExecutionException, MojoFailureException {
225
226 final List artifactList = new ArrayList();
227
228 if (classifiers != null && classifiers.length > 0) {
229
230 for (final String classifier : classifiers) {
231 artifactList.addAll(getAttachedNarDependencies(narArtifacts, classifier));
232 }
233 } else {
234 artifactList.addAll(getAttachedNarDependencies(narArtifacts, (String) null));
235 }
236
237 return artifactList;
238 }
239
240 public final File getNarFile(final Artifact dependency) throws MojoFailureException {
241
242
243 dependency.isSnapshot();
244 return new File(this.repository.getBasedir(), NarUtil.replace("${aol}", this.defaultAOL.toString(),
245 this.repository.pathOf(dependency)));
246 }
247
248 public final NarInfo getNarInfo(final Artifact dependency) throws MojoExecutionException {
249
250
251 dependency.isSnapshot();
252
253 final File file = new File(this.repository.getBasedir(), this.repository.pathOf(dependency));
254 if (!file.exists()) {
255 return null;
256 }
257
258 JarFile jar = null;
259 try {
260 jar = new JarFile(file);
261 final NarInfo info = new NarInfo(dependency.getGroupId(), dependency.getArtifactId(),
262 dependency.getBaseVersion(), this.log);
263 if (!info.exists(jar)) {
264 return null;
265 }
266 info.read(jar);
267 return info;
268 } catch (final IOException e) {
269 throw new MojoExecutionException("Error while reading " + file, e);
270 } finally {
271 if (jar != null) {
272 try {
273 jar.close();
274 } catch (final IOException e) {
275
276 }
277 }
278 }
279 }
280
281 public final void unpackAttachedNars(final List
282 final ArchiverManager archiverManager, final String classifier, final String os, final NarLayout layout,
283 final File unpackDir) throws MojoExecutionException, MojoFailureException {
284 this.log.debug("Unpack called for OS: " + os + ", classifier: " + classifier + " for NarArtifacts {");
285 for (final Object narArtifact : narArtifacts) {
286 this.log.debug(" - " + narArtifact);
287 }
288 this.log.debug("}");
289
290 final List dependencies = getAttachedNarDependencies(narArtifacts, classifier);
291 for (final Object dependency1 : dependencies) {
292 final Artifact dependency = (Artifact) dependency1;
293 this.log.debug("Unpack " + dependency + " to " + unpackDir);
294 final File file = getNarFile(dependency);
295
296 layout.unpackNar(unpackDir, archiverManager, file, os, this.linkerName, this.defaultAOL);
297 }
298 }
299 }