You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

DefaultFileUploadService.java 27KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689
  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. import com.google.common.base.Predicate;
  21. import com.google.common.collect.Iterables;
  22. import org.apache.archiva.admin.model.RepositoryAdminException;
  23. import org.apache.archiva.admin.model.admin.ArchivaAdministration;
  24. import org.apache.archiva.admin.model.beans.ManagedRepository;
  25. import org.apache.archiva.admin.model.managed.ManagedRepositoryAdmin;
  26. import org.apache.archiva.metadata.model.facets.AuditEvent;
  27. import org.apache.archiva.checksum.ChecksumAlgorithm;
  28. import org.apache.archiva.checksum.ChecksummedFile;
  29. import org.apache.archiva.common.utils.VersionComparator;
  30. import org.apache.archiva.common.utils.VersionUtil;
  31. import org.apache.archiva.maven2.metadata.MavenMetadataReader;
  32. import org.apache.archiva.model.ArchivaRepositoryMetadata;
  33. import org.apache.archiva.model.ArtifactReference;
  34. import org.apache.archiva.model.SnapshotVersion;
  35. import org.apache.archiva.redback.components.taskqueue.TaskQueueException;
  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.model.RepositoryTask;
  47. import org.apache.archiva.web.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.slf4j.Logger;
  59. import org.slf4j.LoggerFactory;
  60. import org.springframework.stereotype.Service;
  61. import javax.inject.Inject;
  62. import javax.inject.Named;
  63. import javax.servlet.http.HttpServletRequest;
  64. import javax.ws.rs.core.Context;
  65. import javax.ws.rs.core.Response;
  66. import java.io.File;
  67. import java.io.FileOutputStream;
  68. import java.io.FileWriter;
  69. import java.io.IOException;
  70. import java.nio.file.Files;
  71. import java.nio.file.StandardCopyOption;
  72. import java.text.DateFormat;
  73. import java.text.SimpleDateFormat;
  74. import java.util.ArrayList;
  75. import java.util.Calendar;
  76. import java.util.Collections;
  77. import java.util.Date;
  78. import java.util.Iterator;
  79. import java.util.List;
  80. import java.util.TimeZone;
  81. import java.util.concurrent.CopyOnWriteArrayList;
  82. /**
  83. * @author Olivier Lamy
  84. */
  85. @Service("fileUploadService#rest")
  86. public class DefaultFileUploadService
  87. extends AbstractRestService
  88. implements FileUploadService
  89. {
  90. private Logger log = LoggerFactory.getLogger( getClass() );
  91. @Context
  92. private HttpServletRequest httpServletRequest;
  93. @Inject
  94. private ManagedRepositoryAdmin managedRepositoryAdmin;
  95. @Inject
  96. private RepositoryContentFactory repositoryFactory;
  97. @Inject
  98. private ArchivaAdministration archivaAdministration;
  99. private ChecksumAlgorithm[] algorithms = new ChecksumAlgorithm[]{ ChecksumAlgorithm.SHA1, ChecksumAlgorithm.MD5 };
  100. @Inject
  101. @Named(value = "archivaTaskScheduler#repository")
  102. private ArchivaTaskScheduler scheduler;
  103. private String getStringValue( MultipartBody multipartBody, String attachmentId )
  104. throws IOException
  105. {
  106. Attachment attachment = multipartBody.getAttachment( attachmentId );
  107. return attachment == null ? "" : IOUtils.toString( attachment.getDataHandler().getInputStream() );
  108. }
  109. @Override
  110. public FileMetadata post( MultipartBody multipartBody )
  111. throws ArchivaRestServiceException
  112. {
  113. try
  114. {
  115. String classifier = getStringValue( multipartBody, "classifier" );
  116. String packaging = getStringValue( multipartBody, "packaging" );
  117. // skygo: http header form pomFile was once sending 1 for true and void for false
  118. // leading to permanent false value for pomFile if using toBoolean(); use , "1", ""
  119. boolean pomFile = BooleanUtils.toBoolean( getStringValue( multipartBody, "pomFile" ) );
  120. Attachment file = multipartBody.getAttachment( "files[]" );
  121. //Content-Disposition: form-data; name="files[]"; filename="org.apache.karaf.features.command-2.2.2.jar"
  122. String fileName = file.getContentDisposition().getParameter( "filename" );
  123. File tmpFile = File.createTempFile( "upload-artifact", ".tmp" );
  124. tmpFile.deleteOnExit();
  125. IOUtils.copy( file.getDataHandler().getInputStream(), new FileOutputStream( tmpFile ) );
  126. FileMetadata fileMetadata = new FileMetadata( fileName, tmpFile.length(), "theurl" );
  127. fileMetadata.setServerFileName( tmpFile.getPath() );
  128. fileMetadata.setClassifier( classifier );
  129. fileMetadata.setDeleteUrl( tmpFile.getName() );
  130. fileMetadata.setPomFile( pomFile );
  131. fileMetadata.setPackaging( packaging );
  132. log.info( "uploading file: {}", fileMetadata );
  133. List<FileMetadata> fileMetadatas = getSessionFilesList();
  134. fileMetadatas.add( fileMetadata );
  135. return fileMetadata;
  136. }
  137. catch ( IOException e )
  138. {
  139. throw new ArchivaRestServiceException( e.getMessage(),
  140. Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e );
  141. }
  142. }
  143. /**
  144. * FIXME must be per session synchronized not globally
  145. *
  146. * @return
  147. */
  148. protected synchronized List<FileMetadata> getSessionFilesList()
  149. {
  150. List<FileMetadata> fileMetadatas =
  151. (List<FileMetadata>) httpServletRequest.getSession().getAttribute( FILES_SESSION_KEY );
  152. if ( fileMetadatas == null )
  153. {
  154. fileMetadatas = new CopyOnWriteArrayList<>();
  155. httpServletRequest.getSession().setAttribute( FILES_SESSION_KEY, fileMetadatas );
  156. }
  157. return fileMetadatas;
  158. }
  159. @Override
  160. public Boolean deleteFile( String fileName )
  161. throws ArchivaRestServiceException
  162. {
  163. File file = new File( SystemUtils.getJavaIoTmpDir(), fileName );
  164. log.debug( "delete file:{},exists:{}", file.getPath(), file.exists() );
  165. boolean removed = getSessionFileMetadatas().remove( new FileMetadata( fileName ) );
  166. // try with full name as ui only know the file name
  167. if ( !removed )
  168. {
  169. removed = getSessionFileMetadatas().remove( new FileMetadata( file.getPath() ) );
  170. }
  171. if ( file.exists() )
  172. {
  173. return file.delete();
  174. }
  175. return Boolean.FALSE;
  176. }
  177. @Override
  178. public Boolean clearUploadedFiles()
  179. throws ArchivaRestServiceException
  180. {
  181. List<FileMetadata> fileMetadatas = new ArrayList( getSessionFileMetadatas() );
  182. for ( FileMetadata fileMetadata : fileMetadatas )
  183. {
  184. deleteFile( new File( fileMetadata.getServerFileName() ).getPath() );
  185. }
  186. getSessionFileMetadatas().clear();
  187. return Boolean.TRUE;
  188. }
  189. @Override
  190. public List<FileMetadata> getSessionFileMetadatas()
  191. throws ArchivaRestServiceException
  192. {
  193. List<FileMetadata> fileMetadatas =
  194. (List<FileMetadata>) httpServletRequest.getSession().getAttribute( FILES_SESSION_KEY );
  195. return fileMetadatas == null ? Collections.<FileMetadata>emptyList() : fileMetadatas;
  196. }
  197. @Override
  198. public Boolean save( String repositoryId, String groupId, String artifactId, String version, String packaging,
  199. boolean generatePom )
  200. throws ArchivaRestServiceException
  201. {
  202. repositoryId = StringUtils.trim( repositoryId );
  203. groupId = StringUtils.trim( groupId );
  204. artifactId = StringUtils.trim( artifactId );
  205. version = StringUtils.trim( version );
  206. packaging = StringUtils.trim( packaging );
  207. List<FileMetadata> fileMetadatas = getSessionFilesList();
  208. if ( fileMetadatas == null || fileMetadatas.isEmpty() )
  209. {
  210. return Boolean.FALSE;
  211. }
  212. try
  213. {
  214. ManagedRepository managedRepository = managedRepositoryAdmin.getManagedRepository( repositoryId );
  215. if ( managedRepository == null )
  216. {
  217. // TODO i18n ?
  218. throw new ArchivaRestServiceException( "Cannot find managed repository with id " + repositoryId,
  219. Response.Status.BAD_REQUEST.getStatusCode(), null );
  220. }
  221. if ( VersionUtil.isSnapshot( version ) && !managedRepository.isSnapshots() )
  222. {
  223. // TODO i18n ?
  224. throw new ArchivaRestServiceException(
  225. "Managed repository with id " + repositoryId + " do not accept snapshots",
  226. Response.Status.BAD_REQUEST.getStatusCode(), null );
  227. }
  228. }
  229. catch ( RepositoryAdminException e )
  230. {
  231. throw new ArchivaRestServiceException( e.getMessage(),
  232. Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e );
  233. }
  234. // get from the session file with groupId/artifactId
  235. Iterable<FileMetadata> filesToAdd = Iterables.filter( fileMetadatas, new Predicate<FileMetadata>()
  236. {
  237. public boolean apply( FileMetadata fileMetadata )
  238. {
  239. return fileMetadata != null && !fileMetadata.isPomFile();
  240. }
  241. } );
  242. Iterator<FileMetadata> iterator = filesToAdd.iterator();
  243. boolean pomGenerated = false;
  244. while ( iterator.hasNext() )
  245. {
  246. FileMetadata fileMetadata = iterator.next();
  247. log.debug( "fileToAdd: {}", fileMetadata );
  248. saveFile( repositoryId, fileMetadata, generatePom && !pomGenerated, groupId, artifactId, version,
  249. packaging );
  250. pomGenerated = true;
  251. deleteFile( fileMetadata.getServerFileName() );
  252. }
  253. filesToAdd = Iterables.filter( fileMetadatas, new Predicate<FileMetadata>()
  254. {
  255. @Override
  256. public boolean apply( FileMetadata fileMetadata )
  257. {
  258. return fileMetadata != null && fileMetadata.isPomFile();
  259. }
  260. } );
  261. iterator = filesToAdd.iterator();
  262. while ( iterator.hasNext() )
  263. {
  264. FileMetadata fileMetadata = iterator.next();
  265. log.debug( "fileToAdd: {}", fileMetadata );
  266. savePomFile( repositoryId, fileMetadata, groupId, artifactId, version, packaging );
  267. deleteFile( fileMetadata.getServerFileName() );
  268. }
  269. return Boolean.TRUE;
  270. }
  271. protected void savePomFile( String repositoryId, FileMetadata fileMetadata, String groupId, String artifactId,
  272. String version, String packaging )
  273. throws ArchivaRestServiceException
  274. {
  275. try
  276. {
  277. boolean fixChecksums =
  278. !( archivaAdministration.getKnownContentConsumers().contains( "create-missing-checksums" ) );
  279. ManagedRepository repoConfig = managedRepositoryAdmin.getManagedRepository( repositoryId );
  280. ArtifactReference artifactReference = new ArtifactReference();
  281. artifactReference.setArtifactId( artifactId );
  282. artifactReference.setGroupId( groupId );
  283. artifactReference.setVersion( version );
  284. artifactReference.setClassifier( fileMetadata.getClassifier() );
  285. artifactReference.setType( packaging );
  286. ManagedRepositoryContent repository = repositoryFactory.getManagedRepositoryContent( repositoryId );
  287. String artifactPath = repository.toPath( artifactReference );
  288. int lastIndex = artifactPath.lastIndexOf( '/' );
  289. String path = artifactPath.substring( 0, lastIndex );
  290. File targetPath = new File( repoConfig.getLocation(), path );
  291. String pomFilename = artifactPath.substring( lastIndex + 1 );
  292. if ( StringUtils.isNotEmpty( fileMetadata.getClassifier() ) )
  293. {
  294. pomFilename = StringUtils.remove( pomFilename, "-" + fileMetadata.getClassifier() );
  295. }
  296. pomFilename = FilenameUtils.removeExtension( pomFilename ) + ".pom";
  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(), ie );
  305. }
  306. catch ( RepositoryException rep )
  307. {
  308. throw new ArchivaRestServiceException( "Repository exception: " + rep.getMessage(),
  309. Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), rep );
  310. }
  311. catch ( RepositoryAdminException e )
  312. {
  313. throw new ArchivaRestServiceException( "RepositoryAdmin exception: " + e.getMessage(),
  314. Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e );
  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. ManagedRepository repoConfig = managedRepositoryAdmin.getManagedRepository( repositoryId );
  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(
  330. StringUtils.isEmpty( fileMetadata.getPackaging() ) ? packaging : fileMetadata.getPackaging() );
  331. ManagedRepositoryContent repository = repositoryFactory.getManagedRepositoryContent( repositoryId );
  332. String artifactPath = repository.toPath( artifactReference );
  333. int lastIndex = artifactPath.lastIndexOf( '/' );
  334. String path = artifactPath.substring( 0, lastIndex );
  335. File targetPath = new File( repoConfig.getLocation(), path );
  336. log.debug( "artifactPath: {} found targetPath: {}", artifactPath, targetPath );
  337. Date lastUpdatedTimestamp = Calendar.getInstance().getTime();
  338. int newBuildNumber = -1;
  339. String timestamp = null;
  340. File versionMetadataFile = new File( targetPath, MetadataTools.MAVEN_METADATA );
  341. ArchivaRepositoryMetadata versionMetadata = getMetadata( versionMetadataFile );
  342. if ( VersionUtil.isSnapshot( version ) )
  343. {
  344. TimeZone timezone = TimeZone.getTimeZone( "UTC" );
  345. DateFormat fmt = new SimpleDateFormat( "yyyyMMdd.HHmmss" );
  346. fmt.setTimeZone( timezone );
  347. timestamp = fmt.format( lastUpdatedTimestamp );
  348. if ( versionMetadata.getSnapshotVersion() != null )
  349. {
  350. newBuildNumber = versionMetadata.getSnapshotVersion().getBuildNumber() + 1;
  351. }
  352. else
  353. {
  354. newBuildNumber = 1;
  355. }
  356. }
  357. if ( !targetPath.exists() )
  358. {
  359. targetPath.mkdirs();
  360. }
  361. String filename = artifactPath.substring( lastIndex + 1 );
  362. if ( VersionUtil.isSnapshot( version ) )
  363. {
  364. filename = filename.replaceAll( VersionUtil.SNAPSHOT, timestamp + "-" + newBuildNumber );
  365. }
  366. boolean fixChecksums =
  367. !( archivaAdministration.getKnownContentConsumers().contains( "create-missing-checksums" ) );
  368. try
  369. {
  370. File targetFile = new File( targetPath, filename );
  371. if ( targetFile.exists() && !VersionUtil.isSnapshot( version ) && repoConfig.isBlockRedeployments() )
  372. {
  373. throw new ArchivaRestServiceException(
  374. "Overwriting released artifacts in repository '" + repoConfig.getId() + "' is not allowed.",
  375. Response.Status.BAD_REQUEST.getStatusCode(), null );
  376. }
  377. else
  378. {
  379. copyFile( new File( fileMetadata.getServerFileName() ), targetPath, filename, fixChecksums );
  380. triggerAuditEvent( repository.getId(), path + "/" + filename, AuditEvent.UPLOAD_FILE );
  381. queueRepositoryTask( repository.getId(), targetFile );
  382. }
  383. }
  384. catch ( IOException ie )
  385. {
  386. log.error( "IOException copying file: {}", ie.getMessage(), ie );
  387. throw new ArchivaRestServiceException(
  388. "Overwriting released artifacts in repository '" + repoConfig.getId() + "' is not allowed.",
  389. Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), ie );
  390. }
  391. if ( generatePom )
  392. {
  393. String pomFilename = filename;
  394. if ( StringUtils.isNotEmpty( fileMetadata.getClassifier() ) )
  395. {
  396. pomFilename = StringUtils.remove( pomFilename, "-" + fileMetadata.getClassifier() );
  397. }
  398. pomFilename = FilenameUtils.removeExtension( pomFilename ) + ".pom";
  399. try
  400. {
  401. File generatedPomFile =
  402. createPom( targetPath, pomFilename, fileMetadata, groupId, artifactId, version, packaging );
  403. triggerAuditEvent( repoConfig.getId(), path + "/" + pomFilename, AuditEvent.UPLOAD_FILE );
  404. if ( fixChecksums )
  405. {
  406. fixChecksums( generatedPomFile );
  407. }
  408. queueRepositoryTask( repoConfig.getId(), generatedPomFile );
  409. }
  410. catch ( IOException ie )
  411. {
  412. throw new ArchivaRestServiceException(
  413. "Error encountered while writing pom file: " + ie.getMessage(),
  414. Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), ie );
  415. }
  416. }
  417. // explicitly update only if metadata-updater consumer is not enabled!
  418. if ( !archivaAdministration.getKnownContentConsumers().contains( "metadata-updater" ) )
  419. {
  420. updateProjectMetadata( targetPath.getAbsolutePath(), lastUpdatedTimestamp, timestamp, newBuildNumber,
  421. fixChecksums, fileMetadata, groupId, artifactId, version, packaging );
  422. if ( VersionUtil.isSnapshot( version ) )
  423. {
  424. updateVersionMetadata( versionMetadata, versionMetadataFile, lastUpdatedTimestamp, timestamp,
  425. newBuildNumber, fixChecksums, fileMetadata, groupId, artifactId, version,
  426. packaging );
  427. }
  428. }
  429. }
  430. catch ( RepositoryNotFoundException re )
  431. {
  432. throw new ArchivaRestServiceException( "Target repository cannot be found: " + re.getMessage(),
  433. Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), re );
  434. }
  435. catch ( RepositoryException rep )
  436. {
  437. throw new ArchivaRestServiceException( "Repository exception: " + rep.getMessage(),
  438. Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), rep );
  439. }
  440. catch ( RepositoryAdminException e )
  441. {
  442. throw new ArchivaRestServiceException( "RepositoryAdmin exception: " + e.getMessage(),
  443. Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e );
  444. }
  445. }
  446. private ArchivaRepositoryMetadata getMetadata( File metadataFile )
  447. throws RepositoryMetadataException
  448. {
  449. ArchivaRepositoryMetadata metadata = new ArchivaRepositoryMetadata();
  450. if ( metadataFile.exists() )
  451. {
  452. try
  453. {
  454. metadata = MavenMetadataReader.read( metadataFile );
  455. }
  456. catch ( XMLException e )
  457. {
  458. throw new RepositoryMetadataException( e.getMessage(), e );
  459. }
  460. }
  461. return metadata;
  462. }
  463. private File createPom( File targetPath, String filename, FileMetadata fileMetadata, String groupId,
  464. String artifactId, String version, String packaging )
  465. throws IOException
  466. {
  467. Model projectModel = new Model();
  468. projectModel.setModelVersion( "4.0.0" );
  469. projectModel.setGroupId( groupId );
  470. projectModel.setArtifactId( artifactId );
  471. projectModel.setVersion( version );
  472. projectModel.setPackaging( packaging );
  473. File pomFile = new File( targetPath, filename );
  474. MavenXpp3Writer writer = new MavenXpp3Writer();
  475. try (FileWriter w = new FileWriter( pomFile ))
  476. {
  477. writer.write( w, projectModel );
  478. }
  479. return pomFile;
  480. }
  481. private void fixChecksums( File file )
  482. {
  483. ChecksummedFile checksum = new ChecksummedFile( file );
  484. checksum.fixChecksums( algorithms );
  485. }
  486. private void queueRepositoryTask( String repositoryId, File localFile )
  487. {
  488. RepositoryTask task = new RepositoryTask();
  489. task.setRepositoryId( repositoryId );
  490. task.setResourceFile( localFile );
  491. task.setUpdateRelatedArtifacts( true );
  492. task.setScanAll( false );
  493. try
  494. {
  495. scheduler.queueTask( task );
  496. }
  497. catch ( TaskQueueException e )
  498. {
  499. log.error( "Unable to queue repository task to execute consumers on resource file ['" + localFile.getName()
  500. + "']." );
  501. }
  502. }
  503. private void copyFile( File sourceFile, File targetPath, String targetFilename, boolean fixChecksums )
  504. throws IOException
  505. {
  506. Files.copy( sourceFile.toPath(), new File( targetPath, targetFilename ).toPath(), StandardCopyOption.REPLACE_EXISTING,
  507. StandardCopyOption.COPY_ATTRIBUTES );
  508. if ( fixChecksums )
  509. {
  510. fixChecksums( new File( targetPath, targetFilename ) );
  511. }
  512. }
  513. /**
  514. * Update artifact level metadata. If it does not exist, create the metadata and fix checksums if necessary.
  515. */
  516. private void updateProjectMetadata( String targetPath, Date lastUpdatedTimestamp, String timestamp, int buildNumber,
  517. boolean fixChecksums, FileMetadata fileMetadata, String groupId,
  518. String artifactId, String version, String packaging )
  519. throws RepositoryMetadataException
  520. {
  521. List<String> availableVersions = new ArrayList<>();
  522. String latestVersion = version;
  523. File projectDir = new File( targetPath ).getParentFile();
  524. File projectMetadataFile = new File( projectDir, MetadataTools.MAVEN_METADATA );
  525. ArchivaRepositoryMetadata projectMetadata = getMetadata( projectMetadataFile );
  526. if ( projectMetadataFile.exists() )
  527. {
  528. availableVersions = projectMetadata.getAvailableVersions();
  529. Collections.sort( availableVersions, VersionComparator.getInstance() );
  530. if ( !availableVersions.contains( version ) )
  531. {
  532. availableVersions.add( version );
  533. }
  534. latestVersion = availableVersions.get( availableVersions.size() - 1 );
  535. }
  536. else
  537. {
  538. availableVersions.add( version );
  539. projectMetadata.setGroupId( groupId );
  540. projectMetadata.setArtifactId( artifactId );
  541. }
  542. if ( projectMetadata.getGroupId() == null )
  543. {
  544. projectMetadata.setGroupId( groupId );
  545. }
  546. if ( projectMetadata.getArtifactId() == null )
  547. {
  548. projectMetadata.setArtifactId( artifactId );
  549. }
  550. projectMetadata.setLatestVersion( latestVersion );
  551. projectMetadata.setLastUpdatedTimestamp( lastUpdatedTimestamp );
  552. projectMetadata.setAvailableVersions( availableVersions );
  553. if ( !VersionUtil.isSnapshot( version ) )
  554. {
  555. projectMetadata.setReleasedVersion( latestVersion );
  556. }
  557. RepositoryMetadataWriter.write( projectMetadata, projectMetadataFile );
  558. if ( fixChecksums )
  559. {
  560. fixChecksums( projectMetadataFile );
  561. }
  562. }
  563. /**
  564. * Update version level metadata for snapshot artifacts. If it does not exist, create the metadata and fix checksums
  565. * if necessary.
  566. */
  567. private void updateVersionMetadata( ArchivaRepositoryMetadata metadata, File metadataFile,
  568. Date lastUpdatedTimestamp, String timestamp, int buildNumber,
  569. boolean fixChecksums, FileMetadata fileMetadata, String groupId,
  570. String artifactId, String version, String packaging )
  571. throws RepositoryMetadataException
  572. {
  573. if ( !metadataFile.exists() )
  574. {
  575. metadata.setGroupId( groupId );
  576. metadata.setArtifactId( artifactId );
  577. metadata.setVersion( version );
  578. }
  579. if ( metadata.getSnapshotVersion() == null )
  580. {
  581. metadata.setSnapshotVersion( new SnapshotVersion() );
  582. }
  583. metadata.getSnapshotVersion().setBuildNumber( buildNumber );
  584. metadata.getSnapshotVersion().setTimestamp( timestamp );
  585. metadata.setLastUpdatedTimestamp( lastUpdatedTimestamp );
  586. RepositoryMetadataWriter.write( metadata, metadataFile );
  587. if ( fixChecksums )
  588. {
  589. fixChecksums( metadataFile );
  590. }
  591. }
  592. }