]> source.dussan.org Git - archiva.git/blob
411eef67d7a9b23e1ae2ed971d396eda58731ebd
[archiva.git] /
1 package org.apache.archiva.webapp.ui.services.api;
2 /*
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
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.audit.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.repository.ManagedRepositoryContent;
37 import org.apache.archiva.repository.RepositoryContentFactory;
38 import org.apache.archiva.repository.RepositoryException;
39 import org.apache.archiva.repository.RepositoryNotFoundException;
40 import org.apache.archiva.repository.metadata.MetadataTools;
41 import org.apache.archiva.repository.metadata.RepositoryMetadataException;
42 import org.apache.archiva.repository.metadata.RepositoryMetadataWriter;
43 import org.apache.archiva.rest.api.services.ArchivaRestServiceException;
44 import org.apache.archiva.rest.services.AbstractRestService;
45 import org.apache.archiva.scheduler.ArchivaTaskScheduler;
46 import org.apache.archiva.scheduler.repository.RepositoryTask;
47 import org.apache.archiva.webapp.ui.services.model.FileMetadata;
48 import org.apache.archiva.xml.XMLException;
49 import org.apache.commons.io.FilenameUtils;
50 import org.apache.commons.io.IOUtils;
51 import org.apache.commons.lang.BooleanUtils;
52 import org.apache.commons.lang.StringUtils;
53 import org.apache.commons.lang.SystemUtils;
54 import org.apache.cxf.jaxrs.ext.multipart.Attachment;
55 import org.apache.cxf.jaxrs.ext.multipart.MultipartBody;
56 import org.apache.maven.model.Model;
57 import org.apache.maven.model.io.xpp3.MavenXpp3Writer;
58 import org.codehaus.plexus.taskqueue.TaskQueueException;
59 import org.codehaus.plexus.util.IOUtil;
60 import org.slf4j.Logger;
61 import org.slf4j.LoggerFactory;
62 import org.springframework.stereotype.Service;
63
64 import javax.annotation.Nullable;
65 import javax.inject.Inject;
66 import javax.inject.Named;
67 import javax.servlet.http.HttpServletRequest;
68 import javax.ws.rs.core.Context;
69 import javax.ws.rs.core.Response;
70 import java.io.File;
71 import java.io.FileInputStream;
72 import java.io.FileOutputStream;
73 import java.io.FileWriter;
74 import java.io.IOException;
75 import java.text.DateFormat;
76 import java.text.SimpleDateFormat;
77 import java.util.ArrayList;
78 import java.util.Calendar;
79 import java.util.Collections;
80 import java.util.Date;
81 import java.util.Iterator;
82 import java.util.List;
83 import java.util.TimeZone;
84
85 /**
86  * @author Olivier Lamy
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     public FileMetadata post( MultipartBody multipartBody )
121         throws ArchivaRestServiceException
122     {
123
124         try
125         {
126             String groupId = getStringValue( multipartBody, "groupId" );
127
128             String artifactId = getStringValue( multipartBody, "artifactId" );
129
130             String version = getStringValue( multipartBody, "version" );
131
132             String packaging = getStringValue( multipartBody, "packaging" );
133
134             String classifier = getStringValue( multipartBody, "classifier" );
135             boolean pomFile = BooleanUtils.toBoolean( getStringValue( multipartBody, "pomFile" ) );
136
137             Attachment file = multipartBody.getAttachment( "files[]" );
138
139             //Content-Disposition: form-data; name="files[]"; filename="org.apache.karaf.features.command-2.2.2.jar"
140             String fileName = file.getContentDisposition().getParameter( "filename" );
141
142             File tmpFile = File.createTempFile( "upload-artifact", "tmp" );
143             tmpFile.deleteOnExit();
144             IOUtils.copy( file.getDataHandler().getInputStream(), new FileOutputStream( tmpFile ) );
145             FileMetadata fileMetadata = new FileMetadata( fileName, tmpFile.length(), "theurl" );
146             fileMetadata.setServerFileName( tmpFile.getPath() );
147             fileMetadata.setClassifier( classifier );
148             fileMetadata.setDeleteUrl( tmpFile.getName() );
149             fileMetadata.setPomFile( pomFile );
150
151             log.info( "uploading file:{}", fileMetadata );
152
153             List<FileMetadata> fileMetadatas =
154                 (List<FileMetadata>) httpServletRequest.getSession().getAttribute( FILES_SESSION_KEY );
155
156             if ( fileMetadatas == null )
157             {
158                 fileMetadatas = new ArrayList<FileMetadata>( 1 );
159             }
160             fileMetadatas.add( fileMetadata );
161             httpServletRequest.getSession().setAttribute( FILES_SESSION_KEY, fileMetadatas );
162             return fileMetadata;
163         }
164         catch ( IOException e )
165         {
166             throw new ArchivaRestServiceException( e.getMessage(),
167                                                    Response.Status.INTERNAL_SERVER_ERROR.getStatusCode() );
168         }
169
170     }
171
172     public Boolean deleteFile( String fileName )
173         throws ArchivaRestServiceException
174     {
175         File file = new File( SystemUtils.getJavaIoTmpDir(), fileName );
176         log.debug( "delete file:{},exists:{}", file.getPath(), file.exists() );
177         boolean removed = getSessionFileMetadatas().remove( new FileMetadata( fileName ) );
178         if ( file.exists() )
179         {
180             return file.delete();
181         }
182         return Boolean.FALSE;
183     }
184
185     public Boolean clearUploadedFiles()
186         throws ArchivaRestServiceException
187     {
188         List<FileMetadata> fileMetadatas = new ArrayList( getSessionFileMetadatas() );
189         for ( FileMetadata fileMetadata : fileMetadatas )
190         {
191             deleteFile( fileMetadata.getServerFileName() );
192         }
193         return Boolean.TRUE;
194     }
195
196     public List<FileMetadata> getSessionFileMetadatas()
197         throws ArchivaRestServiceException
198     {
199         List<FileMetadata> fileMetadatas =
200             (List<FileMetadata>) httpServletRequest.getSession().getAttribute( FILES_SESSION_KEY );
201
202         return fileMetadatas == null ? Collections.<FileMetadata>emptyList() : fileMetadatas;
203     }
204
205     public Boolean save( String repositoryId, final String groupId, final String artifactId, String version,
206                          String packaging, final boolean generatePom )
207         throws ArchivaRestServiceException
208     {
209         List<FileMetadata> fileMetadatas =
210             (List<FileMetadata>) httpServletRequest.getSession().getAttribute( FILES_SESSION_KEY );
211         if ( fileMetadatas == null || fileMetadatas.isEmpty() )
212         {
213             return Boolean.FALSE;
214         }
215         // get from the session file with groupId/artifactId
216
217         Iterable<FileMetadata> filesToAdd = Iterables.filter( fileMetadatas, new Predicate<FileMetadata>()
218         {
219             public boolean apply( FileMetadata fileMetadata )
220             {
221                 return fileMetadata != null && !fileMetadata.isPomFile();
222             }
223         } );
224         Iterator<FileMetadata> iterator = filesToAdd.iterator();
225         boolean pomGenerated = false;
226         while ( iterator.hasNext() )
227         {
228             FileMetadata fileMetadata = iterator.next();
229             log.debug( "fileToAdd: {}", fileMetadata );
230             saveFile( repositoryId, fileMetadata, generatePom && !pomGenerated, groupId, artifactId, version,
231                       packaging );
232             pomGenerated = true;
233         }
234
235         filesToAdd = Iterables.filter( fileMetadatas, new Predicate<FileMetadata>()
236         {
237             public boolean apply( @Nullable FileMetadata fileMetadata )
238             {
239                 return fileMetadata != null && fileMetadata.isPomFile();
240             }
241         } );
242
243         iterator = filesToAdd.iterator();
244         while ( iterator.hasNext() )
245         {
246             FileMetadata fileMetadata = iterator.next();
247             log.debug( "fileToAdd: {}", fileMetadata );
248             savePomFile( repositoryId, fileMetadata, groupId, artifactId, version, packaging );
249         }
250
251         return Boolean.TRUE;
252     }
253
254     protected void savePomFile( String repositoryId, FileMetadata fileMetadata, String groupId, String artifactId,
255                                 String version, String packaging )
256         throws ArchivaRestServiceException
257     {
258
259         try
260         {
261             boolean fixChecksums =
262                 !( archivaAdministration.getKnownContentConsumers().contains( "create-missing-checksums" ) );
263
264             ManagedRepository repoConfig = managedRepositoryAdmin.getManagedRepository( repositoryId );
265
266             ArtifactReference artifactReference = new ArtifactReference();
267             artifactReference.setArtifactId( artifactId );
268             artifactReference.setGroupId( groupId );
269             artifactReference.setVersion( version );
270             artifactReference.setClassifier( fileMetadata.getClassifier() );
271             artifactReference.setType( packaging );
272
273             ManagedRepositoryContent repository = repositoryFactory.getManagedRepositoryContent( repositoryId );
274
275             String artifactPath = repository.toPath( artifactReference );
276
277             int lastIndex = artifactPath.lastIndexOf( '/' );
278
279             String path = artifactPath.substring( 0, lastIndex );
280             File targetPath = new File( repoConfig.getLocation(), path );
281
282             String pomFilename = artifactPath.substring( lastIndex + 1 );
283             if ( StringUtils.isNotEmpty( fileMetadata.getClassifier() ) )
284             {
285                 pomFilename = StringUtils.remove( pomFilename, "-" + fileMetadata.getClassifier() );
286             }
287             pomFilename = FilenameUtils.removeExtension( pomFilename ) + ".pom";
288
289             copyFile( new File( fileMetadata.getServerFileName() ), targetPath, pomFilename, fixChecksums );
290             triggerAuditEvent( repoConfig.getId(), path + "/" + pomFilename, AuditEvent.UPLOAD_FILE );
291             queueRepositoryTask( repoConfig.getId(), new File( targetPath, pomFilename ) );
292         }
293         catch ( IOException ie )
294         {
295             throw new ArchivaRestServiceException( "Error encountered while uploading pom file: " + ie.getMessage(),
296                                                    Response.Status.INTERNAL_SERVER_ERROR.getStatusCode() );
297         }
298         catch ( RepositoryException rep )
299         {
300             throw new ArchivaRestServiceException( "Repository exception: " + rep.getMessage(),
301                                                    Response.Status.INTERNAL_SERVER_ERROR.getStatusCode() );
302         }
303         catch ( RepositoryAdminException e )
304         {
305             throw new ArchivaRestServiceException( "RepositoryAdmin exception: " + e.getMessage(),
306                                                    Response.Status.INTERNAL_SERVER_ERROR.getStatusCode() );
307         }
308     }
309
310     protected void saveFile( String repositoryId, FileMetadata fileMetadata, boolean generatePom, String groupId,
311                              String artifactId, String version, String packaging )
312         throws ArchivaRestServiceException
313     {
314         try
315         {
316
317             ManagedRepository repoConfig = managedRepositoryAdmin.getManagedRepository( repositoryId );
318
319             ArtifactReference artifactReference = new ArtifactReference();
320             artifactReference.setArtifactId( artifactId );
321             artifactReference.setGroupId( groupId );
322             artifactReference.setVersion( version );
323             artifactReference.setClassifier( fileMetadata.getClassifier() );
324             artifactReference.setType( packaging );
325
326             ManagedRepositoryContent repository = repositoryFactory.getManagedRepositoryContent( repositoryId );
327
328             String artifactPath = repository.toPath( artifactReference );
329
330             int lastIndex = artifactPath.lastIndexOf( '/' );
331
332             String path = artifactPath.substring( 0, lastIndex );
333             File targetPath = new File( repoConfig.getLocation(), path );
334
335             log.debug( "artifactPath: {} found targetPath: {}", artifactPath, targetPath );
336
337             Date lastUpdatedTimestamp = Calendar.getInstance().getTime();
338             int newBuildNumber = -1;
339             String timestamp = null;
340
341             File versionMetadataFile = new File( targetPath, MetadataTools.MAVEN_METADATA );
342             ArchivaRepositoryMetadata versionMetadata = getMetadata( versionMetadataFile );
343
344             if ( VersionUtil.isSnapshot( version ) )
345             {
346                 TimeZone timezone = TimeZone.getTimeZone( "UTC" );
347                 DateFormat fmt = new SimpleDateFormat( "yyyyMMdd.HHmmss" );
348                 fmt.setTimeZone( timezone );
349                 timestamp = fmt.format( lastUpdatedTimestamp );
350                 if ( versionMetadata.getSnapshotVersion() != null )
351                 {
352                     newBuildNumber = versionMetadata.getSnapshotVersion().getBuildNumber() + 1;
353                 }
354                 else
355                 {
356                     newBuildNumber = 1;
357                 }
358             }
359
360             if ( !targetPath.exists() )
361             {
362                 targetPath.mkdirs();
363             }
364
365             String filename = artifactPath.substring( lastIndex + 1 );
366             if ( VersionUtil.isSnapshot( version ) )
367             {
368                 filename = filename.replaceAll( "SNAPSHOT", timestamp + "-" + newBuildNumber );
369             }
370
371             boolean fixChecksums =
372                 !( archivaAdministration.getKnownContentConsumers().contains( "create-missing-checksums" ) );
373
374             try
375             {
376                 File targetFile = new File( targetPath, filename );
377                 if ( targetFile.exists() && !VersionUtil.isSnapshot( version ) && repoConfig.isBlockRedeployments() )
378                 {
379                     throw new ArchivaRestServiceException(
380                         "Overwriting released artifacts in repository '" + repoConfig.getId() + "' is not allowed.",
381                         Response.Status.BAD_REQUEST.getStatusCode() );
382                 }
383                 else
384                 {
385                     copyFile( new File( fileMetadata.getServerFileName() ), targetPath, filename, fixChecksums );
386                     triggerAuditEvent( repository.getId(), path + "/" + filename, AuditEvent.UPLOAD_FILE );
387                     queueRepositoryTask( repository.getId(), targetFile );
388                 }
389             }
390             catch ( IOException ie )
391             {
392                 throw new ArchivaRestServiceException(
393                     "Overwriting released artifacts in repository '" + repoConfig.getId() + "' is not allowed.",
394                     Response.Status.INTERNAL_SERVER_ERROR.getStatusCode() );
395             }
396
397             if ( generatePom )
398             {
399                 String pomFilename = filename;
400                 if ( StringUtils.isNotEmpty( fileMetadata.getClassifier() ) )
401                 {
402                     pomFilename = StringUtils.remove( pomFilename, "-" + fileMetadata.getClassifier() );
403                 }
404                 pomFilename = FilenameUtils.removeExtension( pomFilename ) + ".pom";
405
406                 try
407                 {
408                     File generatedPomFile =
409                         createPom( targetPath, pomFilename, fileMetadata, groupId, artifactId, version, packaging );
410                     triggerAuditEvent( repoConfig.getId(), path + "/" + pomFilename, AuditEvent.UPLOAD_FILE );
411                     if ( fixChecksums )
412                     {
413                         fixChecksums( generatedPomFile );
414                     }
415                     queueRepositoryTask( repoConfig.getId(), generatedPomFile );
416                 }
417                 catch ( IOException ie )
418                 {
419                     throw new ArchivaRestServiceException(
420                         "Error encountered while writing pom file: " + ie.getMessage(),
421                         Response.Status.INTERNAL_SERVER_ERROR.getStatusCode() );
422                 }
423             }
424
425             // explicitly update only if metadata-updater consumer is not enabled!
426             if ( !archivaAdministration.getKnownContentConsumers().contains( "metadata-updater" ) )
427             {
428                 updateProjectMetadata( targetPath.getAbsolutePath(), lastUpdatedTimestamp, timestamp, newBuildNumber,
429                                        fixChecksums, fileMetadata, groupId, artifactId, version, packaging );
430
431                 if ( VersionUtil.isSnapshot( version ) )
432                 {
433                     updateVersionMetadata( versionMetadata, versionMetadataFile, lastUpdatedTimestamp, timestamp,
434                                            newBuildNumber, fixChecksums, fileMetadata, groupId, artifactId, version,
435                                            packaging );
436                 }
437             }
438         }
439         catch ( RepositoryNotFoundException re )
440         {
441             throw new ArchivaRestServiceException( "Target repository cannot be found: " + re.getMessage(),
442                                                    Response.Status.INTERNAL_SERVER_ERROR.getStatusCode() );
443         }
444         catch ( RepositoryException rep )
445         {
446             throw new ArchivaRestServiceException( "Repository exception: " + rep.getMessage(),
447                                                    Response.Status.INTERNAL_SERVER_ERROR.getStatusCode() );
448         }
449         catch ( RepositoryAdminException e )
450         {
451             throw new ArchivaRestServiceException( "RepositoryAdmin exception: " + e.getMessage(),
452                                                    Response.Status.INTERNAL_SERVER_ERROR.getStatusCode() );
453         }
454     }
455
456     private ArchivaRepositoryMetadata getMetadata( File metadataFile )
457         throws RepositoryMetadataException
458     {
459         ArchivaRepositoryMetadata metadata = new ArchivaRepositoryMetadata();
460         if ( metadataFile.exists() )
461         {
462             try
463             {
464                 metadata = MavenMetadataReader.read( metadataFile );
465             }
466             catch ( XMLException e )
467             {
468                 throw new RepositoryMetadataException( e.getMessage(), e );
469             }
470         }
471         return metadata;
472     }
473
474     private File createPom( File targetPath, String filename, FileMetadata fileMetadata, String groupId,
475                             String artifactId, String version, String packaging )
476         throws IOException
477     {
478         Model projectModel = new Model();
479         projectModel.setModelVersion( "4.0.0" );
480         projectModel.setGroupId( groupId );
481         projectModel.setArtifactId( artifactId );
482         projectModel.setVersion( version );
483         projectModel.setPackaging( packaging );
484
485         File pomFile = new File( targetPath, filename );
486         MavenXpp3Writer writer = new MavenXpp3Writer();
487         FileWriter w = new FileWriter( pomFile );
488         try
489         {
490             writer.write( w, projectModel );
491         }
492         finally
493         {
494             IOUtil.close( w );
495         }
496
497         return pomFile;
498     }
499
500     private void fixChecksums( File file )
501     {
502         ChecksummedFile checksum = new ChecksummedFile( file );
503         checksum.fixChecksums( algorithms );
504     }
505
506     private void queueRepositoryTask( String repositoryId, File localFile )
507     {
508         RepositoryTask task = new RepositoryTask();
509         task.setRepositoryId( repositoryId );
510         task.setResourceFile( localFile );
511         task.setUpdateRelatedArtifacts( true );
512         task.setScanAll( false );
513
514         try
515         {
516             scheduler.queueTask( task );
517         }
518         catch ( TaskQueueException e )
519         {
520             log.error( "Unable to queue repository task to execute consumers on resource file ['" + localFile.getName()
521                            + "']." );
522         }
523     }
524
525     private void copyFile( File sourceFile, File targetPath, String targetFilename, boolean fixChecksums )
526         throws IOException
527     {
528         FileOutputStream out = new FileOutputStream( new File( targetPath, targetFilename ) );
529         FileInputStream input = new FileInputStream( sourceFile );
530
531         try
532         {
533             IOUtils.copy( input, out );
534         }
535         finally
536         {
537             out.close();
538             input.close();
539         }
540
541         if ( fixChecksums )
542         {
543             fixChecksums( new File( targetPath, targetFilename ) );
544         }
545     }
546
547     /**
548      * Update artifact level metadata. If it does not exist, create the metadata and fix checksums if necessary.
549      */
550     private void updateProjectMetadata( String targetPath, Date lastUpdatedTimestamp, String timestamp, int buildNumber,
551                                         boolean fixChecksums, FileMetadata fileMetadata, String groupId,
552                                         String artifactId, String version, String packaging )
553         throws RepositoryMetadataException
554     {
555         List<String> availableVersions = new ArrayList<String>();
556         String latestVersion = version;
557
558         File projectDir = new File( targetPath ).getParentFile();
559         File projectMetadataFile = new File( projectDir, MetadataTools.MAVEN_METADATA );
560
561         ArchivaRepositoryMetadata projectMetadata = getMetadata( projectMetadataFile );
562
563         if ( projectMetadataFile.exists() )
564         {
565             availableVersions = projectMetadata.getAvailableVersions();
566
567             Collections.sort( availableVersions, VersionComparator.getInstance() );
568
569             if ( !availableVersions.contains( version ) )
570             {
571                 availableVersions.add( version );
572             }
573
574             latestVersion = availableVersions.get( availableVersions.size() - 1 );
575         }
576         else
577         {
578             availableVersions.add( version );
579
580             projectMetadata.setGroupId( groupId );
581             projectMetadata.setArtifactId( artifactId );
582         }
583
584         if ( projectMetadata.getGroupId() == null )
585         {
586             projectMetadata.setGroupId( groupId );
587         }
588
589         if ( projectMetadata.getArtifactId() == null )
590         {
591             projectMetadata.setArtifactId( artifactId );
592         }
593
594         projectMetadata.setLatestVersion( latestVersion );
595         projectMetadata.setLastUpdatedTimestamp( lastUpdatedTimestamp );
596         projectMetadata.setAvailableVersions( availableVersions );
597
598         if ( !VersionUtil.isSnapshot( version ) )
599         {
600             projectMetadata.setReleasedVersion( latestVersion );
601         }
602
603         RepositoryMetadataWriter.write( projectMetadata, projectMetadataFile );
604
605         if ( fixChecksums )
606         {
607             fixChecksums( projectMetadataFile );
608         }
609     }
610
611     /**
612      * Update version level metadata for snapshot artifacts. If it does not exist, create the metadata and fix checksums
613      * if necessary.
614      */
615     private void updateVersionMetadata( ArchivaRepositoryMetadata metadata, File metadataFile,
616                                         Date lastUpdatedTimestamp, String timestamp, int buildNumber,
617                                         boolean fixChecksums, FileMetadata fileMetadata, String groupId,
618                                         String artifactId, String version, String packaging )
619         throws RepositoryMetadataException
620     {
621         if ( !metadataFile.exists() )
622         {
623             metadata.setGroupId( groupId );
624             metadata.setArtifactId( artifactId );
625             metadata.setVersion( version );
626         }
627
628         if ( metadata.getSnapshotVersion() == null )
629         {
630             metadata.setSnapshotVersion( new SnapshotVersion() );
631         }
632
633         metadata.getSnapshotVersion().setBuildNumber( buildNumber );
634         metadata.getSnapshotVersion().setTimestamp( timestamp );
635         metadata.setLastUpdatedTimestamp( lastUpdatedTimestamp );
636
637         RepositoryMetadataWriter.write( metadata, metadataFile );
638
639         if ( fixChecksums )
640         {
641             fixChecksums( metadataFile );
642         }
643     }
644
645
646 }