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