Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

DefaultRepositoriesService.java 47KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239
  1. package org.apache.archiva.rest.services;
  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 org.apache.archiva.admin.model.RepositoryAdminException;
  21. import org.apache.archiva.admin.model.admin.ArchivaAdministration;
  22. import org.apache.archiva.admin.model.beans.ManagedRepository;
  23. import org.apache.archiva.admin.model.managed.ManagedRepositoryAdmin;
  24. import org.apache.archiva.metadata.model.facets.AuditEvent;
  25. import org.apache.archiva.checksum.ChecksumAlgorithm;
  26. import org.apache.archiva.checksum.ChecksummedFile;
  27. import org.apache.archiva.common.plexusbridge.MavenIndexerUtils;
  28. import org.apache.archiva.common.plexusbridge.PlexusSisuBridge;
  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.maven2.model.Artifact;
  33. import org.apache.archiva.metadata.model.ArtifactMetadata;
  34. import org.apache.archiva.metadata.model.maven2.MavenArtifactFacet;
  35. import org.apache.archiva.metadata.repository.MetadataRepository;
  36. import org.apache.archiva.metadata.repository.MetadataRepositoryException;
  37. import org.apache.archiva.metadata.repository.MetadataResolutionException;
  38. import org.apache.archiva.metadata.repository.RepositorySession;
  39. import org.apache.archiva.metadata.repository.RepositorySessionFactory;
  40. import org.apache.archiva.model.ArchivaRepositoryMetadata;
  41. import org.apache.archiva.model.ArtifactReference;
  42. import org.apache.archiva.model.VersionedReference;
  43. import org.apache.archiva.redback.authentication.AuthenticationResult;
  44. import org.apache.archiva.redback.authorization.AuthorizationException;
  45. import org.apache.archiva.redback.components.cache.Cache;
  46. import org.apache.archiva.redback.components.taskqueue.TaskQueueException;
  47. import org.apache.archiva.redback.system.DefaultSecuritySession;
  48. import org.apache.archiva.redback.system.SecuritySession;
  49. import org.apache.archiva.redback.system.SecuritySystem;
  50. import org.apache.archiva.redback.users.User;
  51. import org.apache.archiva.redback.users.UserManagerException;
  52. import org.apache.archiva.redback.users.UserNotFoundException;
  53. import org.apache.archiva.repository.ContentNotFoundException;
  54. import org.apache.archiva.repository.ManagedRepositoryContent;
  55. import org.apache.archiva.repository.RepositoryContentFactory;
  56. import org.apache.archiva.repository.RepositoryException;
  57. import org.apache.archiva.repository.RepositoryNotFoundException;
  58. import org.apache.archiva.repository.events.RepositoryListener;
  59. import org.apache.archiva.repository.metadata.MetadataTools;
  60. import org.apache.archiva.repository.metadata.RepositoryMetadataException;
  61. import org.apache.archiva.repository.metadata.RepositoryMetadataWriter;
  62. import org.apache.archiva.repository.scanner.RepositoryScanStatistics;
  63. import org.apache.archiva.repository.scanner.RepositoryScanner;
  64. import org.apache.archiva.repository.scanner.RepositoryScannerException;
  65. import org.apache.archiva.rest.api.model.ArtifactTransferRequest;
  66. import org.apache.archiva.rest.api.model.StringList;
  67. import org.apache.archiva.rest.api.services.ArchivaRestServiceException;
  68. import org.apache.archiva.rest.api.services.RepositoriesService;
  69. import org.apache.archiva.scheduler.ArchivaTaskScheduler;
  70. import org.apache.archiva.scheduler.indexing.ArchivaIndexingTaskExecutor;
  71. import org.apache.archiva.scheduler.indexing.ArtifactIndexingTask;
  72. import org.apache.archiva.scheduler.indexing.DownloadRemoteIndexException;
  73. import org.apache.archiva.scheduler.indexing.DownloadRemoteIndexScheduler;
  74. import org.apache.archiva.scheduler.repository.model.RepositoryTask;
  75. import org.apache.archiva.security.ArchivaSecurityException;
  76. import org.apache.archiva.security.common.ArchivaRoleConstants;
  77. import org.apache.archiva.xml.XMLException;
  78. import org.apache.commons.io.FilenameUtils;
  79. import org.apache.commons.lang.StringUtils;
  80. import org.apache.maven.index.context.IndexingContext;
  81. import org.slf4j.Logger;
  82. import org.slf4j.LoggerFactory;
  83. import org.springframework.beans.factory.annotation.Autowired;
  84. import org.springframework.stereotype.Service;
  85. import javax.inject.Inject;
  86. import javax.inject.Named;
  87. import javax.ws.rs.core.Response;
  88. import java.io.File;
  89. import java.io.IOException;
  90. import java.nio.file.Files;
  91. import java.nio.file.StandardCopyOption;
  92. import java.text.DateFormat;
  93. import java.text.SimpleDateFormat;
  94. import java.util.ArrayList;
  95. import java.util.Calendar;
  96. import java.util.Collection;
  97. import java.util.Collections;
  98. import java.util.Date;
  99. import java.util.List;
  100. import java.util.Set;
  101. import java.util.TimeZone;
  102. /**
  103. * @author Olivier Lamy
  104. * @since 1.4-M1
  105. */
  106. @Service("repositoriesService#rest")
  107. public class DefaultRepositoriesService
  108. extends AbstractRestService
  109. implements RepositoriesService
  110. {
  111. private Logger log = LoggerFactory.getLogger( getClass() );
  112. @Inject
  113. @Named(value = "taskExecutor#indexing")
  114. private ArchivaIndexingTaskExecutor archivaIndexingTaskExecutor;
  115. @Inject
  116. private ManagedRepositoryAdmin managedRepositoryAdmin;
  117. @Inject
  118. private PlexusSisuBridge plexusSisuBridge;
  119. @Inject
  120. private MavenIndexerUtils mavenIndexerUtils;
  121. @Inject
  122. private SecuritySystem securitySystem;
  123. @Inject
  124. private RepositoryContentFactory repositoryFactory;
  125. @Inject
  126. @Named(value = "archivaTaskScheduler#repository")
  127. private ArchivaTaskScheduler scheduler;
  128. @Inject
  129. private DownloadRemoteIndexScheduler downloadRemoteIndexScheduler;
  130. @Inject
  131. @Named(value = "repositorySessionFactory")
  132. protected RepositorySessionFactory repositorySessionFactory;
  133. @Inject
  134. @Autowired(required = false)
  135. protected List<RepositoryListener> listeners = new ArrayList<RepositoryListener>();
  136. @Inject
  137. private RepositoryScanner repoScanner;
  138. /**
  139. * Cache used for namespaces
  140. */
  141. @Inject
  142. @Named(value = "cache#namespaces")
  143. private Cache<String, Collection<String>> namespacesCache;
  144. private ChecksumAlgorithm[] algorithms = new ChecksumAlgorithm[]{ ChecksumAlgorithm.SHA1, ChecksumAlgorithm.MD5 };
  145. @Override
  146. public Boolean scanRepository( String repositoryId, boolean fullScan )
  147. {
  148. return doScanRepository( repositoryId, fullScan );
  149. }
  150. @Override
  151. public Boolean alreadyScanning( String repositoryId )
  152. {
  153. return repositoryTaskScheduler.isProcessingRepositoryTask( repositoryId );
  154. }
  155. @Override
  156. public Boolean removeScanningTaskFromQueue( String repositoryId )
  157. {
  158. RepositoryTask task = new RepositoryTask();
  159. task.setRepositoryId( repositoryId );
  160. try
  161. {
  162. return repositoryTaskScheduler.unQueueTask( task );
  163. }
  164. catch ( TaskQueueException e )
  165. {
  166. log.error( "failed to unschedule scanning of repo with id {}", repositoryId, e );
  167. return false;
  168. }
  169. }
  170. @Override
  171. public Boolean scanRepositoryNow( String repositoryId, boolean fullScan )
  172. throws ArchivaRestServiceException
  173. {
  174. try
  175. {
  176. ManagedRepository repository = managedRepositoryAdmin.getManagedRepository( repositoryId );
  177. IndexingContext context = managedRepositoryAdmin.createIndexContext( repository );
  178. ArtifactIndexingTask task =
  179. new ArtifactIndexingTask( repository, null, ArtifactIndexingTask.Action.FINISH, context );
  180. task.setExecuteOnEntireRepo( true );
  181. task.setOnlyUpdate( !fullScan );
  182. archivaIndexingTaskExecutor.executeTask( task );
  183. return Boolean.TRUE;
  184. }
  185. catch ( Exception e )
  186. {
  187. log.error( e.getMessage(), e );
  188. throw new ArchivaRestServiceException( e.getMessage(), e );
  189. }
  190. }
  191. @Override
  192. public Boolean scheduleDownloadRemoteIndex( String repositoryId, boolean now, boolean fullDownload )
  193. throws ArchivaRestServiceException
  194. {
  195. try
  196. {
  197. downloadRemoteIndexScheduler.scheduleDownloadRemote( repositoryId, now, fullDownload );
  198. }
  199. catch ( DownloadRemoteIndexException e )
  200. {
  201. log.error( e.getMessage(), e );
  202. throw new ArchivaRestServiceException( e.getMessage(), e );
  203. }
  204. return Boolean.TRUE;
  205. }
  206. @Override
  207. public Boolean copyArtifact( ArtifactTransferRequest artifactTransferRequest )
  208. throws ArchivaRestServiceException
  209. {
  210. // check parameters
  211. String userName = getAuditInformation().getUser().getUsername();
  212. if ( StringUtils.isBlank( userName ) )
  213. {
  214. throw new ArchivaRestServiceException( "copyArtifact call: userName not found", null );
  215. }
  216. if ( StringUtils.isBlank( artifactTransferRequest.getRepositoryId() ) )
  217. {
  218. throw new ArchivaRestServiceException( "copyArtifact call: sourceRepositoryId cannot be null", null );
  219. }
  220. if ( StringUtils.isBlank( artifactTransferRequest.getTargetRepositoryId() ) )
  221. {
  222. throw new ArchivaRestServiceException( "copyArtifact call: targetRepositoryId cannot be null", null );
  223. }
  224. ManagedRepository source = null;
  225. try
  226. {
  227. source = managedRepositoryAdmin.getManagedRepository( artifactTransferRequest.getRepositoryId() );
  228. }
  229. catch ( RepositoryAdminException e )
  230. {
  231. throw new ArchivaRestServiceException( e.getMessage(), e );
  232. }
  233. if ( source == null )
  234. {
  235. throw new ArchivaRestServiceException(
  236. "cannot find repository with id " + artifactTransferRequest.getRepositoryId(), null );
  237. }
  238. ManagedRepository target = null;
  239. try
  240. {
  241. target = managedRepositoryAdmin.getManagedRepository( artifactTransferRequest.getTargetRepositoryId() );
  242. }
  243. catch ( RepositoryAdminException e )
  244. {
  245. throw new ArchivaRestServiceException( e.getMessage(), e );
  246. }
  247. if ( target == null )
  248. {
  249. throw new ArchivaRestServiceException(
  250. "cannot find repository with id " + artifactTransferRequest.getTargetRepositoryId(), null );
  251. }
  252. if ( StringUtils.isBlank( artifactTransferRequest.getGroupId() ) )
  253. {
  254. throw new ArchivaRestServiceException( "groupId is mandatory", null );
  255. }
  256. if ( StringUtils.isBlank( artifactTransferRequest.getArtifactId() ) )
  257. {
  258. throw new ArchivaRestServiceException( "artifactId is mandatory", null );
  259. }
  260. if ( StringUtils.isBlank( artifactTransferRequest.getVersion() ) )
  261. {
  262. throw new ArchivaRestServiceException( "version is mandatory", null );
  263. }
  264. if ( VersionUtil.isSnapshot( artifactTransferRequest.getVersion() ) )
  265. {
  266. throw new ArchivaRestServiceException( "copy of SNAPSHOT not supported", null );
  267. }
  268. // end check parameters
  269. User user = null;
  270. try
  271. {
  272. user = securitySystem.getUserManager().findUser( userName );
  273. }
  274. catch ( UserNotFoundException e )
  275. {
  276. throw new ArchivaRestServiceException( "user " + userName + " not found", e );
  277. }
  278. catch ( UserManagerException e )
  279. {
  280. throw new ArchivaRestServiceException( "ArchivaRestServiceException:" + e.getMessage(), e );
  281. }
  282. // check karma on source : read
  283. AuthenticationResult authn = new AuthenticationResult( true, userName, null );
  284. SecuritySession securitySession = new DefaultSecuritySession( authn, user );
  285. try
  286. {
  287. boolean authz =
  288. securitySystem.isAuthorized( securitySession, ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS,
  289. artifactTransferRequest.getRepositoryId() );
  290. if ( !authz )
  291. {
  292. throw new ArchivaRestServiceException(
  293. "not authorized to access repo:" + artifactTransferRequest.getRepositoryId(), null );
  294. }
  295. }
  296. catch ( AuthorizationException e )
  297. {
  298. log.error( "error reading permission: " + e.getMessage(), e );
  299. throw new ArchivaRestServiceException( e.getMessage(), e );
  300. }
  301. // check karma on target: write
  302. try
  303. {
  304. boolean authz =
  305. securitySystem.isAuthorized( securitySession, ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD,
  306. artifactTransferRequest.getTargetRepositoryId() );
  307. if ( !authz )
  308. {
  309. throw new ArchivaRestServiceException(
  310. "not authorized to write to repo:" + artifactTransferRequest.getTargetRepositoryId(), null );
  311. }
  312. }
  313. catch ( AuthorizationException e )
  314. {
  315. log.error( "error reading permission: " + e.getMessage(), e );
  316. throw new ArchivaRestServiceException( e.getMessage(), e );
  317. }
  318. // sounds good we can continue !
  319. ArtifactReference artifactReference = new ArtifactReference();
  320. artifactReference.setArtifactId( artifactTransferRequest.getArtifactId() );
  321. artifactReference.setGroupId( artifactTransferRequest.getGroupId() );
  322. artifactReference.setVersion( artifactTransferRequest.getVersion() );
  323. artifactReference.setClassifier( artifactTransferRequest.getClassifier() );
  324. String packaging = StringUtils.trim( artifactTransferRequest.getPackaging() );
  325. artifactReference.setType( StringUtils.isEmpty( packaging ) ? "jar" : packaging );
  326. try
  327. {
  328. ManagedRepositoryContent sourceRepository =
  329. repositoryFactory.getManagedRepositoryContent( artifactTransferRequest.getRepositoryId() );
  330. String artifactSourcePath = sourceRepository.toPath( artifactReference );
  331. if ( StringUtils.isEmpty( artifactSourcePath ) )
  332. {
  333. log.error( "cannot find artifact " + artifactTransferRequest.toString() );
  334. throw new ArchivaRestServiceException( "cannot find artifact " + artifactTransferRequest.toString(),
  335. null );
  336. }
  337. File artifactFile = new File( source.getLocation(), artifactSourcePath );
  338. if ( !artifactFile.exists() )
  339. {
  340. log.error( "cannot find artifact " + artifactTransferRequest.toString() );
  341. throw new ArchivaRestServiceException( "cannot find artifact " + artifactTransferRequest.toString(),
  342. null );
  343. }
  344. ManagedRepositoryContent targetRepository =
  345. repositoryFactory.getManagedRepositoryContent( artifactTransferRequest.getTargetRepositoryId() );
  346. String artifactPath = targetRepository.toPath( artifactReference );
  347. int lastIndex = artifactPath.lastIndexOf( '/' );
  348. String path = artifactPath.substring( 0, lastIndex );
  349. File targetPath = new File( target.getLocation(), path );
  350. Date lastUpdatedTimestamp = Calendar.getInstance().getTime();
  351. int newBuildNumber = 1;
  352. String timestamp = null;
  353. File versionMetadataFile = new File( targetPath, MetadataTools.MAVEN_METADATA );
  354. ArchivaRepositoryMetadata versionMetadata = getMetadata( versionMetadataFile );
  355. if ( !targetPath.exists() )
  356. {
  357. targetPath.mkdirs();
  358. }
  359. String filename = artifactPath.substring( lastIndex + 1 );
  360. boolean fixChecksums =
  361. !( archivaAdministration.getKnownContentConsumers().contains( "create-missing-checksums" ) );
  362. File targetFile = new File( targetPath, filename );
  363. if ( targetFile.exists() && target.isBlockRedeployments() )
  364. {
  365. throw new ArchivaRestServiceException(
  366. "artifact already exists in target repo: " + artifactTransferRequest.getTargetRepositoryId()
  367. + " and redeployment blocked", null
  368. );
  369. }
  370. else
  371. {
  372. copyFile( artifactFile, targetPath, filename, fixChecksums );
  373. queueRepositoryTask( target.getId(), targetFile );
  374. }
  375. // copy source pom to target repo
  376. String pomFilename = filename;
  377. if ( StringUtils.isNotBlank( artifactTransferRequest.getClassifier() ) )
  378. {
  379. pomFilename = StringUtils.remove( pomFilename, "-" + artifactTransferRequest.getClassifier() );
  380. }
  381. pomFilename = FilenameUtils.removeExtension( pomFilename ) + ".pom";
  382. File pomFile = new File(
  383. new File( source.getLocation(), artifactSourcePath.substring( 0, artifactPath.lastIndexOf( '/' ) ) ),
  384. pomFilename );
  385. if ( pomFile != null && pomFile.length() > 0 )
  386. {
  387. copyFile( pomFile, targetPath, pomFilename, fixChecksums );
  388. queueRepositoryTask( target.getId(), new File( targetPath, pomFilename ) );
  389. }
  390. // explicitly update only if metadata-updater consumer is not enabled!
  391. if ( !archivaAdministration.getKnownContentConsumers().contains( "metadata-updater" ) )
  392. {
  393. updateProjectMetadata( targetPath.getAbsolutePath(), lastUpdatedTimestamp, timestamp, newBuildNumber,
  394. fixChecksums, artifactTransferRequest );
  395. }
  396. String msg =
  397. "Artifact \'" + artifactTransferRequest.getGroupId() + ":" + artifactTransferRequest.getArtifactId()
  398. + ":" + artifactTransferRequest.getVersion() + "\' was successfully deployed to repository \'"
  399. + artifactTransferRequest.getTargetRepositoryId() + "\'";
  400. }
  401. catch ( RepositoryException e )
  402. {
  403. log.error( "RepositoryException: " + e.getMessage(), e );
  404. throw new ArchivaRestServiceException( e.getMessage(), e );
  405. }
  406. catch ( RepositoryAdminException e )
  407. {
  408. log.error( "RepositoryAdminException: " + e.getMessage(), e );
  409. throw new ArchivaRestServiceException( e.getMessage(), e );
  410. }
  411. catch ( IOException e )
  412. {
  413. log.error( "IOException: " + e.getMessage(), e );
  414. throw new ArchivaRestServiceException( e.getMessage(), e );
  415. }
  416. return true;
  417. }
  418. private void queueRepositoryTask( String repositoryId, File localFile )
  419. {
  420. RepositoryTask task = new RepositoryTask();
  421. task.setRepositoryId( repositoryId );
  422. task.setResourceFile( localFile );
  423. task.setUpdateRelatedArtifacts( true );
  424. //task.setScanAll( true );
  425. try
  426. {
  427. scheduler.queueTask( task );
  428. }
  429. catch ( TaskQueueException e )
  430. {
  431. log.error( "Unable to queue repository task to execute consumers on resource file ['" + localFile.getName()
  432. + "']." );
  433. }
  434. }
  435. private ArchivaRepositoryMetadata getMetadata( File metadataFile )
  436. throws RepositoryMetadataException
  437. {
  438. ArchivaRepositoryMetadata metadata = new ArchivaRepositoryMetadata();
  439. if ( metadataFile.exists() )
  440. {
  441. try
  442. {
  443. metadata = MavenMetadataReader.read( metadataFile );
  444. }
  445. catch ( XMLException e )
  446. {
  447. throw new RepositoryMetadataException( e.getMessage(), e );
  448. }
  449. }
  450. return metadata;
  451. }
  452. private File getMetadata( String targetPath )
  453. {
  454. String artifactPath = targetPath.substring( 0, targetPath.lastIndexOf( File.separatorChar ) );
  455. return new File( artifactPath, MetadataTools.MAVEN_METADATA );
  456. }
  457. private void copyFile( File sourceFile, File targetPath, String targetFilename, boolean fixChecksums )
  458. throws IOException
  459. {
  460. Files.copy( sourceFile.toPath(), new File( targetPath, targetFilename ).toPath(), StandardCopyOption.REPLACE_EXISTING,
  461. StandardCopyOption.COPY_ATTRIBUTES );
  462. if ( fixChecksums )
  463. {
  464. fixChecksums( new File( targetPath, targetFilename ) );
  465. }
  466. }
  467. private void fixChecksums( File file )
  468. {
  469. ChecksummedFile checksum = new ChecksummedFile( file );
  470. checksum.fixChecksums( algorithms );
  471. }
  472. private void updateProjectMetadata( String targetPath, Date lastUpdatedTimestamp, String timestamp, int buildNumber,
  473. boolean fixChecksums, ArtifactTransferRequest artifactTransferRequest )
  474. throws RepositoryMetadataException
  475. {
  476. List<String> availableVersions = new ArrayList<>();
  477. String latestVersion = artifactTransferRequest.getVersion();
  478. File projectDir = new File( targetPath ).getParentFile();
  479. File projectMetadataFile = new File( projectDir, MetadataTools.MAVEN_METADATA );
  480. ArchivaRepositoryMetadata projectMetadata = getMetadata( projectMetadataFile );
  481. if ( projectMetadataFile.exists() )
  482. {
  483. availableVersions = projectMetadata.getAvailableVersions();
  484. Collections.sort( availableVersions, VersionComparator.getInstance() );
  485. if ( !availableVersions.contains( artifactTransferRequest.getVersion() ) )
  486. {
  487. availableVersions.add( artifactTransferRequest.getVersion() );
  488. }
  489. latestVersion = availableVersions.get( availableVersions.size() - 1 );
  490. }
  491. else
  492. {
  493. availableVersions.add( artifactTransferRequest.getVersion() );
  494. projectMetadata.setGroupId( artifactTransferRequest.getGroupId() );
  495. projectMetadata.setArtifactId( artifactTransferRequest.getArtifactId() );
  496. }
  497. if ( projectMetadata.getGroupId() == null )
  498. {
  499. projectMetadata.setGroupId( artifactTransferRequest.getGroupId() );
  500. }
  501. if ( projectMetadata.getArtifactId() == null )
  502. {
  503. projectMetadata.setArtifactId( artifactTransferRequest.getArtifactId() );
  504. }
  505. projectMetadata.setLatestVersion( latestVersion );
  506. projectMetadata.setLastUpdatedTimestamp( lastUpdatedTimestamp );
  507. projectMetadata.setAvailableVersions( availableVersions );
  508. if ( !VersionUtil.isSnapshot( artifactTransferRequest.getVersion() ) )
  509. {
  510. projectMetadata.setReleasedVersion( latestVersion );
  511. }
  512. RepositoryMetadataWriter.write( projectMetadata, projectMetadataFile );
  513. if ( fixChecksums )
  514. {
  515. fixChecksums( projectMetadataFile );
  516. }
  517. }
  518. @Override
  519. public Boolean removeProjectVersion( String repositoryId, String namespace, String projectId, String version )
  520. throws ArchivaRestServiceException
  521. {
  522. // if not a generic we can use the standard way to delete artifact
  523. if ( !VersionUtil.isGenericSnapshot( version ) )
  524. {
  525. Artifact artifact = new Artifact( namespace, projectId, version );
  526. artifact.setRepositoryId( repositoryId );
  527. artifact.setContext( repositoryId );
  528. return deleteArtifact( artifact );
  529. }
  530. if ( StringUtils.isEmpty( repositoryId ) )
  531. {
  532. throw new ArchivaRestServiceException( "repositoryId cannot be null", 400, null );
  533. }
  534. if ( !isAuthorizedToDeleteArtifacts( repositoryId ) )
  535. {
  536. throw new ArchivaRestServiceException( "not authorized to delete artifacts", 403, null );
  537. }
  538. if ( StringUtils.isEmpty( namespace ) )
  539. {
  540. throw new ArchivaRestServiceException( "groupId cannot be null", 400, null );
  541. }
  542. if ( StringUtils.isEmpty( projectId ) )
  543. {
  544. throw new ArchivaRestServiceException( "artifactId cannot be null", 400, null );
  545. }
  546. if ( StringUtils.isEmpty( version ) )
  547. {
  548. throw new ArchivaRestServiceException( "version cannot be null", 400, null );
  549. }
  550. RepositorySession repositorySession = repositorySessionFactory.createSession();
  551. try
  552. {
  553. ManagedRepositoryContent repository = repositoryFactory.getManagedRepositoryContent( repositoryId );
  554. VersionedReference ref = new VersionedReference();
  555. ref.setArtifactId( projectId );
  556. ref.setGroupId( namespace );
  557. ref.setVersion( version );
  558. repository.deleteVersion( ref );
  559. /*
  560. ProjectReference projectReference = new ProjectReference();
  561. projectReference.setGroupId( namespace );
  562. projectReference.setArtifactId( projectId );
  563. repository.getVersions( )
  564. */
  565. ArtifactReference artifactReference = new ArtifactReference();
  566. artifactReference.setGroupId( namespace );
  567. artifactReference.setArtifactId( projectId );
  568. artifactReference.setVersion( version );
  569. MetadataRepository metadataRepository = repositorySession.getRepository();
  570. Set<ArtifactReference> related = repository.getRelatedArtifacts( artifactReference );
  571. log.debug( "related: {}", related );
  572. for ( ArtifactReference artifactRef : related )
  573. {
  574. repository.deleteArtifact( artifactRef );
  575. }
  576. Collection<ArtifactMetadata> artifacts =
  577. metadataRepository.getArtifacts( repositoryId, namespace, projectId, version );
  578. for ( ArtifactMetadata artifactMetadata : artifacts )
  579. {
  580. metadataRepository.removeArtifact( artifactMetadata, version );
  581. }
  582. metadataRepository.removeProjectVersion( repositoryId, namespace, projectId, version );
  583. }
  584. catch ( MetadataRepositoryException e )
  585. {
  586. throw new ArchivaRestServiceException( "Repository exception: " + e.getMessage(), 500, e );
  587. }
  588. catch ( MetadataResolutionException e )
  589. {
  590. throw new ArchivaRestServiceException( "Repository exception: " + e.getMessage(), 500, e );
  591. }
  592. catch ( RepositoryException e )
  593. {
  594. throw new ArchivaRestServiceException( "Repository exception: " + e.getMessage(), 500, e );
  595. }
  596. finally
  597. {
  598. repositorySession.save();
  599. repositorySession.close();
  600. }
  601. return Boolean.TRUE;
  602. }
  603. @Override
  604. public Boolean deleteArtifact( Artifact artifact )
  605. throws ArchivaRestServiceException
  606. {
  607. String repositoryId = artifact.getContext();
  608. // some rest call can use context or repositoryId
  609. // so try both!!
  610. if ( StringUtils.isEmpty( repositoryId ) )
  611. {
  612. repositoryId = artifact.getRepositoryId();
  613. }
  614. if ( StringUtils.isEmpty( repositoryId ) )
  615. {
  616. throw new ArchivaRestServiceException( "repositoryId cannot be null", 400, null );
  617. }
  618. if ( !isAuthorizedToDeleteArtifacts( repositoryId ) )
  619. {
  620. throw new ArchivaRestServiceException( "not authorized to delete artifacts", 403, null );
  621. }
  622. if ( artifact == null )
  623. {
  624. throw new ArchivaRestServiceException( "artifact cannot be null", 400, null );
  625. }
  626. if ( StringUtils.isEmpty( artifact.getGroupId() ) )
  627. {
  628. throw new ArchivaRestServiceException( "artifact.groupId cannot be null", 400, null );
  629. }
  630. if ( StringUtils.isEmpty( artifact.getArtifactId() ) )
  631. {
  632. throw new ArchivaRestServiceException( "artifact.artifactId cannot be null", 400, null );
  633. }
  634. // TODO more control on artifact fields
  635. boolean snapshotVersion =
  636. VersionUtil.isSnapshot( artifact.getVersion() ) | VersionUtil.isGenericSnapshot( artifact.getVersion() );
  637. RepositorySession repositorySession = repositorySessionFactory.createSession();
  638. try
  639. {
  640. Date lastUpdatedTimestamp = Calendar.getInstance().getTime();
  641. TimeZone timezone = TimeZone.getTimeZone( "UTC" );
  642. DateFormat fmt = new SimpleDateFormat( "yyyyMMdd.HHmmss" );
  643. fmt.setTimeZone( timezone );
  644. ManagedRepository repoConfig = managedRepositoryAdmin.getManagedRepository( repositoryId );
  645. VersionedReference ref = new VersionedReference();
  646. ref.setArtifactId( artifact.getArtifactId() );
  647. ref.setGroupId( artifact.getGroupId() );
  648. ref.setVersion( artifact.getVersion() );
  649. ManagedRepositoryContent repository = repositoryFactory.getManagedRepositoryContent( repositoryId );
  650. ArtifactReference artifactReference = new ArtifactReference();
  651. artifactReference.setArtifactId( artifact.getArtifactId() );
  652. artifactReference.setGroupId( artifact.getGroupId() );
  653. artifactReference.setVersion( artifact.getVersion() );
  654. artifactReference.setClassifier( artifact.getClassifier() );
  655. artifactReference.setType( artifact.getPackaging() );
  656. MetadataRepository metadataRepository = repositorySession.getRepository();
  657. String path = repository.toMetadataPath( ref );
  658. if ( StringUtils.isNotBlank( artifact.getClassifier() ) )
  659. {
  660. if ( StringUtils.isBlank( artifact.getPackaging() ) )
  661. {
  662. throw new ArchivaRestServiceException( "You must configure a type/packaging when using classifier",
  663. 400, null );
  664. }
  665. repository.deleteArtifact( artifactReference );
  666. }
  667. else
  668. {
  669. int index = path.lastIndexOf( '/' );
  670. path = path.substring( 0, index );
  671. File targetPath = new File( repoConfig.getLocation(), path );
  672. if ( !targetPath.exists() )
  673. {
  674. //throw new ContentNotFoundException(
  675. // artifact.getGroupId() + ":" + artifact.getArtifactId() + ":" + artifact.getVersion() );
  676. log.warn( "targetPath {} not found skip file deletion", targetPath );
  677. }
  678. // TODO: this should be in the storage mechanism so that it is all tied together
  679. // delete from file system
  680. if ( !snapshotVersion )
  681. {
  682. repository.deleteVersion( ref );
  683. }
  684. else
  685. {
  686. Set<ArtifactReference> related = repository.getRelatedArtifacts( artifactReference );
  687. log.debug( "related: {}", related );
  688. for ( ArtifactReference artifactRef : related )
  689. {
  690. repository.deleteArtifact( artifactRef );
  691. }
  692. }
  693. File metadataFile = getMetadata( targetPath.getAbsolutePath() );
  694. ArchivaRepositoryMetadata metadata = getMetadata( metadataFile );
  695. updateMetadata( metadata, metadataFile, lastUpdatedTimestamp, artifact );
  696. }
  697. Collection<ArtifactMetadata> artifacts = Collections.emptyList();
  698. if ( snapshotVersion )
  699. {
  700. String baseVersion = VersionUtil.getBaseVersion( artifact.getVersion() );
  701. artifacts =
  702. metadataRepository.getArtifacts( repositoryId, artifact.getGroupId(), artifact.getArtifactId(),
  703. baseVersion );
  704. }
  705. else
  706. {
  707. artifacts =
  708. metadataRepository.getArtifacts( repositoryId, artifact.getGroupId(), artifact.getArtifactId(),
  709. artifact.getVersion() );
  710. }
  711. log.debug( "artifacts: {}", artifacts );
  712. if ( artifacts.isEmpty() )
  713. {
  714. if ( !snapshotVersion )
  715. {
  716. // verify metata repository doesn't contains anymore the version
  717. Collection<String> projectVersions =
  718. metadataRepository.getProjectVersions( repositoryId, artifact.getGroupId(),
  719. artifact.getArtifactId() );
  720. if ( projectVersions.contains( artifact.getVersion() ) )
  721. {
  722. log.warn( "artifact not found when deleted but version still here ! so force cleanup" );
  723. metadataRepository.removeProjectVersion( repositoryId, artifact.getGroupId(),
  724. artifact.getArtifactId(), artifact.getVersion() );
  725. }
  726. }
  727. }
  728. for ( ArtifactMetadata artifactMetadata : artifacts )
  729. {
  730. // TODO: mismatch between artifact (snapshot) version and project (base) version here
  731. if ( artifactMetadata.getVersion().equals( artifact.getVersion() ) )
  732. {
  733. if ( StringUtils.isNotBlank( artifact.getClassifier() ) )
  734. {
  735. if ( StringUtils.isBlank( artifact.getPackaging() ) )
  736. {
  737. throw new ArchivaRestServiceException(
  738. "You must configure a type/packaging when using classifier", 400, null );
  739. }
  740. // cleanup facet which contains classifier information
  741. MavenArtifactFacet mavenArtifactFacet =
  742. (MavenArtifactFacet) artifactMetadata.getFacet( MavenArtifactFacet.FACET_ID );
  743. if ( StringUtils.equals( artifact.getClassifier(), mavenArtifactFacet.getClassifier() ) )
  744. {
  745. artifactMetadata.removeFacet( MavenArtifactFacet.FACET_ID );
  746. String groupId = artifact.getGroupId(), artifactId = artifact.getArtifactId(), version =
  747. artifact.getVersion();
  748. MavenArtifactFacet mavenArtifactFacetToCompare = new MavenArtifactFacet();
  749. mavenArtifactFacetToCompare.setClassifier( artifact.getClassifier() );
  750. metadataRepository.removeArtifact( repositoryId, groupId, artifactId, version,
  751. mavenArtifactFacetToCompare );
  752. metadataRepository.save();
  753. }
  754. }
  755. else
  756. {
  757. if ( snapshotVersion )
  758. {
  759. metadataRepository.removeArtifact( artifactMetadata,
  760. VersionUtil.getBaseVersion( artifact.getVersion() ) );
  761. }
  762. else
  763. {
  764. metadataRepository.removeArtifact( artifactMetadata.getRepositoryId(),
  765. artifactMetadata.getNamespace(),
  766. artifactMetadata.getProject(), artifact.getVersion(),
  767. artifactMetadata.getId() );
  768. }
  769. }
  770. // TODO: move into the metadata repository proper - need to differentiate attachment of
  771. // repository metadata to an artifact
  772. for ( RepositoryListener listener : listeners )
  773. {
  774. listener.deleteArtifact( metadataRepository, repository.getId(),
  775. artifactMetadata.getNamespace(), artifactMetadata.getProject(),
  776. artifactMetadata.getVersion(), artifactMetadata.getId() );
  777. }
  778. triggerAuditEvent( repositoryId, path, AuditEvent.REMOVE_FILE );
  779. }
  780. }
  781. }
  782. catch ( ContentNotFoundException e )
  783. {
  784. throw new ArchivaRestServiceException( "Artifact does not exist: " + e.getMessage(), 400, e );
  785. }
  786. catch ( RepositoryNotFoundException e )
  787. {
  788. throw new ArchivaRestServiceException( "Target repository cannot be found: " + e.getMessage(), 400, e );
  789. }
  790. catch ( RepositoryException e )
  791. {
  792. throw new ArchivaRestServiceException( "Repository exception: " + e.getMessage(), 500, e );
  793. }
  794. catch ( MetadataResolutionException e )
  795. {
  796. throw new ArchivaRestServiceException( "Repository exception: " + e.getMessage(), 500, e );
  797. }
  798. catch ( MetadataRepositoryException e )
  799. {
  800. throw new ArchivaRestServiceException( "Repository exception: " + e.getMessage(), 500, e );
  801. }
  802. catch ( RepositoryAdminException e )
  803. {
  804. throw new ArchivaRestServiceException( "RepositoryAdmin exception: " + e.getMessage(), 500, e );
  805. }
  806. finally
  807. {
  808. repositorySession.save();
  809. repositorySession.close();
  810. }
  811. return Boolean.TRUE;
  812. }
  813. @Override
  814. public Boolean deleteGroupId( String groupId, String repositoryId )
  815. throws ArchivaRestServiceException
  816. {
  817. if ( StringUtils.isEmpty( repositoryId ) )
  818. {
  819. throw new ArchivaRestServiceException( "repositoryId cannot be null", 400, null );
  820. }
  821. if ( !isAuthorizedToDeleteArtifacts( repositoryId ) )
  822. {
  823. throw new ArchivaRestServiceException( "not authorized to delete artifacts", 403, null );
  824. }
  825. if ( StringUtils.isEmpty( groupId ) )
  826. {
  827. throw new ArchivaRestServiceException( "groupId cannot be null", 400, null );
  828. }
  829. RepositorySession repositorySession = repositorySessionFactory.createSession();
  830. try
  831. {
  832. ManagedRepositoryContent repository = repositoryFactory.getManagedRepositoryContent( repositoryId );
  833. repository.deleteGroupId( groupId );
  834. MetadataRepository metadataRepository = repositorySession.getRepository();
  835. metadataRepository.removeNamespace( repositoryId, groupId );
  836. // just invalidate cache entry
  837. String cacheKey = repositoryId + "-" + groupId;
  838. namespacesCache.remove( cacheKey );
  839. namespacesCache.remove( repositoryId );
  840. metadataRepository.save();
  841. }
  842. catch ( MetadataRepositoryException e )
  843. {
  844. log.error( e.getMessage(), e );
  845. throw new ArchivaRestServiceException( "Repository exception: " + e.getMessage(), 500, e );
  846. }
  847. catch ( RepositoryException e )
  848. {
  849. log.error( e.getMessage(), e );
  850. throw new ArchivaRestServiceException( "Repository exception: " + e.getMessage(), 500, e );
  851. }
  852. finally
  853. {
  854. repositorySession.close();
  855. }
  856. return true;
  857. }
  858. @Override
  859. public Boolean deleteProject( String groupId, String projectId, String repositoryId )
  860. throws ArchivaRestServiceException
  861. {
  862. if ( StringUtils.isEmpty( repositoryId ) )
  863. {
  864. throw new ArchivaRestServiceException( "repositoryId cannot be null", 400, null );
  865. }
  866. if ( !isAuthorizedToDeleteArtifacts( repositoryId ) )
  867. {
  868. throw new ArchivaRestServiceException( "not authorized to delete artifacts", 403, null );
  869. }
  870. if ( StringUtils.isEmpty( groupId ) )
  871. {
  872. throw new ArchivaRestServiceException( "groupId cannot be null", 400, null );
  873. }
  874. if ( StringUtils.isEmpty( projectId ) )
  875. {
  876. throw new ArchivaRestServiceException( "artifactId cannot be null", 400, null );
  877. }
  878. RepositorySession repositorySession = repositorySessionFactory.createSession();
  879. try
  880. {
  881. ManagedRepositoryContent repository = repositoryFactory.getManagedRepositoryContent( repositoryId );
  882. repository.deleteProject( groupId, projectId );
  883. }
  884. catch ( ContentNotFoundException e )
  885. {
  886. log.warn( "skip ContentNotFoundException: {}", e.getMessage() );
  887. }
  888. catch ( RepositoryException e )
  889. {
  890. log.error( e.getMessage(), e );
  891. throw new ArchivaRestServiceException( "Repository exception: " + e.getMessage(), 500, e );
  892. }
  893. try
  894. {
  895. MetadataRepository metadataRepository = repositorySession.getRepository();
  896. metadataRepository.removeProject( repositoryId, groupId, projectId );
  897. metadataRepository.save();
  898. }
  899. catch ( MetadataRepositoryException e )
  900. {
  901. log.error( e.getMessage(), e );
  902. throw new ArchivaRestServiceException( "Repository exception: " + e.getMessage(), 500, e );
  903. }
  904. finally
  905. {
  906. repositorySession.close();
  907. }
  908. return true;
  909. }
  910. @Override
  911. public Boolean isAuthorizedToDeleteArtifacts( String repoId )
  912. throws ArchivaRestServiceException
  913. {
  914. String userName =
  915. getAuditInformation().getUser() == null ? "guest" : getAuditInformation().getUser().getUsername();
  916. try
  917. {
  918. return userRepositories.isAuthorizedToDeleteArtifacts( userName, repoId );
  919. }
  920. catch ( ArchivaSecurityException e )
  921. {
  922. throw new ArchivaRestServiceException( e.getMessage(),
  923. Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), e );
  924. }
  925. }
  926. @Override
  927. public RepositoryScanStatistics scanRepositoryDirectoriesNow( String repositoryId )
  928. throws ArchivaRestServiceException
  929. {
  930. long sinceWhen = RepositoryScanner.FRESH_SCAN;
  931. try
  932. {
  933. return repoScanner.scan( getManagedRepositoryAdmin().getManagedRepository( repositoryId ), sinceWhen );
  934. }
  935. catch ( RepositoryScannerException e )
  936. {
  937. log.error( e.getMessage(), e );
  938. throw new ArchivaRestServiceException( "RepositoryScannerException exception: " + e.getMessage(), 500, e );
  939. }
  940. catch ( RepositoryAdminException e )
  941. {
  942. log.error( e.getMessage(), e );
  943. throw new ArchivaRestServiceException( "RepositoryScannerException exception: " + e.getMessage(), 500, e );
  944. }
  945. }
  946. /**
  947. * Update artifact level metadata. Creates one if metadata does not exist after artifact deletion.
  948. *
  949. * @param metadata
  950. */
  951. private void updateMetadata( ArchivaRepositoryMetadata metadata, File metadataFile, Date lastUpdatedTimestamp,
  952. Artifact artifact )
  953. throws RepositoryMetadataException
  954. {
  955. List<String> availableVersions = new ArrayList<>();
  956. String latestVersion = "";
  957. if ( metadataFile.exists() )
  958. {
  959. if ( metadata.getAvailableVersions() != null )
  960. {
  961. availableVersions = metadata.getAvailableVersions();
  962. if ( availableVersions.size() > 0 )
  963. {
  964. Collections.sort( availableVersions, VersionComparator.getInstance() );
  965. if ( availableVersions.contains( artifact.getVersion() ) )
  966. {
  967. availableVersions.remove( availableVersions.indexOf( artifact.getVersion() ) );
  968. }
  969. if ( availableVersions.size() > 0 )
  970. {
  971. latestVersion = availableVersions.get( availableVersions.size() - 1 );
  972. }
  973. }
  974. }
  975. }
  976. if ( metadata.getGroupId() == null )
  977. {
  978. metadata.setGroupId( artifact.getGroupId() );
  979. }
  980. if ( metadata.getArtifactId() == null )
  981. {
  982. metadata.setArtifactId( artifact.getArtifactId() );
  983. }
  984. if ( !VersionUtil.isSnapshot( artifact.getVersion() ) )
  985. {
  986. if ( metadata.getReleasedVersion() != null && metadata.getReleasedVersion().equals(
  987. artifact.getVersion() ) )
  988. {
  989. metadata.setReleasedVersion( latestVersion );
  990. }
  991. }
  992. metadata.setLatestVersion( latestVersion );
  993. metadata.setLastUpdatedTimestamp( lastUpdatedTimestamp );
  994. metadata.setAvailableVersions( availableVersions );
  995. RepositoryMetadataWriter.write( metadata, metadataFile );
  996. ChecksummedFile checksum = new ChecksummedFile( metadataFile );
  997. checksum.fixChecksums( algorithms );
  998. }
  999. @Override
  1000. public StringList getRunningRemoteDownloadIds()
  1001. {
  1002. return new StringList( downloadRemoteIndexScheduler.getRunningRemoteDownloadIds() );
  1003. }
  1004. public ManagedRepositoryAdmin getManagedRepositoryAdmin()
  1005. {
  1006. return managedRepositoryAdmin;
  1007. }
  1008. public void setManagedRepositoryAdmin( ManagedRepositoryAdmin managedRepositoryAdmin )
  1009. {
  1010. this.managedRepositoryAdmin = managedRepositoryAdmin;
  1011. }
  1012. public RepositoryContentFactory getRepositoryFactory()
  1013. {
  1014. return repositoryFactory;
  1015. }
  1016. public void setRepositoryFactory( RepositoryContentFactory repositoryFactory )
  1017. {
  1018. this.repositoryFactory = repositoryFactory;
  1019. }
  1020. public RepositorySessionFactory getRepositorySessionFactory()
  1021. {
  1022. return repositorySessionFactory;
  1023. }
  1024. public void setRepositorySessionFactory( RepositorySessionFactory repositorySessionFactory )
  1025. {
  1026. this.repositorySessionFactory = repositorySessionFactory;
  1027. }
  1028. public List<RepositoryListener> getListeners()
  1029. {
  1030. return listeners;
  1031. }
  1032. public void setListeners( List<RepositoryListener> listeners )
  1033. {
  1034. this.listeners = listeners;
  1035. }
  1036. public ArchivaAdministration getArchivaAdministration()
  1037. {
  1038. return archivaAdministration;
  1039. }
  1040. public void setArchivaAdministration( ArchivaAdministration archivaAdministration )
  1041. {
  1042. this.archivaAdministration = archivaAdministration;
  1043. }
  1044. }