public boolean releaseExistsForSnapshot(Gav snapshotGav, Map<String, Object> context) { for (Repository repository : repositoryRegistry.getRepositories()) { // we need to filter for: // repository that is MavenRepository and is hosted or proxy // repository that has release policy if (repository.getRepositoryKind().isFacetAvailable(MavenHostedRepository.class) || repository.getRepositoryKind().isFacetAvailable(MavenProxyRepository.class)) { // actually, we don't care is it proxy or hosted, we only need to filter out groups and // other // "composite" reposes like shadows MavenRepository mrepository = repository.adaptToFacet(MavenRepository.class); // look in release reposes only if (mrepository.isUserManaged() && RepositoryPolicy.RELEASE.equals(mrepository.getRepositoryPolicy())) { try { String releaseVersion = null; // NEXUS-3148 if (snapshotGav.getBaseVersion().endsWith("-SNAPSHOT")) { // "-SNAPSHOT" :== 9 chars releaseVersion = snapshotGav .getBaseVersion() .substring(0, snapshotGav.getBaseVersion().length() - 9); } else { // "SNAPSHOT" :== 8 chars releaseVersion = snapshotGav .getBaseVersion() .substring(0, snapshotGav.getBaseVersion().length() - 8); } Gav releaseGav = new Gav( snapshotGav.getGroupId(), snapshotGav.getArtifactId(), releaseVersion, snapshotGav.getClassifier(), snapshotGav.getExtension(), null, null, null, false, null, false, null); String path = mrepository.getGavCalculator().gavToPath(releaseGav); ResourceStoreRequest req = new ResourceStoreRequest(path, true); req.getRequestContext().putAll(context); mrepository.retrieveItem(false, req); return true; } catch (ItemNotFoundException e) { // nothing } catch (Exception e) { // nothing } } } } return false; }
public void doOnCollectionExit(WalkerContext context, StorageCollectionItem coll) throws Exception { if (getLogger().isDebugEnabled()) { getLogger().debug("onCollectionExit() :: " + coll.getRepositoryItemUid().toString()); } shouldProcessCollection = coll.getPath().endsWith("SNAPSHOT"); if (!shouldProcessCollection) { return; } deletableSnapshotsAndFiles.clear(); remainingSnapshotsAndFiles.clear(); removeWholeGAV = false; Gav gav = null; Collection<StorageItem> items; items = repository.list(false, coll); HashSet<Long> versionsToRemove = new HashSet<Long>(); // gathering the facts for (StorageItem item : items) { if (!item.isVirtual() && !StorageCollectionItem.class.isAssignableFrom(item.getClass())) { gav = ((MavenRepository) coll.getRepositoryItemUid().getRepository()) .getGavCalculator() .pathToGav(item.getPath()); if (gav != null) { // if we find a pom, check for delete on release if (!gav.isHash() && !gav.isSignature() && gav.getExtension().equals("pom")) { if (request.isRemoveIfReleaseExists() && releaseExistsForSnapshot(gav, item.getItemContext())) { getLogger().debug("Found POM and release exists, removing whole gav."); removeWholeGAV = true; // Will break out and junk whole gav break; } } item.getItemContext().put(Gav.class.getName(), gav); if (gav.getSnapshotTimeStamp() != null) { getLogger().debug("Using GAV snapshot timestamp"); long itemTimestamp = gav.getSnapshotTimeStamp().longValue(); getLogger().debug("NOW is " + itemTimestamp); // If this timestamp is already marked to be removed, junk it if (versionsToRemove.contains(new Long(itemTimestamp))) { addStorageFileItemToMap(deletableSnapshotsAndFiles, gav, (StorageFileItem) item); } else { getLogger() .debug("itemTimestamp=" + itemTimestamp + ", dateTreshold=" + dateThreshold); // if dateTreshold is not used (zero days) OR // if itemTimestamp is less then dateTreshold (NB: both are positive!) // below will the retentionCount overrule if needed this if (-1 == dateThreshold || itemTimestamp < dateThreshold) { versionsToRemove.add(new Long(itemTimestamp)); addStorageFileItemToMap(deletableSnapshotsAndFiles, gav, (StorageFileItem) item); } else { addStorageFileItemToMap(remainingSnapshotsAndFiles, gav, (StorageFileItem) item); } } } else { // If no timestamp on gav, then it is a non-unique snapshot // and should _not_ be removed getLogger() .debug("GAV Snapshot timestamp not available, skipping non-unique snapshot"); addStorageFileItemToMap(remainingSnapshotsAndFiles, gav, (StorageFileItem) item); } } } } // and doing the work here if (removeWholeGAV) { try { for (StorageItem item : items) { try { // preserve possible subdirs if (!(item instanceof StorageCollectionItem)) { repository.deleteItem(false, new ResourceStoreRequest(item)); } } catch (ItemNotFoundException e) { if (getLogger().isDebugEnabled()) { getLogger() .debug( "Could not delete whole GAV " + coll.getRepositoryItemUid().toString(), e); } } } } catch (Exception e) { getLogger() .warn("Could not delete whole GAV " + coll.getRepositoryItemUid().toString(), e); } } else { // and now check some things if (remainingSnapshotsAndFiles.size() < request.getMinCountOfSnapshotsToKeep()) { // do something if (remainingSnapshotsAndFiles.size() + deletableSnapshotsAndFiles.size() < request.getMinCountOfSnapshotsToKeep()) { // delete nothing, since there is less snapshots in total as allowed deletableSnapshotsAndFiles.clear(); } else { TreeSet<Version> keys = new TreeSet<Version>(deletableSnapshotsAndFiles.keySet()); while (!keys.isEmpty() && remainingSnapshotsAndFiles.size() < request.getMinCountOfSnapshotsToKeep()) { Version keyToMove = keys.last(); if (remainingSnapshotsAndFiles.containsKey(keyToMove)) { remainingSnapshotsAndFiles .get(keyToMove) .addAll(deletableSnapshotsAndFiles.get(keyToMove)); } else { remainingSnapshotsAndFiles.put( keyToMove, deletableSnapshotsAndFiles.get(keyToMove)); } deletableSnapshotsAndFiles.remove(keyToMove); keys.remove(keyToMove); } } } // NEXUS-814: is this GAV have remaining artifacts? boolean gavHasMoreTimestampedSnapshots = remainingSnapshotsAndFiles.size() > 0; for (Version key : deletableSnapshotsAndFiles.keySet()) { List<StorageFileItem> files = deletableSnapshotsAndFiles.get(key); deletedSnapshots++; for (StorageFileItem file : files) { try { // NEXUS-814: mark that we are deleting a TS snapshot, but there are still remaining // ones in repository. if (gavHasMoreTimestampedSnapshots) { file.getItemContext().put(MORE_TS_SNAPSHOTS_EXISTS_FOR_GAV, Boolean.TRUE); } gav = (Gav) file.getItemContext().get(Gav.class.getName()); repository.deleteItem(false, new ResourceStoreRequest(file)); deletedFiles++; } catch (ItemNotFoundException e) { if (getLogger().isDebugEnabled()) { getLogger().debug("Could not delete file:", e); } } catch (Exception e) { getLogger().info("Could not delete file:", e); } } } } removeDirectoryIfEmpty(coll); updateMetadataIfNecessary(context, coll); }