1 package org.apache.archiva.web.api;
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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
21 import org.apache.archiva.admin.model.RepositoryAdminException;
22 import org.apache.archiva.admin.model.admin.ArchivaAdministration;
23 import org.apache.archiva.checksum.ChecksumAlgorithm;
24 import org.apache.archiva.checksum.ChecksumUtil;
25 import org.apache.archiva.checksum.ChecksummedFile;
26 import org.apache.archiva.common.utils.VersionComparator;
27 import org.apache.archiva.common.utils.VersionUtil;
28 import org.apache.archiva.components.taskqueue.TaskQueueException;
29 import org.apache.archiva.configuration.ArchivaConfiguration;
30 import org.apache.archiva.metadata.model.facets.AuditEvent;
31 import org.apache.archiva.model.ArchivaRepositoryMetadata;
32 import org.apache.archiva.model.SnapshotVersion;
33 import org.apache.archiva.repository.ReleaseScheme;
34 import org.apache.archiva.repository.Repository;
35 import org.apache.archiva.repository.RepositoryException;
36 import org.apache.archiva.repository.RepositoryRegistry;
37 import org.apache.archiva.repository.RepositoryType;
38 import org.apache.archiva.repository.content.ItemSelector;
39 import org.apache.archiva.repository.content.base.ArchivaItemSelector;
40 import org.apache.archiva.repository.metadata.MetadataReader;
41 import org.apache.archiva.repository.metadata.RepositoryMetadataException;
42 import org.apache.archiva.repository.metadata.base.MetadataTools;
43 import org.apache.archiva.repository.metadata.base.RepositoryMetadataWriter;
44 import org.apache.archiva.repository.storage.StorageAsset;
45 import org.apache.archiva.rest.api.services.ArchivaRestServiceException;
46 import org.apache.archiva.rest.services.AbstractRestService;
47 import org.apache.archiva.scheduler.ArchivaTaskScheduler;
48 import org.apache.archiva.scheduler.repository.model.RepositoryTask;
49 import org.apache.archiva.web.model.FileMetadata;
50 import org.apache.commons.io.FilenameUtils;
51 import org.apache.commons.io.IOUtils;
52 import org.apache.commons.lang3.BooleanUtils;
53 import org.apache.commons.lang3.StringUtils;
54 import org.apache.commons.lang3.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;
63 import javax.annotation.PostConstruct;
64 import javax.inject.Inject;
65 import javax.inject.Named;
66 import javax.servlet.http.HttpServletRequest;
67 import javax.servlet.http.HttpSession;
68 import javax.ws.rs.core.Context;
69 import javax.ws.rs.core.Response;
70 import java.io.FileOutputStream;
71 import java.io.IOException;
72 import java.io.OutputStreamWriter;
73 import java.io.Writer;
74 import java.net.URLDecoder;
75 import java.nio.file.FileSystems;
76 import java.nio.file.Files;
77 import java.nio.file.Path;
78 import java.nio.file.Paths;
79 import java.text.DateFormat;
80 import java.text.SimpleDateFormat;
81 import java.util.ArrayList;
82 import java.util.Calendar;
83 import java.util.Collections;
84 import java.util.Date;
85 import java.util.Iterator;
86 import java.util.List;
87 import java.util.TimeZone;
88 import java.util.concurrent.CopyOnWriteArrayList;
92 * Service for uploading files to the repository.
94 * @author Olivier Lamy
95 * @author Martin Stockhammer
97 @Service("fileUploadService#rest")
98 public class DefaultFileUploadService
99 extends AbstractRestService
100 implements FileUploadService {
101 private Logger log = LoggerFactory.getLogger(getClass());
104 private HttpServletRequest httpServletRequest;
107 private ArchivaAdministration archivaAdministration;
110 ArchivaConfiguration configuration;
112 private List<ChecksumAlgorithm> algorithms;
114 private final String FS = FileSystems.getDefault().getSeparator();
117 @Named(value = "archivaTaskScheduler#repository")
118 private ArchivaTaskScheduler<RepositoryTask> scheduler;
121 private RepositoryRegistry repositoryRegistry;
123 private String getStringValue(MultipartBody multipartBody, String attachmentId)
125 Attachment attachment = multipartBody.getAttachment(attachmentId);
126 return attachment == null ? "" :
127 StringUtils.trim(URLDecoder.decode(IOUtils.toString(attachment.getDataHandler().getInputStream(), "UTF-8"), "UTF-8"));
131 private void initialize() {
132 algorithms = ChecksumUtil.getAlgorithms(configuration.getConfiguration().getArchivaRuntimeConfiguration().getChecksumTypes());
136 public FileMetadata post(MultipartBody multipartBody)
137 throws ArchivaRestServiceException {
141 String classifier = getStringValue(multipartBody, "classifier");
142 String packaging = getStringValue(multipartBody, "packaging");
144 checkParamChars("classifier", classifier);
145 checkParamChars("packaging", packaging);
147 // skygo: http header form pomFile was once sending 1 for true and void for false
148 // leading to permanent false value for pomFile if using toBoolean(); use , "1", ""
150 boolean pomFile = false;
152 pomFile = BooleanUtils.toBoolean(getStringValue(multipartBody, "pomFile"));
153 } catch (IllegalArgumentException ex) {
154 ArchivaRestServiceException e = new ArchivaRestServiceException("Bad value for boolean pomFile field.", null);
155 e.setHttpErrorCode(422);
156 e.setFieldName("pomFile");
157 e.setErrorKey("fileupload.malformed.pomFile");
161 Attachment file = multipartBody.getAttachment("files[]");
163 //Content-Disposition: form-data; name="files[]"; filename="org.apache.karaf.features.command-2.2.2.jar"
164 String fileName = file.getContentDisposition().getParameter("filename");
165 Path fileNamePath = Paths.get(fileName);
166 if (!fileName.equals(fileNamePath.getFileName().toString())) {
167 ArchivaRestServiceException e = new ArchivaRestServiceException("Bad filename in upload content: " + fileName + " - File traversal chars (..|/) are not allowed"
169 e.setHttpErrorCode(422);
170 e.setErrorKey("fileupload.malformed.filename");
174 Path tmpFile = Files.createTempFile("upload-artifact", ".tmp");
175 tmpFile.toFile().deleteOnExit();
176 IOUtils.copy(file.getDataHandler().getInputStream(), new FileOutputStream(tmpFile.toFile()));
177 FileMetadata fileMetadata = new FileMetadata(fileName, Files.size(tmpFile), "theurl");
178 fileMetadata.setServerFileName(tmpFile.toString());
179 fileMetadata.setClassifier(classifier);
180 fileMetadata.setDeleteUrl(tmpFile.getFileName().toString());
181 fileMetadata.setPomFile(pomFile);
182 fileMetadata.setPackaging(packaging);
184 log.info("uploading file: {}", fileMetadata);
186 List<FileMetadata> fileMetadatas = getSessionFilesList();
188 fileMetadatas.add(fileMetadata);
191 } catch (IOException e) {
192 throw new ArchivaRestServiceException(e.getMessage(),
193 Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e);
199 * @return The file list from the session.
201 @SuppressWarnings("unchecked")
202 protected List<FileMetadata> getSessionFilesList() {
203 final HttpSession session = httpServletRequest.getSession();
204 List<FileMetadata> fileMetadata = (List<FileMetadata>) session.getAttribute(FILES_SESSION_KEY);
205 // Double check with synchronization, we assume, that httpServletRequest is
206 // fully initialized (no volatile)
207 if (fileMetadata == null) {
208 synchronized (session) {
209 fileMetadata = (List<FileMetadata>) session.getAttribute(FILES_SESSION_KEY);
210 if (fileMetadata == null) {
211 fileMetadata = new CopyOnWriteArrayList<>();
212 session.setAttribute(FILES_SESSION_KEY, fileMetadata);
220 public Boolean deleteFile(String fileName)
221 throws ArchivaRestServiceException {
222 log.debug("Deleting file {}", fileName);
223 // we make sure, that there are no other path components in the filename:
224 String checkedFileName = Paths.get(fileName).getFileName().toString();
225 Path file = SystemUtils.getJavaIoTmpDir().toPath().resolve(checkedFileName);
226 log.debug("delete file:{},exists:{}", file, Files.exists(file));
227 boolean removed = getSessionFileMetadatas().remove(new FileMetadata(fileName));
228 // try with full name as ui only know the file name
230 removed = getSessionFileMetadatas().remove(new FileMetadata(file.toString()));
234 Files.deleteIfExists(file);
236 } catch (IOException e) {
237 log.error("Could not delete file {}: {}", file, e.getMessage(), e);
240 return Boolean.FALSE;
244 public Boolean clearUploadedFiles()
245 throws ArchivaRestServiceException {
246 List<FileMetadata> fileMetadatas = new ArrayList<>(getSessionFileMetadatas());
247 for (FileMetadata fileMetadata : fileMetadatas) {
248 deleteFile(Paths.get(fileMetadata.getServerFileName()).toString());
250 getSessionFileMetadatas().clear();
255 public List<FileMetadata> getSessionFileMetadatas()
256 throws ArchivaRestServiceException {
257 return getSessionFilesList();
261 private boolean hasValidChars(String checkString) {
262 if (checkString.contains(FS)) {
265 if (checkString.contains("../")) {
268 if (checkString.contains("/..")) {
274 private void checkParamChars(String param, String value) throws ArchivaRestServiceException {
275 if (!hasValidChars(value)) {
276 ArchivaRestServiceException e = new ArchivaRestServiceException("Bad characters in " + param, null);
277 e.setHttpErrorCode(422);
278 e.setErrorKey("fileupload.malformed.param");
279 e.setFieldName(param);
285 public Boolean save(String repositoryId, String groupId, String artifactId, String version, String packaging,
287 throws ArchivaRestServiceException {
288 repositoryId = StringUtils.trim(repositoryId);
289 groupId = StringUtils.trim(groupId);
290 artifactId = StringUtils.trim(artifactId);
291 version = StringUtils.trim(version);
292 packaging = StringUtils.trim(packaging);
294 checkParamChars("repositoryId", repositoryId);
295 checkParamChars("groupId", groupId);
296 checkParamChars("artifactId", artifactId);
297 checkParamChars("version", version);
298 checkParamChars("packaging", packaging);
301 List<FileMetadata> fileMetadatas = getSessionFilesList();
302 if (fileMetadatas == null || fileMetadatas.isEmpty()) {
303 return Boolean.FALSE;
306 org.apache.archiva.repository.ManagedRepository repository = repositoryRegistry.getManagedRepository(repositoryId);
307 if (repository == null) {
309 throw new ArchivaRestServiceException("Cannot find managed repository with id " + repositoryId,
310 Response.Status.BAD_REQUEST.getStatusCode(), null);
313 if (VersionUtil.isSnapshot(version) && !repository.getActiveReleaseSchemes().contains( ReleaseScheme.SNAPSHOT )) {
315 throw new ArchivaRestServiceException(
316 "Managed repository with id " + repositoryId + " do not accept snapshots",
317 Response.Status.BAD_REQUEST.getStatusCode(), null);
320 // get from the session file with groupId/artifactId
322 Iterator<FileMetadata> iterator = fileMetadatas.stream( )
323 .filter( fileMetadata -> fileMetadata != null && !fileMetadata.isPomFile( ) )
325 boolean pomGenerated = false;
326 while (iterator.hasNext()) {
327 FileMetadata fileMetadata = iterator.next();
328 log.debug("fileToAdd: {}", fileMetadata);
329 saveFile(repositoryId, fileMetadata, generatePom && !pomGenerated, groupId, artifactId, version,
332 deleteFile(fileMetadata.getServerFileName());
335 iterator = fileMetadatas.stream( ).filter( fileMetadata -> fileMetadata != null && fileMetadata.isPomFile( ) )
337 while (iterator.hasNext()) {
338 FileMetadata fileMetadata = iterator.next();
339 log.debug("fileToAdd: {}", fileMetadata);
340 savePomFile(repositoryId, fileMetadata, groupId, artifactId, version, packaging);
341 deleteFile(fileMetadata.getServerFileName());
347 protected void savePomFile(String repositoryId, FileMetadata fileMetadata, String groupId, String artifactId,
348 String version, String packaging)
349 throws ArchivaRestServiceException {
351 log.debug("Saving POM");
353 boolean fixChecksums =
354 !(archivaAdministration.getKnownContentConsumers().contains("create-missing-checksums"));
356 org.apache.archiva.repository.ManagedRepository repository = repositoryRegistry.getManagedRepository(repositoryId);
357 ItemSelector selector = ArchivaItemSelector.builder( )
358 .withNamespace( groupId )
359 .withProjectId( artifactId )
360 .withArtifactId( artifactId )
361 .withArtifactVersion( version )
362 .withExtension( packaging ).build();
364 StorageAsset pomPath = repository.getContent( ).getItem( selector ).getAsset();
365 StorageAsset targetPath = pomPath.getParent();
367 String pomFilename = pomPath.getName();
368 if (StringUtils.isNotEmpty(fileMetadata.getClassifier())) {
369 pomFilename = StringUtils.remove(pomFilename, "-" + fileMetadata.getClassifier());
371 pomFilename = FilenameUtils.removeExtension(pomFilename) + ".pom";
373 copyFile(Paths.get(fileMetadata.getServerFileName()), targetPath, pomFilename, fixChecksums);
374 triggerAuditEvent(repository.getId(), targetPath.resolve(pomFilename).toString(), AuditEvent.UPLOAD_FILE);
375 queueRepositoryTask(repository.getId(), targetPath.resolve(pomFilename));
376 log.debug("Finished Saving POM");
377 } catch (IOException ie) {
378 log.error("IOException for POM {}", ie.getMessage());
379 throw new ArchivaRestServiceException("Error encountered while uploading pom file: " + ie.getMessage(),
380 Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), ie);
382 catch (RepositoryAdminException e) {
383 log.error("RepositoryAdminException for POM {}", e.getMessage());
384 throw new ArchivaRestServiceException("RepositoryAdmin exception: " + e.getMessage(),
385 Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e);
389 protected void saveFile(String repositoryId, FileMetadata fileMetadata, boolean generatePom, String groupId,
390 String artifactId, String version, String packaging)
391 throws ArchivaRestServiceException {
392 log.debug("Saving file");
395 org.apache.archiva.repository.ManagedRepository repository = repositoryRegistry.getManagedRepository(repositoryId);
397 log.debug( "Finding artifact path for {}, {}, {}, {}", groupId, artifactId, version, packaging );
398 ItemSelector selector = ArchivaItemSelector.builder( )
399 .withNamespace( groupId )
400 .withProjectId( artifactId )
401 .withArtifactId( artifactId )
402 .withArtifactVersion( version )
403 .withExtension( packaging ).build();
405 StorageAsset artifactPath = repository.getContent( ).getItem( selector ).getAsset();
406 StorageAsset targetPath = artifactPath.getParent();
408 log.debug("artifactPath: {} found targetPath: {}", artifactPath, targetPath);
410 Date lastUpdatedTimestamp = Calendar.getInstance().getTime();
411 int newBuildNumber = -1;
412 String timestamp = null;
414 StorageAsset versionMetadataFile = targetPath.resolve(MetadataTools.MAVEN_METADATA);
415 ArchivaRepositoryMetadata versionMetadata = getMetadata(versionMetadataFile);
417 if (VersionUtil.isSnapshot(version)) {
418 TimeZone timezone = TimeZone.getTimeZone("UTC");
419 DateFormat fmt = new SimpleDateFormat("yyyyMMdd.HHmmss");
420 fmt.setTimeZone(timezone);
421 timestamp = fmt.format(lastUpdatedTimestamp);
422 if (versionMetadata.getSnapshotVersion() != null) {
423 newBuildNumber = versionMetadata.getSnapshotVersion().getBuildNumber() + 1;
429 if (!targetPath.exists()) {
433 String filename = artifactPath.getName().toString();
434 if (VersionUtil.isSnapshot(version)) {
435 filename = filename.replaceAll(VersionUtil.SNAPSHOT, timestamp + "-" + newBuildNumber);
438 // We always fix checksums for newly uploaded files, even if the content consumer is active.
439 boolean fixChecksums = true;
440 // !(archivaAdministration.getKnownContentConsumers().contains("create-missing-checksums"));
443 StorageAsset targetFile = targetPath.resolve(filename);
444 if (targetFile.exists() && !VersionUtil.isSnapshot(version) && repository.blocksRedeployments()) {
445 throw new ArchivaRestServiceException(
446 "Overwriting released artifacts in repository '" + repository.getId() + "' is not allowed.",
447 Response.Status.BAD_REQUEST.getStatusCode(), null);
449 copyFile(Paths.get(fileMetadata.getServerFileName()), targetPath, filename, fixChecksums);
450 triggerAuditEvent(repository.getId(), artifactPath.toString(), AuditEvent.UPLOAD_FILE);
451 queueRepositoryTask(repository.getId(), targetFile);
453 } catch (IOException ie) {
454 log.error("IOException copying file: {}", ie.getMessage(), ie);
455 throw new ArchivaRestServiceException(
456 "Overwriting released artifacts in repository '" + repository.getId() + "' is not allowed.",
457 Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), ie);
461 String pomFilename = filename;
462 if (StringUtils.isNotEmpty(fileMetadata.getClassifier())) {
463 pomFilename = StringUtils.remove(pomFilename, "-" + fileMetadata.getClassifier());
465 pomFilename = FilenameUtils.removeExtension(pomFilename) + ".pom";
468 StorageAsset generatedPomFile =
469 createPom(targetPath, pomFilename, fileMetadata, groupId, artifactId, version, packaging);
470 triggerAuditEvent(repository.getId(), targetPath.resolve(pomFilename).toString(), AuditEvent.UPLOAD_FILE);
472 fixChecksums(generatedPomFile);
474 queueRepositoryTask(repository.getId(), generatedPomFile);
475 } catch (IOException ie) {
476 throw new ArchivaRestServiceException(
477 "Error encountered while writing pom file: " + ie.getMessage(),
478 Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), ie);
482 // explicitly update only if metadata-updater consumer is not enabled!
483 if (!archivaAdministration.getKnownContentConsumers().contains("metadata-updater")) {
484 updateProjectMetadata(targetPath, lastUpdatedTimestamp, timestamp, newBuildNumber,
485 fixChecksums, fileMetadata, groupId, artifactId, version, packaging);
487 if (VersionUtil.isSnapshot(version)) {
488 updateVersionMetadata(versionMetadata, versionMetadataFile, lastUpdatedTimestamp, timestamp,
489 newBuildNumber, fixChecksums, fileMetadata, groupId, artifactId, version,
494 catch (RepositoryException rep) {
495 log.error("RepositoryException during save {}", rep.getMessage());
496 throw new ArchivaRestServiceException("Repository exception: " + rep.getMessage(),
497 Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), rep);
498 } catch (RepositoryAdminException e) {
499 log.error("RepositoryAdminException during save {}", e.getMessage());
500 throw new ArchivaRestServiceException("RepositoryAdmin exception: " + e.getMessage(),
501 Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e);
502 } catch (IOException e) {
503 log.error("IOException during save {}", e.getMessage());
504 throw new ArchivaRestServiceException("Repository exception " + e.getMessage(),
505 Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e);
509 private ArchivaRepositoryMetadata getMetadata(StorageAsset metadataFile)
510 throws RepositoryMetadataException {
511 ArchivaRepositoryMetadata metadata = new ArchivaRepositoryMetadata();
512 if (metadataFile.exists()) {
513 Repository repo = repositoryRegistry.getRepositoryOfAsset( metadataFile );
514 RepositoryType type = repo == null ? RepositoryType.MAVEN : repo.getType( );
515 MetadataReader metadataReader = repositoryRegistry.getMetadataReader( type );
516 metadata = metadataReader.read(metadataFile);
521 private StorageAsset createPom(StorageAsset targetPath, String filename, FileMetadata fileMetadata, String groupId,
522 String artifactId, String version, String packaging)
524 Model projectModel = new Model();
525 projectModel.setModelVersion("4.0.0");
526 projectModel.setGroupId(groupId);
527 projectModel.setArtifactId(artifactId);
528 projectModel.setVersion(version);
529 projectModel.setPackaging(packaging);
531 StorageAsset pomFile = targetPath.resolve(filename);
532 MavenXpp3Writer writer = new MavenXpp3Writer();
534 try (Writer w = new OutputStreamWriter(pomFile.getWriteStream(true))) {
535 writer.write(w, projectModel);
541 private void fixChecksums(StorageAsset file) {
542 ChecksummedFile checksum = new ChecksummedFile(file.getFilePath());
543 checksum.fixChecksums(algorithms);
546 private void queueRepositoryTask(String repositoryId, StorageAsset localFile) {
547 RepositoryTask task = new RepositoryTask();
548 task.setRepositoryId(repositoryId);
549 task.setResourceFile(localFile);
550 task.setUpdateRelatedArtifacts(true);
551 task.setScanAll(false);
554 scheduler.queueTask(task);
555 } catch (TaskQueueException e) {
556 log.error("Unable to queue repository task to execute consumers on resource file ['{}"
557 + "'].", localFile.getName());
561 private void copyFile(Path sourceFile, StorageAsset targetPath, String targetFilename, boolean fixChecksums)
564 targetPath.resolve(targetFilename).replaceDataFromFile(sourceFile);
567 fixChecksums(targetPath.resolve(targetFilename));
572 * Update artifact level metadata. If it does not exist, create the metadata and fix checksums if necessary.
574 private void updateProjectMetadata(StorageAsset targetPath, Date lastUpdatedTimestamp, String timestamp, int buildNumber,
575 boolean fixChecksums, FileMetadata fileMetadata, String groupId,
576 String artifactId, String version, String packaging)
577 throws RepositoryMetadataException {
578 List<String> availableVersions = new ArrayList<>();
579 String latestVersion = version;
581 StorageAsset projectDir = targetPath.getParent();
582 StorageAsset projectMetadataFile = projectDir.resolve(MetadataTools.MAVEN_METADATA);
584 ArchivaRepositoryMetadata projectMetadata = getMetadata(projectMetadataFile);
586 if (projectMetadataFile.exists()) {
587 availableVersions = projectMetadata.getAvailableVersions();
589 Collections.sort(availableVersions, VersionComparator.getInstance());
591 if (!availableVersions.contains(version)) {
592 availableVersions.add(version);
595 latestVersion = availableVersions.get(availableVersions.size() - 1);
597 availableVersions.add(version);
599 projectMetadata.setGroupId(groupId);
600 projectMetadata.setArtifactId(artifactId);
603 if (projectMetadata.getGroupId() == null) {
604 projectMetadata.setGroupId(groupId);
607 if (projectMetadata.getArtifactId() == null) {
608 projectMetadata.setArtifactId(artifactId);
611 projectMetadata.setLatestVersion(latestVersion);
612 projectMetadata.setLastUpdatedTimestamp(lastUpdatedTimestamp);
613 projectMetadata.setAvailableVersions(availableVersions);
615 if (!VersionUtil.isSnapshot(version)) {
616 projectMetadata.setReleasedVersion(latestVersion);
619 RepositoryMetadataWriter.write(projectMetadata, projectMetadataFile);
622 fixChecksums(projectMetadataFile);
627 * Update version level metadata for snapshot artifacts. If it does not exist, create the metadata and fix checksums
630 private void updateVersionMetadata(ArchivaRepositoryMetadata metadata, StorageAsset metadataFile,
631 Date lastUpdatedTimestamp, String timestamp, int buildNumber,
632 boolean fixChecksums, FileMetadata fileMetadata, String groupId,
633 String artifactId, String version, String packaging)
634 throws RepositoryMetadataException {
635 if (!metadataFile.exists()) {
636 metadata.setGroupId(groupId);
637 metadata.setArtifactId(artifactId);
638 metadata.setVersion(version);
641 if (metadata.getSnapshotVersion() == null) {
642 metadata.setSnapshotVersion(new SnapshotVersion());
645 metadata.getSnapshotVersion().setBuildNumber(buildNumber);
646 metadata.getSnapshotVersion().setTimestamp(timestamp);
647 metadata.setLastUpdatedTimestamp(lastUpdatedTimestamp);
649 RepositoryMetadataWriter.write(metadata, metadataFile);
652 fixChecksums(metadataFile);