]> source.dussan.org Git - archiva.git/blob
d485d22b5fe32bac3e92dbee33c3b5de27d2bbea
[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 = 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, final boolean generatePom )
211         throws ArchivaRestServiceException
212     {
213         List<FileMetadata> fileMetadatas =
214             (List<FileMetadata>) httpServletRequest.getSession().getAttribute( FILES_SESSION_KEY );
215         if ( fileMetadatas == null || fileMetadatas.isEmpty() )
216         {
217             return Boolean.FALSE;
218         }
219         // get from the session file with groupId/artifactId
220
221         Iterable<FileMetadata> filesToAdd = Iterables.filter( fileMetadatas, new Predicate<FileMetadata>()
222         {
223             public boolean apply( FileMetadata fileMetadata )
224             {
225                 if ( fileMetadata == null )
226                 {
227                     return false;
228                 }
229                 return StringUtils.equals( groupId, fileMetadata.getGroupId() ) && StringUtils.equals( artifactId,
230                                                                                                        fileMetadata.getArtifactId() )
231                     && !fileMetadata.isPomFile();
232             }
233         } );
234         Iterator<FileMetadata> iterator = filesToAdd.iterator();
235         boolean pomGenerated = false;
236         while ( iterator.hasNext() )
237         {
238             FileMetadata fileMetadata = iterator.next();
239             log.debug( "fileToAdd: {}", fileMetadata );
240             saveFile( repositoryId, fileMetadata, generatePom && !pomGenerated );
241             pomGenerated = true;
242         }
243
244         filesToAdd = Iterables.filter( fileMetadatas, new Predicate<FileMetadata>()
245         {
246             public boolean apply( @Nullable FileMetadata fileMetadata )
247             {
248                 return fileMetadata.isPomFile();
249             }
250         } );
251
252         iterator = filesToAdd.iterator();
253         while ( iterator.hasNext() )
254         {
255             FileMetadata fileMetadata = iterator.next();
256             log.debug( "fileToAdd: {}", fileMetadata );
257             savePomFile( repositoryId, fileMetadata );
258         }
259
260         return Boolean.TRUE;
261     }
262
263     protected void savePomFile( String repositoryId, FileMetadata fileMetadata )
264         throws ArchivaRestServiceException
265     {
266
267         try
268         {
269             boolean fixChecksums =
270                 !( archivaAdministration.getKnownContentConsumers().contains( "create-missing-checksums" ) );
271
272             ManagedRepository repoConfig = managedRepositoryAdmin.getManagedRepository( repositoryId );
273
274             ArtifactReference artifactReference = new ArtifactReference();
275             artifactReference.setArtifactId( fileMetadata.getArtifactId() );
276             artifactReference.setGroupId( fileMetadata.getGroupId() );
277             artifactReference.setVersion( fileMetadata.getVersion() );
278             artifactReference.setClassifier( fileMetadata.getClassifier() );
279             artifactReference.setType( fileMetadata.getPackaging() );
280
281             ManagedRepositoryContent repository = repositoryFactory.getManagedRepositoryContent( repositoryId );
282
283             String artifactPath = repository.toPath( artifactReference );
284
285             int lastIndex = artifactPath.lastIndexOf( '/' );
286
287             String path = artifactPath.substring( 0, lastIndex );
288             File targetPath = new File( repoConfig.getLocation(), path );
289
290             String pomFilename = artifactPath.substring( lastIndex + 1 );
291             if ( StringUtils.isNotEmpty( fileMetadata.getClassifier() ) )
292             {
293                 pomFilename = StringUtils.remove( pomFilename, "-" + fileMetadata.getClassifier() );
294             }
295             pomFilename = FilenameUtils.removeExtension( pomFilename ) + ".pom";
296
297             copyFile( new File( fileMetadata.getServerFileName() ), targetPath, pomFilename, fixChecksums );
298             triggerAuditEvent( repoConfig.getId(), path + "/" + pomFilename, AuditEvent.UPLOAD_FILE );
299             queueRepositoryTask( repoConfig.getId(), new File( targetPath, pomFilename ) );
300         }
301         catch ( IOException ie )
302         {
303             throw new ArchivaRestServiceException( "Error encountered while uploading pom file: " + ie.getMessage(),
304                                                    Response.Status.INTERNAL_SERVER_ERROR.getStatusCode() );
305         }
306         catch ( RepositoryException rep )
307         {
308             throw new ArchivaRestServiceException( "Repository exception: " + rep.getMessage(),
309                                                    Response.Status.INTERNAL_SERVER_ERROR.getStatusCode() );
310         }
311         catch ( RepositoryAdminException e )
312         {
313             throw new ArchivaRestServiceException( "RepositoryAdmin exception: " + e.getMessage(),
314                                                    Response.Status.INTERNAL_SERVER_ERROR.getStatusCode() );
315         }
316     }
317
318     protected void saveFile( String repositoryId, FileMetadata fileMetadata, boolean generatePom )
319         throws ArchivaRestServiceException
320     {
321         try
322         {
323
324             ManagedRepository repoConfig = managedRepositoryAdmin.getManagedRepository( repositoryId );
325
326             ArtifactReference artifactReference = new ArtifactReference();
327             artifactReference.setArtifactId( fileMetadata.getArtifactId() );
328             artifactReference.setGroupId( fileMetadata.getGroupId() );
329             artifactReference.setVersion( fileMetadata.getVersion() );
330             artifactReference.setClassifier( fileMetadata.getClassifier() );
331             artifactReference.setType( fileMetadata.getPackaging() );
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( fileMetadata.getVersion() ) )
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( fileMetadata.getVersion() ) )
374             {
375                 filename = filename.replaceAll( "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( fileMetadata.getVersion() )
385                     && repoConfig.isBlockRedeployments() )
386                 {
387                     throw new ArchivaRestServiceException(
388                         "Overwriting released artifacts in repository '" + repoConfig.getId() + "' is not allowed.",
389                         Response.Status.BAD_REQUEST.getStatusCode() );
390                 }
391                 else
392                 {
393                     copyFile( new File( fileMetadata.getServerFileName() ), targetPath, filename, fixChecksums );
394                     triggerAuditEvent( repository.getId(), path + "/" + filename, AuditEvent.UPLOAD_FILE );
395                     queueRepositoryTask( repository.getId(), targetFile );
396                 }
397             }
398             catch ( IOException ie )
399             {
400                 throw new ArchivaRestServiceException(
401                     "Overwriting released artifacts in repository '" + repoConfig.getId() + "' is not allowed.",
402                     Response.Status.INTERNAL_SERVER_ERROR.getStatusCode() );
403             }
404
405             if ( generatePom )
406             {
407                 String pomFilename = filename;
408                 if ( StringUtils.isNotEmpty( fileMetadata.getClassifier() ) )
409                 {
410                     pomFilename = StringUtils.remove( pomFilename, "-" + fileMetadata.getClassifier() );
411                 }
412                 pomFilename = FilenameUtils.removeExtension( pomFilename ) + ".pom";
413
414                 try
415                 {
416                     File generatedPomFile = createPom( targetPath, pomFilename, fileMetadata );
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() );
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 );
437
438                 if ( VersionUtil.isSnapshot( fileMetadata.getVersion() ) )
439                 {
440                     updateVersionMetadata( versionMetadata, versionMetadataFile, lastUpdatedTimestamp, timestamp,
441                                            newBuildNumber, fixChecksums, fileMetadata );
442                 }
443             }
444         }
445         catch ( RepositoryNotFoundException re )
446         {
447             throw new ArchivaRestServiceException( "Target repository cannot be found: " + re.getMessage(),
448                                                    Response.Status.INTERNAL_SERVER_ERROR.getStatusCode() );
449         }
450         catch ( RepositoryException rep )
451         {
452             throw new ArchivaRestServiceException( "Repository exception: " + rep.getMessage(),
453                                                    Response.Status.INTERNAL_SERVER_ERROR.getStatusCode() );
454         }
455         catch ( RepositoryAdminException e )
456         {
457             throw new ArchivaRestServiceException( "RepositoryAdmin exception: " + e.getMessage(),
458                                                    Response.Status.INTERNAL_SERVER_ERROR.getStatusCode() );
459         }
460     }
461
462     private ArchivaRepositoryMetadata getMetadata( File metadataFile )
463         throws RepositoryMetadataException
464     {
465         ArchivaRepositoryMetadata metadata = new ArchivaRepositoryMetadata();
466         if ( metadataFile.exists() )
467         {
468             try
469             {
470                 metadata = MavenMetadataReader.read( metadataFile );
471             }
472             catch ( XMLException e )
473             {
474                 throw new RepositoryMetadataException( e.getMessage(), e );
475             }
476         }
477         return metadata;
478     }
479
480     private File createPom( File targetPath, String filename, FileMetadata fileMetadata )
481         throws IOException
482     {
483         Model projectModel = new Model();
484         projectModel.setModelVersion( "4.0.0" );
485         projectModel.setGroupId( fileMetadata.getGroupId() );
486         projectModel.setArtifactId( fileMetadata.getArtifactId() );
487         projectModel.setVersion( fileMetadata.getVersion() );
488         projectModel.setPackaging( fileMetadata.getPackaging() );
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 )
557         throws RepositoryMetadataException
558     {
559         List<String> availableVersions = new ArrayList<String>();
560         String latestVersion = fileMetadata.getVersion();
561
562         File projectDir = new File( targetPath ).getParentFile();
563         File projectMetadataFile = new File( projectDir, MetadataTools.MAVEN_METADATA );
564
565         ArchivaRepositoryMetadata projectMetadata = getMetadata( projectMetadataFile );
566
567         if ( projectMetadataFile.exists() )
568         {
569             availableVersions = projectMetadata.getAvailableVersions();
570
571             Collections.sort( availableVersions, VersionComparator.getInstance() );
572
573             if ( !availableVersions.contains( fileMetadata.getVersion() ) )
574             {
575                 availableVersions.add( fileMetadata.getVersion() );
576             }
577
578             latestVersion = availableVersions.get( availableVersions.size() - 1 );
579         }
580         else
581         {
582             availableVersions.add( fileMetadata.getVersion() );
583
584             projectMetadata.setGroupId( fileMetadata.getGroupId() );
585             projectMetadata.setArtifactId( fileMetadata.getArtifactId() );
586         }
587
588         if ( projectMetadata.getGroupId() == null )
589         {
590             projectMetadata.setGroupId( fileMetadata.getGroupId() );
591         }
592
593         if ( projectMetadata.getArtifactId() == null )
594         {
595             projectMetadata.setArtifactId( fileMetadata.getArtifactId() );
596         }
597
598         projectMetadata.setLatestVersion( latestVersion );
599         projectMetadata.setLastUpdatedTimestamp( lastUpdatedTimestamp );
600         projectMetadata.setAvailableVersions( availableVersions );
601
602         if ( !VersionUtil.isSnapshot( fileMetadata.getVersion() ) )
603         {
604             projectMetadata.setReleasedVersion( latestVersion );
605         }
606
607         RepositoryMetadataWriter.write( projectMetadata, projectMetadataFile );
608
609         if ( fixChecksums )
610         {
611             fixChecksums( projectMetadataFile );
612         }
613     }
614
615     /**
616      * Update version level metadata for snapshot artifacts. If it does not exist, create the metadata and fix checksums
617      * if necessary.
618      */
619     private void updateVersionMetadata( ArchivaRepositoryMetadata metadata, File metadataFile,
620                                         Date lastUpdatedTimestamp, String timestamp, int buildNumber,
621                                         boolean fixChecksums, FileMetadata fileMetadata )
622         throws RepositoryMetadataException
623     {
624         if ( !metadataFile.exists() )
625         {
626             metadata.setGroupId( fileMetadata.getGroupId() );
627             metadata.setArtifactId( fileMetadata.getArtifactId() );
628             metadata.setVersion( fileMetadata.getVersion() );
629         }
630
631         if ( metadata.getSnapshotVersion() == null )
632         {
633             metadata.setSnapshotVersion( new SnapshotVersion() );
634         }
635
636         metadata.getSnapshotVersion().setBuildNumber( buildNumber );
637         metadata.getSnapshotVersion().setTimestamp( timestamp );
638         metadata.setLastUpdatedTimestamp( lastUpdatedTimestamp );
639
640         RepositoryMetadataWriter.write( metadata, metadataFile );
641
642         if ( fixChecksums )
643         {
644             fixChecksums( metadataFile );
645         }
646     }
647
648
649 }