1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package de.smartics.properties.resource.filesystem.heap;
17
18 import java.io.BufferedInputStream;
19 import java.io.File;
20 import java.io.IOException;
21 import java.io.InputStream;
22 import java.util.jar.Attributes;
23 import java.util.jar.JarEntry;
24 import java.util.jar.JarFile;
25 import java.util.jar.Manifest;
26
27 import javax.annotation.concurrent.ThreadSafe;
28
29 import org.apache.commons.io.FilenameUtils;
30 import org.apache.commons.io.IOUtils;
31 import org.apache.commons.lang.StringUtils;
32
33 import de.smartics.properties.resource.domain.ArtifactId;
34 import de.smartics.util.lang.Arg;
35
36
37
38
39 @ThreadSafe
40 final class ArtifactIdGrabber
41 {
42
43
44
45
46
47
48
49
50
51
52 private final boolean definitionArchive;
53
54
55
56
57 private final ArtifactId artifactId;
58
59
60
61
62 private final String archiveType;
63
64
65
66
67 private final String classifier;
68
69
70
71
72
73 private ArtifactIdGrabber(final File archiveFile, final boolean lazy)
74 throws NullPointerException, IOException
75 {
76 Arg.checkNotNull("archiveFile", archiveFile);
77
78 final JarFile jarFile = new JarFile(archiveFile);
79
80 this.definitionArchive = isDefinitionArchive(jarFile);
81 if (lazy && !definitionArchive)
82 {
83 this.archiveType = null;
84 this.classifier = null;
85 this.artifactId = null;
86 return;
87 }
88 final String name = archiveFile.getName();
89 this.archiveType = determineType(name);
90 this.classifier = determineClassifier(name);
91 this.artifactId = load(jarFile);
92 }
93
94
95
96
97
98
99
100 private static boolean isDefinitionArchive(final JarFile jarFile)
101 {
102 final String definitionXmlName =
103 "META-INF/smartics-properties/definition.xml";
104 final JarEntry entry = jarFile.getJarEntry(definitionXmlName);
105 final boolean hasDefinition = entry != null;
106 return hasDefinition;
107 }
108
109 private static String determineType(final String name)
110 {
111 final String extension = FilenameUtils.getExtension(name);
112 final String type = StringUtils.isNotBlank(extension) ? extension : "jar";
113 return type;
114 }
115
116 private static String determineClassifier(final String name)
117 {
118 final String baseName = FilenameUtils.getBaseName(name);
119 final int pos = baseName.lastIndexOf('-');
120 if (pos == -1)
121 {
122 return null;
123 }
124
125 final String classifier = baseName.substring(pos);
126 if ("-SNAPSHOT".equals(classifier)
127 || StringUtils.containsAny(classifier, "0123456789"))
128 {
129 return null;
130 }
131
132 return classifier;
133 }
134
135 private ArtifactId load(final JarFile jarFile)
136 {
137 final JarEntry entry = jarFile.getJarEntry(JarFile.MANIFEST_NAME);
138 if (entry == null)
139 {
140 throw new IllegalStateException(String.format(
141 "No Manifest file found in: %s", jarFile.getName()));
142 }
143
144 final ArtifactId id = readManifestFile(jarFile, entry);
145 return id;
146 }
147
148 private ArtifactId readManifestFile(final JarFile jarFile,
149 final JarEntry entry) throws IllegalArgumentException,
150 IllegalStateException
151 {
152 InputStream inputStream = null;
153 try
154 {
155 inputStream = jarFile.getInputStream(entry);
156 if (inputStream != null)
157 {
158 inputStream = new BufferedInputStream(inputStream);
159 final Manifest manifest = new Manifest(inputStream);
160
161 final ArtifactId artifactId = createArtifactId(manifest);
162
163 return artifactId;
164 }
165
166 throw new IllegalStateException(
167 "Cannot find Manifest file to determine artifact ID: "
168 + entry.getName());
169 }
170 catch (final IOException e)
171 {
172 throw new IllegalStateException(String.format(
173 "Cannot read Manifest file: %s", jarFile.getName()), e);
174 }
175 finally
176 {
177 IOUtils.closeQuietly(inputStream);
178 }
179 }
180
181 private ArtifactId createArtifactId(final Manifest manifest)
182 throws IllegalArgumentException
183 {
184 final Attributes attributes = manifest.getMainAttributes();
185 final String groupId =
186 attributes.getValue(Attributes.Name.IMPLEMENTATION_VENDOR_ID);
187 final String artifactId =
188 attributes.getValue(Attributes.Name.IMPLEMENTATION_TITLE);
189 final String version =
190 attributes.getValue(Attributes.Name.IMPLEMENTATION_VERSION);
191
192 final ArtifactId id =
193 ArtifactId
194 .create(groupId, artifactId, version, archiveType, classifier);
195 return id;
196 }
197
198
199
200
201
202
203
204
205
206
207 static ArtifactIdGrabber create(final File archiveFile)
208 throws NullPointerException, IOException
209 {
210 return new ArtifactIdGrabber(archiveFile, false);
211 }
212
213
214
215
216
217
218
219
220
221
222
223 static ArtifactIdGrabber createLazy(final File archiveFile)
224 throws NullPointerException, IOException
225 {
226 return new ArtifactIdGrabber(archiveFile, true);
227 }
228
229
230
231
232
233
234
235
236
237
238 public boolean isDefinitionArchive()
239 {
240 return definitionArchive;
241 }
242
243
244
245
246
247
248 public ArtifactId getArtifactId()
249 {
250 return artifactId;
251 }
252
253
254
255
256
257 }