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