1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.artifact.repository.metadata;
20
21 import javax.xml.stream.XMLInputFactory;
22 import javax.xml.stream.XMLOutputFactory;
23
24 import java.io.ByteArrayInputStream;
25 import java.io.ByteArrayOutputStream;
26 import java.text.DateFormat;
27 import java.text.SimpleDateFormat;
28 import java.util.Date;
29 import java.util.GregorianCalendar;
30 import java.util.TimeZone;
31
32 import com.ctc.wstx.stax.WstxInputFactory;
33 import com.ctc.wstx.stax.WstxOutputFactory;
34 import org.apache.maven.artifact.repository.metadata.io.MetadataStaxReader;
35 import org.apache.maven.artifact.repository.metadata.io.MetadataStaxWriter;
36 import org.eclipse.aether.artifact.Artifact;
37 import org.eclipse.aether.artifact.DefaultArtifact;
38 import org.junit.jupiter.api.BeforeEach;
39 import org.junit.jupiter.api.Test;
40
41 import static org.junit.jupiter.api.Assertions.assertEquals;
42 import static org.junit.jupiter.api.Assertions.assertFalse;
43 import static org.junit.jupiter.api.Assertions.assertNotNull;
44 import static org.junit.jupiter.api.Assertions.assertTrue;
45
46 class MetadataTest {
47
48 Artifact artifact;
49
50 Metadata target;
51
52 @BeforeEach
53 void before() {
54 artifact = new DefaultArtifact("myGroup:myArtifact:1.0-SNAPSHOT");
55 target = createMetadataFromArtifact(artifact);
56 }
57
58
59 @Test
60 void mergeEmptyMetadata() throws Exception {
61 Metadata metadata = new Metadata();
62 assertFalse(metadata.merge(new Metadata()));
63 }
64
65 @Test
66 void mergeDifferentGAV() throws Exception {
67
68 Metadata source = new Metadata();
69 source.setArtifactId("source-artifact");
70 source.setGroupId("source-group");
71 source.setVersion("2.0");
72 assertFalse(target.merge(source));
73 assertEquals("myArtifact", target.getArtifactId());
74 assertEquals("myGroup", target.getGroupId());
75 assertEquals("1.0-SNAPSHOT", target.getVersion());
76 }
77
78
79
80 @Test
81 void mergeSnapshotWithEmptyList() throws Exception {
82 Snapshot snapshot = new Snapshot();
83 snapshot.setBuildNumber(3);
84 snapshot.setTimestamp("20200710.072412");
85 target.getVersioning().setSnapshot(snapshot);
86 target.getVersioning().setLastUpdated("20200921071745");
87 SnapshotVersion sv = new SnapshotVersion();
88 sv.setClassifier("sources");
89 sv.setExtension("jar");
90 sv.setUpdated("20200710072412");
91 target.getVersioning().addSnapshotVersion(sv);
92
93 Metadata source = createMetadataFromArtifact(artifact);
94
95 assertTrue(target.merge(source));
96
97
98 assertEquals("20200921071745", source.getVersioning().getLastUpdated());
99
100 assertEquals("myArtifact", target.getArtifactId());
101 assertEquals("myGroup", target.getGroupId());
102
103 assertEquals(3, target.getVersioning().getSnapshot().getBuildNumber());
104 assertEquals("20200710.072412", target.getVersioning().getSnapshot().getTimestamp());
105
106 assertEquals(1, target.getVersioning().getSnapshotVersions().size());
107 assertEquals(
108 "sources", target.getVersioning().getSnapshotVersions().get(0).getClassifier());
109 assertEquals("jar", target.getVersioning().getSnapshotVersions().get(0).getExtension());
110 assertEquals(
111 "20200710072412",
112 target.getVersioning().getSnapshotVersions().get(0).getUpdated());
113 }
114
115 @Test
116 void mergeWithSameSnapshotWithDifferentVersionsAndNewerLastUpdated() {
117 Metadata source = createMetadataFromArtifact(artifact);
118 Date before = new Date(System.currentTimeMillis() - 5000);
119 Date after = new Date(System.currentTimeMillis());
120 addSnapshotVersion(target.getVersioning(), "jar", before, "1", 1);
121 SnapshotVersion sv2 =
122 addSnapshotVersion(source.getVersioning(), "jar", after, "1.0-" + formatDate(after, true) + "-2", 2);
123 SnapshotVersion sv3 =
124 addSnapshotVersion(source.getVersioning(), "pom", after, "1.0-" + formatDate(after, true) + "-2", 2);
125 assertTrue(target.merge(source));
126 Versioning actualVersioning = target.getVersioning();
127 assertEquals(2, actualVersioning.getSnapshotVersions().size());
128 assertEquals(sv2, actualVersioning.getSnapshotVersions().get(0));
129 assertEquals(sv3, actualVersioning.getSnapshotVersions().get(1));
130 assertEquals(formatDate(after, false), actualVersioning.getLastUpdated());
131 assertEquals(formatDate(after, true), actualVersioning.getSnapshot().getTimestamp());
132 assertEquals(2, actualVersioning.getSnapshot().getBuildNumber());
133 }
134
135 @Test
136 void mergeWithSameSnapshotWithDifferentVersionsAndOlderLastUpdated() {
137 Metadata source = createMetadataFromArtifact(artifact);
138 Date before = new Date(System.currentTimeMillis() - 5000);
139 Date after = new Date(System.currentTimeMillis());
140 SnapshotVersion sv1 = addSnapshotVersion(target.getVersioning(), after, artifact);
141 addSnapshotVersion(source.getVersioning(), before, artifact);
142
143 assertFalse(target.merge(source));
144 assertEquals(1, target.getVersioning().getSnapshotVersions().size());
145 assertEquals(sv1, target.getVersioning().getSnapshotVersions().get(0));
146 assertEquals(formatDate(after, false), target.getVersioning().getLastUpdated());
147 assertEquals(
148 formatDate(after, true), target.getVersioning().getSnapshot().getTimestamp());
149 }
150
151 @Test
152 void mergeWithSameSnapshotWithSameVersionAndTimestamp() {
153 Metadata source = createMetadataFromArtifact(artifact);
154 Date date = new Date();
155 addSnapshotVersion(target.getVersioning(), date, artifact);
156 SnapshotVersion sv1 = addSnapshotVersion(source.getVersioning(), date, artifact);
157
158
159 assertTrue(target.merge(source));
160 assertEquals(1, target.getVersioning().getSnapshotVersions().size());
161 assertEquals(sv1, target.getVersioning().getSnapshotVersions().get(0));
162 assertEquals(formatDate(date, false), target.getVersioning().getLastUpdated());
163 assertEquals(
164 formatDate(date, true), target.getVersioning().getSnapshot().getTimestamp());
165 }
166
167 @Test
168 void mergeLegacyWithSnapshotLegacy() {
169 Metadata source = createMetadataFromArtifact(artifact);
170 Date before = new Date(System.currentTimeMillis() - 5000);
171 Date after = new Date(System.currentTimeMillis());
172
173 addSnapshotVersionLegacy(target.getVersioning(), before, 1);
174 addSnapshotVersionLegacy(source.getVersioning(), after, 2);
175
176
177 assertTrue(target.merge(source));
178 assertEquals(0, target.getVersioning().getSnapshotVersions().size());
179 assertEquals(formatDate(after, false), target.getVersioning().getLastUpdated());
180 assertEquals(
181 formatDate(after, true), target.getVersioning().getSnapshot().getTimestamp());
182 }
183
184 @Test
185 void mergeLegacyWithSnapshot() {
186 Metadata source = createMetadataFromArtifact(artifact);
187 Date before = new Date(System.currentTimeMillis() - 5000);
188 Date after = new Date(System.currentTimeMillis());
189
190 addSnapshotVersionLegacy(target.getVersioning(), before, 1);
191 addSnapshotVersion(source.getVersioning(), after, artifact);
192
193
194 assertTrue(target.merge(source));
195
196 assertEquals(0, target.getVersioning().getSnapshotVersions().size());
197 assertEquals(formatDate(after, false), target.getVersioning().getLastUpdated());
198 assertEquals(
199 formatDate(after, true), target.getVersioning().getSnapshot().getTimestamp());
200 }
201
202 @Test
203 void mergeWithSnapshotLegacy() {
204 Metadata source = createMetadataFromArtifact(artifact);
205 Date before = new Date(System.currentTimeMillis() - 5000);
206 Date after = new Date(System.currentTimeMillis());
207 addSnapshotVersion(target.getVersioning(), before, artifact);
208
209 addSnapshotVersionLegacy(source.getVersioning(), after, 2);
210
211
212 assertTrue(target.merge(source));
213
214 assertEquals(0, target.getVersioning().getSnapshotVersions().size());
215 assertEquals(formatDate(after, false), target.getVersioning().getLastUpdated());
216 assertEquals(
217 formatDate(after, true), target.getVersioning().getSnapshot().getTimestamp());
218 assertEquals(2, target.getVersioning().getSnapshot().getBuildNumber());
219 }
220
221
222 @Test
223 void testRoundtrip() throws Exception {
224 System.setProperty(XMLInputFactory.class.getName(), WstxInputFactory.class.getName());
225 System.setProperty(XMLOutputFactory.class.getName(), WstxOutputFactory.class.getName());
226
227 Metadata source = new Metadata(org.apache.maven.artifact.repository.metadata.v4.Metadata.newBuilder(
228 createMetadataFromArtifact(artifact).getDelegate(), true)
229 .modelEncoding("UTF-16")
230 .build());
231 ByteArrayOutputStream baos = new ByteArrayOutputStream();
232 new MetadataStaxWriter().write(baos, source.getDelegate());
233 Metadata source2 =
234 new Metadata(new MetadataStaxReader().read(new ByteArrayInputStream(baos.toByteArray()), true));
235 assertNotNull(source2);
236 }
237
238
239 private static final String SNAPSHOT = "SNAPSHOT";
240
241 private static final String DEFAULT_SNAPSHOT_TIMESTAMP_FORMAT = "yyyyMMdd.HHmmss";
242
243 private static final String DEFAULT_DATE_FORMAT = "yyyyMMddHHmmss";
244
245 private static String formatDate(Date date, boolean forSnapshotTimestamp) {
246
247 TimeZone timezone = TimeZone.getTimeZone("UTC");
248 DateFormat fmt =
249 new SimpleDateFormat(forSnapshotTimestamp ? DEFAULT_SNAPSHOT_TIMESTAMP_FORMAT : DEFAULT_DATE_FORMAT);
250 fmt.setCalendar(new GregorianCalendar());
251 fmt.setTimeZone(timezone);
252 return fmt.format(date);
253 }
254
255 private static Metadata createMetadataFromArtifact(Artifact artifact) {
256 Metadata metadata = new Metadata();
257 metadata.setArtifactId(artifact.getArtifactId());
258 metadata.setGroupId(artifact.getGroupId());
259 metadata.setVersion(artifact.getVersion());
260 metadata.setVersioning(new Versioning());
261 return metadata;
262 }
263
264 private static SnapshotVersion addSnapshotVersion(Versioning versioning, Date timestamp, Artifact artifact) {
265 int buildNumber = 1;
266
267
268 String version = artifact.getVersion();
269 String qualifier = formatDate(timestamp, true) + '-' + buildNumber;
270 version = version.substring(0, version.length() - SNAPSHOT.length()) + qualifier;
271 return addSnapshotVersion(versioning, artifact.getExtension(), timestamp, version, buildNumber);
272 }
273
274 private static SnapshotVersion addSnapshotVersion(
275 Versioning versioning, String extension, Date timestamp, String version, int buildNumber) {
276 Snapshot snapshot = new Snapshot();
277 snapshot.setBuildNumber(buildNumber);
278 snapshot.setTimestamp(formatDate(timestamp, true));
279
280 SnapshotVersion sv = new SnapshotVersion();
281 sv.setExtension(extension);
282 sv.setVersion(version);
283 sv.setUpdated(formatDate(timestamp, false));
284 versioning.addSnapshotVersion(sv);
285
286
287 versioning.setSnapshot(snapshot);
288 versioning.setLastUpdatedTimestamp(timestamp);
289 return sv;
290 }
291
292
293
294 private static void addSnapshotVersionLegacy(Versioning versioning, Date timestamp, int buildNumber) {
295 Snapshot snapshot = new Snapshot();
296 snapshot.setBuildNumber(buildNumber);
297 snapshot.setTimestamp(formatDate(timestamp, true));
298
299 versioning.setSnapshot(snapshot);
300 versioning.setLastUpdatedTimestamp(timestamp);
301 }
302
303 }