1 package org.apache.archiva.web.api;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 import com.google.common.base.Predicate;
22 import com.google.common.collect.Iterables;
23 import org.apache.archiva.admin.model.RepositoryAdminException;
24 import org.apache.archiva.admin.model.admin.ArchivaAdministration;
25 import org.apache.archiva.admin.model.beans.ManagedRepository;
26 import org.apache.archiva.admin.model.managed.ManagedRepositoryAdmin;
27 import org.apache.archiva.metadata.model.facets.AuditEvent;
28 import org.apache.archiva.checksum.ChecksumAlgorithm;
29 import org.apache.archiva.checksum.ChecksummedFile;
30 import org.apache.archiva.common.utils.VersionComparator;
31 import org.apache.archiva.common.utils.VersionUtil;
32 import org.apache.archiva.maven2.metadata.MavenMetadataReader;
33 import org.apache.archiva.model.ArchivaRepositoryMetadata;
34 import org.apache.archiva.model.ArtifactReference;
35 import org.apache.archiva.model.SnapshotVersion;
36 import org.apache.archiva.redback.components.taskqueue.TaskQueueException;
37 import org.apache.archiva.repository.ManagedRepositoryContent;
38 import org.apache.archiva.repository.RepositoryContentFactory;
39 import org.apache.archiva.repository.RepositoryException;
40 import org.apache.archiva.repository.RepositoryNotFoundException;
41 import org.apache.archiva.repository.metadata.MetadataTools;
42 import org.apache.archiva.repository.metadata.RepositoryMetadataException;
43 import org.apache.archiva.repository.metadata.RepositoryMetadataWriter;
44 import org.apache.archiva.rest.api.services.ArchivaRestServiceException;
45 import org.apache.archiva.rest.services.AbstractRestService;
46 import org.apache.archiva.scheduler.ArchivaTaskScheduler;
47 import org.apache.archiva.scheduler.repository.model.RepositoryTask;
48 import org.apache.archiva.web.model.FileMetadata;
49 import org.apache.archiva.xml.XMLException;
50 import org.apache.commons.io.FilenameUtils;
51 import org.apache.commons.io.IOUtils;
52 import org.apache.commons.lang.BooleanUtils;
53 import org.apache.commons.lang.StringUtils;
54 import org.apache.commons.lang.SystemUtils;
55 import org.apache.cxf.jaxrs.ext.multipart.Attachment;
56 import org.apache.cxf.jaxrs.ext.multipart.MultipartBody;
57 import org.apache.maven.model.Model;
58 import org.apache.maven.model.io.xpp3.MavenXpp3Writer;
59 import org.slf4j.Logger;
60 import org.slf4j.LoggerFactory;
61 import org.springframework.stereotype.Service;
62
63 import javax.inject.Inject;
64 import javax.inject.Named;
65 import javax.servlet.http.HttpServletRequest;
66 import javax.ws.rs.core.Context;
67 import javax.ws.rs.core.Response;
68 import java.io.File;
69 import java.io.FileOutputStream;
70 import java.io.FileWriter;
71 import java.io.IOException;
72 import java.nio.file.Files;
73 import java.nio.file.StandardCopyOption;
74 import java.text.DateFormat;
75 import java.text.SimpleDateFormat;
76 import java.util.ArrayList;
77 import java.util.Calendar;
78 import java.util.Collections;
79 import java.util.Date;
80 import java.util.Iterator;
81 import java.util.List;
82 import java.util.TimeZone;
83 import java.util.concurrent.CopyOnWriteArrayList;
84
85
86
87
88 @Service("fileUploadService#rest")
89 public class DefaultFileUploadService
90 extends AbstractRestService
91 implements FileUploadService
92 {
93 private Logger log = LoggerFactory.getLogger( getClass() );
94
95 @Context
96 private HttpServletRequest httpServletRequest;
97
98 @Inject
99 private ManagedRepositoryAdmin managedRepositoryAdmin;
100
101 @Inject
102 private RepositoryContentFactory repositoryFactory;
103
104 @Inject
105 private ArchivaAdministration archivaAdministration;
106
107 private ChecksumAlgorithm[] algorithms = new ChecksumAlgorithm[]{ ChecksumAlgorithm.SHA1, ChecksumAlgorithm.MD5 };
108
109 @Inject
110 @Named(value = "archivaTaskScheduler#repository")
111 private ArchivaTaskScheduler scheduler;
112
113 private String getStringValue( MultipartBody multipartBody, String attachmentId )
114 throws IOException
115 {
116 Attachment attachment = multipartBody.getAttachment( attachmentId );
117 return attachment == null ? "" : IOUtils.toString( attachment.getDataHandler().getInputStream() );
118 }
119
120 @Override
121 public FileMetadata post( MultipartBody multipartBody )
122 throws ArchivaRestServiceException
123 {
124
125 try
126 {
127
128 String classifier = getStringValue( multipartBody, "classifier" );
129 String packaging = getStringValue( multipartBody, "packaging" );
130
131
132 boolean pomFile = BooleanUtils.toBoolean( getStringValue( multipartBody, "pomFile" ) );
133
134 Attachment file = multipartBody.getAttachment( "files[]" );
135
136
137 String fileName = file.getContentDisposition().getParameter( "filename" );
138
139 File tmpFile = File.createTempFile( "upload-artifact", ".tmp" );
140 tmpFile.deleteOnExit();
141 IOUtils.copy( file.getDataHandler().getInputStream(), new FileOutputStream( tmpFile ) );
142 FileMetadata fileMetadata = new FileMetadata( fileName, tmpFile.length(), "theurl" );
143 fileMetadata.setServerFileName( tmpFile.getPath() );
144 fileMetadata.setClassifier( classifier );
145 fileMetadata.setDeleteUrl( tmpFile.getName() );
146 fileMetadata.setPomFile( pomFile );
147 fileMetadata.setPackaging( packaging );
148
149 log.info( "uploading file: {}", fileMetadata );
150
151 List<FileMetadata> fileMetadatas = getSessionFilesList();
152
153 fileMetadatas.add( fileMetadata );
154
155 return fileMetadata;
156 }
157 catch ( IOException e )
158 {
159 throw new ArchivaRestServiceException( e.getMessage(),
160 Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e );
161 }
162
163 }
164
165
166
167
168
169
170 protected synchronized List<FileMetadata> getSessionFilesList()
171 {
172 List<FileMetadata> fileMetadatas =
173 (List<FileMetadata>) httpServletRequest.getSession().getAttribute( FILES_SESSION_KEY );
174 if ( fileMetadatas == null )
175 {
176 fileMetadatas = new CopyOnWriteArrayList<>();
177 httpServletRequest.getSession().setAttribute( FILES_SESSION_KEY, fileMetadatas );
178 }
179 return fileMetadatas;
180 }
181
182 @Override
183 public Boolean deleteFile( String fileName )
184 throws ArchivaRestServiceException
185 {
186 File file = new File( SystemUtils.getJavaIoTmpDir(), fileName );
187 log.debug( "delete file:{},exists:{}", file.getPath(), file.exists() );
188 boolean removed = getSessionFileMetadatas().remove( new FileMetadata( fileName ) );
189
190 if ( !removed )
191 {
192 getSessionFileMetadatas().remove( new FileMetadata( file.getPath() ) );
193 }
194 if ( file.exists() )
195 {
196 return file.delete();
197 }
198 return Boolean.FALSE;
199 }
200
201 @Override
202 public Boolean clearUploadedFiles()
203 throws ArchivaRestServiceException
204 {
205 List<FileMetadata> fileMetadatas = new ArrayList( getSessionFileMetadatas() );
206 for ( FileMetadata fileMetadata : fileMetadatas )
207 {
208 deleteFile( new File( fileMetadata.getServerFileName() ).getPath() );
209 }
210 getSessionFileMetadatas().clear();
211 return Boolean.TRUE;
212 }
213
214 @Override
215 public List<FileMetadata> getSessionFileMetadatas()
216 throws ArchivaRestServiceException
217 {
218 List<FileMetadata> fileMetadatas =
219 (List<FileMetadata>) httpServletRequest.getSession().getAttribute( FILES_SESSION_KEY );
220
221 return fileMetadatas == null ? Collections.<FileMetadata>emptyList() : fileMetadatas;
222 }
223
224 @Override
225 public Boolean save( String repositoryId, String groupId, String artifactId, String version, String packaging,
226 boolean generatePom )
227 throws ArchivaRestServiceException
228 {
229 repositoryId = StringUtils.trim( repositoryId );
230 groupId = StringUtils.trim( groupId );
231 artifactId = StringUtils.trim( artifactId );
232 version = StringUtils.trim( version );
233 packaging = StringUtils.trim( packaging );
234
235 List<FileMetadata> fileMetadatas = getSessionFilesList();
236 if ( fileMetadatas == null || fileMetadatas.isEmpty() )
237 {
238 return Boolean.FALSE;
239 }
240
241 try
242 {
243 ManagedRepository managedRepository = managedRepositoryAdmin.getManagedRepository( repositoryId );
244
245 if ( managedRepository == null )
246 {
247
248 throw new ArchivaRestServiceException( "Cannot find managed repository with id " + repositoryId,
249 Response.Status.BAD_REQUEST.getStatusCode(), null );
250 }
251
252 if ( VersionUtil.isSnapshot( version ) && !managedRepository.isSnapshots() )
253 {
254
255 throw new ArchivaRestServiceException(
256 "Managed repository with id " + repositoryId + " do not accept snapshots",
257 Response.Status.BAD_REQUEST.getStatusCode(), null );
258 }
259 }
260 catch ( RepositoryAdminException e )
261 {
262 throw new ArchivaRestServiceException( e.getMessage(),
263 Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e );
264 }
265
266
267
268 Iterable<FileMetadata> filesToAdd = Iterables.filter( fileMetadatas, new Predicate<FileMetadata>()
269 {
270 public boolean apply( FileMetadata fileMetadata )
271 {
272 return fileMetadata != null && !fileMetadata.isPomFile();
273 }
274 } );
275 Iterator<FileMetadata> iterator = filesToAdd.iterator();
276 boolean pomGenerated = false;
277 while ( iterator.hasNext() )
278 {
279 FileMetadata fileMetadata = iterator.next();
280 log.debug( "fileToAdd: {}", fileMetadata );
281 saveFile( repositoryId, fileMetadata, generatePom && !pomGenerated, groupId, artifactId, version,
282 packaging );
283 pomGenerated = true;
284 deleteFile( fileMetadata.getServerFileName() );
285 }
286
287 filesToAdd = Iterables.filter( fileMetadatas, new Predicate<FileMetadata>()
288 {
289 @Override
290 public boolean apply( FileMetadata fileMetadata )
291 {
292 return fileMetadata != null && fileMetadata.isPomFile();
293 }
294 } );
295
296 iterator = filesToAdd.iterator();
297 while ( iterator.hasNext() )
298 {
299 FileMetadata fileMetadata = iterator.next();
300 log.debug( "fileToAdd: {}", fileMetadata );
301 savePomFile( repositoryId, fileMetadata, groupId, artifactId, version, packaging );
302 deleteFile( fileMetadata.getServerFileName() );
303 }
304
305 return Boolean.TRUE;
306 }
307
308 protected void savePomFile( String repositoryId, FileMetadata fileMetadata, String groupId, String artifactId,
309 String version, String packaging )
310 throws ArchivaRestServiceException
311 {
312
313 try
314 {
315 boolean fixChecksums =
316 !( archivaAdministration.getKnownContentConsumers().contains( "create-missing-checksums" ) );
317
318 ManagedRepository repoConfig = managedRepositoryAdmin.getManagedRepository( repositoryId );
319
320 ArtifactReference artifactReference = new ArtifactReference();
321 artifactReference.setArtifactId( artifactId );
322 artifactReference.setGroupId( groupId );
323 artifactReference.setVersion( version );
324 artifactReference.setClassifier( fileMetadata.getClassifier() );
325 artifactReference.setType( packaging );
326
327 ManagedRepositoryContent repository = repositoryFactory.getManagedRepositoryContent( repositoryId );
328
329 String artifactPath = repository.toPath( artifactReference );
330
331 int lastIndex = artifactPath.lastIndexOf( '/' );
332
333 String path = artifactPath.substring( 0, lastIndex );
334 File targetPath = new File( repoConfig.getLocation(), path );
335
336 String pomFilename = artifactPath.substring( lastIndex + 1 );
337 if ( StringUtils.isNotEmpty( fileMetadata.getClassifier() ) )
338 {
339 pomFilename = StringUtils.remove( pomFilename, "-" + fileMetadata.getClassifier() );
340 }
341 pomFilename = FilenameUtils.removeExtension( pomFilename ) + ".pom";
342
343 copyFile( new File( fileMetadata.getServerFileName() ), targetPath, pomFilename, fixChecksums );
344 triggerAuditEvent( repoConfig.getId(), path + "/" + pomFilename, AuditEvent.UPLOAD_FILE );
345 queueRepositoryTask( repoConfig.getId(), new File( targetPath, pomFilename ) );
346 }
347 catch ( IOException ie )
348 {
349 throw new ArchivaRestServiceException( "Error encountered while uploading pom file: " + ie.getMessage(),
350 Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), ie );
351 }
352 catch ( RepositoryException rep )
353 {
354 throw new ArchivaRestServiceException( "Repository exception: " + rep.getMessage(),
355 Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), rep );
356 }
357 catch ( RepositoryAdminException e )
358 {
359 throw new ArchivaRestServiceException( "RepositoryAdmin exception: " + e.getMessage(),
360 Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e );
361 }
362 }
363
364 protected void saveFile( String repositoryId, FileMetadata fileMetadata, boolean generatePom, String groupId,
365 String artifactId, String version, String packaging )
366 throws ArchivaRestServiceException
367 {
368 try
369 {
370
371 ManagedRepository repoConfig = managedRepositoryAdmin.getManagedRepository( repositoryId );
372
373 ArtifactReference artifactReference = new ArtifactReference();
374 artifactReference.setArtifactId( artifactId );
375 artifactReference.setGroupId( groupId );
376 artifactReference.setVersion( version );
377 artifactReference.setClassifier( fileMetadata.getClassifier() );
378 artifactReference.setType(
379 StringUtils.isEmpty( fileMetadata.getPackaging() ) ? packaging : fileMetadata.getPackaging() );
380
381 ManagedRepositoryContent repository = repositoryFactory.getManagedRepositoryContent( repositoryId );
382
383 String artifactPath = repository.toPath( artifactReference );
384
385 int lastIndex = artifactPath.lastIndexOf( '/' );
386
387 String path = artifactPath.substring( 0, lastIndex );
388 File targetPath = new File( repoConfig.getLocation(), path );
389
390 log.debug( "artifactPath: {} found targetPath: {}", artifactPath, targetPath );
391
392 Date lastUpdatedTimestamp = Calendar.getInstance().getTime();
393 int newBuildNumber = -1;
394 String timestamp = null;
395
396 File versionMetadataFile = new File( targetPath, MetadataTools.MAVEN_METADATA );
397 ArchivaRepositoryMetadata versionMetadata = getMetadata( versionMetadataFile );
398
399 if ( VersionUtil.isSnapshot( version ) )
400 {
401 TimeZone timezone = TimeZone.getTimeZone( "UTC" );
402 DateFormat fmt = new SimpleDateFormat( "yyyyMMdd.HHmmss" );
403 fmt.setTimeZone( timezone );
404 timestamp = fmt.format( lastUpdatedTimestamp );
405 if ( versionMetadata.getSnapshotVersion() != null )
406 {
407 newBuildNumber = versionMetadata.getSnapshotVersion().getBuildNumber() + 1;
408 }
409 else
410 {
411 newBuildNumber = 1;
412 }
413 }
414
415 if ( !targetPath.exists() )
416 {
417 targetPath.mkdirs();
418 }
419
420 String filename = artifactPath.substring( lastIndex + 1 );
421 if ( VersionUtil.isSnapshot( version ) )
422 {
423 filename = filename.replaceAll( VersionUtil.SNAPSHOT, timestamp + "-" + newBuildNumber );
424 }
425
426 boolean fixChecksums =
427 !( archivaAdministration.getKnownContentConsumers().contains( "create-missing-checksums" ) );
428
429 try
430 {
431 File targetFile = new File( targetPath, filename );
432 if ( targetFile.exists() && !VersionUtil.isSnapshot( version ) && repoConfig.isBlockRedeployments() )
433 {
434 throw new ArchivaRestServiceException(
435 "Overwriting released artifacts in repository '" + repoConfig.getId() + "' is not allowed.",
436 Response.Status.BAD_REQUEST.getStatusCode(), null );
437 }
438 else
439 {
440 copyFile( new File( fileMetadata.getServerFileName() ), targetPath, filename, fixChecksums );
441 triggerAuditEvent( repository.getId(), path + "/" + filename, AuditEvent.UPLOAD_FILE );
442 queueRepositoryTask( repository.getId(), targetFile );
443 }
444 }
445 catch ( IOException ie )
446 {
447 log.error( "IOException copying file: {}", ie.getMessage(), ie );
448 throw new ArchivaRestServiceException(
449 "Overwriting released artifacts in repository '" + repoConfig.getId() + "' is not allowed.",
450 Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), ie );
451 }
452
453 if ( generatePom )
454 {
455 String pomFilename = filename;
456 if ( StringUtils.isNotEmpty( fileMetadata.getClassifier() ) )
457 {
458 pomFilename = StringUtils.remove( pomFilename, "-" + fileMetadata.getClassifier() );
459 }
460 pomFilename = FilenameUtils.removeExtension( pomFilename ) + ".pom";
461
462 try
463 {
464 File generatedPomFile =
465 createPom( targetPath, pomFilename, fileMetadata, groupId, artifactId, version, packaging );
466 triggerAuditEvent( repoConfig.getId(), path + "/" + pomFilename, AuditEvent.UPLOAD_FILE );
467 if ( fixChecksums )
468 {
469 fixChecksums( generatedPomFile );
470 }
471 queueRepositoryTask( repoConfig.getId(), generatedPomFile );
472 }
473 catch ( IOException ie )
474 {
475 throw new ArchivaRestServiceException(
476 "Error encountered while writing pom file: " + ie.getMessage(),
477 Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), ie );
478 }
479 }
480
481
482 if ( !archivaAdministration.getKnownContentConsumers().contains( "metadata-updater" ) )
483 {
484 updateProjectMetadata( targetPath.getAbsolutePath(), lastUpdatedTimestamp, timestamp, newBuildNumber,
485 fixChecksums, fileMetadata, groupId, artifactId, version, packaging );
486
487 if ( VersionUtil.isSnapshot( version ) )
488 {
489 updateVersionMetadata( versionMetadata, versionMetadataFile, lastUpdatedTimestamp, timestamp,
490 newBuildNumber, fixChecksums, fileMetadata, groupId, artifactId, version,
491 packaging );
492 }
493 }
494 }
495 catch ( RepositoryNotFoundException re )
496 {
497 throw new ArchivaRestServiceException( "Target repository cannot be found: " + re.getMessage(),
498 Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), re );
499 }
500 catch ( RepositoryException rep )
501 {
502 throw new ArchivaRestServiceException( "Repository exception: " + rep.getMessage(),
503 Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), rep );
504 }
505 catch ( RepositoryAdminException e )
506 {
507 throw new ArchivaRestServiceException( "RepositoryAdmin exception: " + e.getMessage(),
508 Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e );
509 }
510 }
511
512 private ArchivaRepositoryMetadata getMetadata( File metadataFile )
513 throws RepositoryMetadataException
514 {
515 ArchivaRepositoryMetadata metadata = new ArchivaRepositoryMetadata();
516 if ( metadataFile.exists() )
517 {
518 try
519 {
520 metadata = MavenMetadataReader.read( metadataFile );
521 }
522 catch ( XMLException e )
523 {
524 throw new RepositoryMetadataException( e.getMessage(), e );
525 }
526 }
527 return metadata;
528 }
529
530 private File createPom( File targetPath, String filename, FileMetadata fileMetadata, String groupId,
531 String artifactId, String version, String packaging )
532 throws IOException
533 {
534 Model projectModel = new Model();
535 projectModel.setModelVersion( "4.0.0" );
536 projectModel.setGroupId( groupId );
537 projectModel.setArtifactId( artifactId );
538 projectModel.setVersion( version );
539 projectModel.setPackaging( packaging );
540
541 File pomFile = new File( targetPath, filename );
542 MavenXpp3Writer writer = new MavenXpp3Writer();
543
544 try (FileWriter w = new FileWriter( pomFile ))
545 {
546 writer.write( w, projectModel );
547 }
548
549 return pomFile;
550 }
551
552 private void fixChecksums( File file )
553 {
554 ChecksummedFile checksum = new ChecksummedFile( file );
555 checksum.fixChecksums( algorithms );
556 }
557
558 private void queueRepositoryTask( String repositoryId, File localFile )
559 {
560 RepositoryTask task = new RepositoryTask();
561 task.setRepositoryId( repositoryId );
562 task.setResourceFile( localFile );
563 task.setUpdateRelatedArtifacts( true );
564 task.setScanAll( false );
565
566 try
567 {
568 scheduler.queueTask( task );
569 }
570 catch ( TaskQueueException e )
571 {
572 log.error( "Unable to queue repository task to execute consumers on resource file ['" + localFile.getName()
573 + "']." );
574 }
575 }
576
577 private void copyFile( File sourceFile, File targetPath, String targetFilename, boolean fixChecksums )
578 throws IOException
579 {
580
581 Files.copy( sourceFile.toPath(), new File( targetPath, targetFilename ).toPath(), StandardCopyOption.REPLACE_EXISTING,
582 StandardCopyOption.COPY_ATTRIBUTES );
583
584 if ( fixChecksums )
585 {
586 fixChecksums( new File( targetPath, targetFilename ) );
587 }
588 }
589
590
591
592
593 private void updateProjectMetadata( String targetPath, Date lastUpdatedTimestamp, String timestamp, int buildNumber,
594 boolean fixChecksums, FileMetadata fileMetadata, String groupId,
595 String artifactId, String version, String packaging )
596 throws RepositoryMetadataException
597 {
598 List<String> availableVersions = new ArrayList<>();
599 String latestVersion = version;
600
601 File projectDir = new File( targetPath ).getParentFile();
602 File projectMetadataFile = new File( projectDir, MetadataTools.MAVEN_METADATA );
603
604 ArchivaRepositoryMetadata projectMetadata = getMetadata( projectMetadataFile );
605
606 if ( projectMetadataFile.exists() )
607 {
608 availableVersions = projectMetadata.getAvailableVersions();
609
610 Collections.sort( availableVersions, VersionComparator.getInstance() );
611
612 if ( !availableVersions.contains( version ) )
613 {
614 availableVersions.add( version );
615 }
616
617 latestVersion = availableVersions.get( availableVersions.size() - 1 );
618 }
619 else
620 {
621 availableVersions.add( version );
622
623 projectMetadata.setGroupId( groupId );
624 projectMetadata.setArtifactId( artifactId );
625 }
626
627 if ( projectMetadata.getGroupId() == null )
628 {
629 projectMetadata.setGroupId( groupId );
630 }
631
632 if ( projectMetadata.getArtifactId() == null )
633 {
634 projectMetadata.setArtifactId( artifactId );
635 }
636
637 projectMetadata.setLatestVersion( latestVersion );
638 projectMetadata.setLastUpdatedTimestamp( lastUpdatedTimestamp );
639 projectMetadata.setAvailableVersions( availableVersions );
640
641 if ( !VersionUtil.isSnapshot( version ) )
642 {
643 projectMetadata.setReleasedVersion( latestVersion );
644 }
645
646 RepositoryMetadataWriter.write( projectMetadata, projectMetadataFile );
647
648 if ( fixChecksums )
649 {
650 fixChecksums( projectMetadataFile );
651 }
652 }
653
654
655
656
657
658 private void updateVersionMetadata( ArchivaRepositoryMetadata metadata, File metadataFile,
659 Date lastUpdatedTimestamp, String timestamp, int buildNumber,
660 boolean fixChecksums, FileMetadata fileMetadata, String groupId,
661 String artifactId, String version, String packaging )
662 throws RepositoryMetadataException
663 {
664 if ( !metadataFile.exists() )
665 {
666 metadata.setGroupId( groupId );
667 metadata.setArtifactId( artifactId );
668 metadata.setVersion( version );
669 }
670
671 if ( metadata.getSnapshotVersion() == null )
672 {
673 metadata.setSnapshotVersion( new SnapshotVersion() );
674 }
675
676 metadata.getSnapshotVersion().setBuildNumber( buildNumber );
677 metadata.getSnapshotVersion().setTimestamp( timestamp );
678 metadata.setLastUpdatedTimestamp( lastUpdatedTimestamp );
679
680 RepositoryMetadataWriter.write( metadata, metadataFile );
681
682 if ( fixChecksums )
683 {
684 fixChecksums( metadataFile );
685 }
686 }
687
688
689 }