package org.carlspring.strongbox.storage.metadata; import org.carlspring.maven.commons.DetachedArtifact; import org.carlspring.maven.commons.util.ArtifactUtils; import java.io.File; import java.io.FileNotFoundException; import java.nio.file.Files; import java.nio.file.Path; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Collections; import java.util.List; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.repository.metadata.Metadata; import org.apache.maven.artifact.repository.metadata.Snapshot; import org.apache.maven.artifact.repository.metadata.SnapshotVersion; import org.apache.maven.artifact.repository.metadata.Versioning; import org.springframework.util.StringUtils; /** * @author mtodorov */ public class MetadataHelper { public static final String MAVEN_METADATA_XML = "maven-metadata.xml"; private static SimpleDateFormat LAST_UPDATED_FIELD_FORMATTER; private MetadataHelper() { } public static SimpleDateFormat getDateFormatInstance() { if (LAST_UPDATED_FIELD_FORMATTER == null) { LAST_UPDATED_FIELD_FORMATTER = new SimpleDateFormat("yyyyMMddHHmmss"); } return LAST_UPDATED_FIELD_FORMATTER; } public static void setLastUpdated(Versioning versioning) { if (versioning != null) { versioning.setLastUpdated(getDateFormatInstance().format(Calendar.getInstance().getTime())); } } public static void setLatest(Metadata metadata) { setLatest(metadata, null); } /** * Sets the "latest" field. * * @param metadata The metadata to apply this to. * @param currentLatest Only pass this in, if this is delete mode, otherwise * this method will figure things out on it's own. */ public static void setLatest(Metadata metadata, String currentLatest) { Versioning versioning = metadata.getVersioning() != null ? metadata.getVersioning() : new Versioning(); if (metadata.getVersioning() == null) { metadata.setVersioning(versioning); } List<String> versions = versioning.getVersions(); sortVersions(versions); if (currentLatest != null && versioning.getLatest() != null && versioning.getLatest().equals(currentLatest)) { // Delete mode: if (versions.size() > 1) { // TODO: Is this the right thing to do? versioning.setLatest(versions.get(versions.size() - 2)); } else { // TODO: Figure out what we should do in case there are no other available versions } } else { // Regular mode versioning.setLatest(versions.get(versions.size() - 1)); } } /** * @param metadata The metadata to apply this to. */ public static void setRelease(Metadata metadata) { setRelease(metadata, null); } /** * Sets the "release" field. * * @param metadata The metadata to apply this to. * @param currentRelease Only pass this in, if this is delete mode, otherwise * this method will figure things out on it's own. */ public static void setRelease(Metadata metadata, String currentRelease) { Versioning versioning = metadata.getVersioning() != null ? metadata.getVersioning() : new Versioning(); if (metadata.getVersioning() == null) { metadata.setVersioning(versioning); } List<String> versions = versioning.getVersions(); sortVersions(versions); if (currentRelease != null && versioning.getRelease()!= null && versioning.getRelease().equals(currentRelease)) { // Delete mode: if (versions.size() > 1) { versioning.setRelease(versions.get(versions.size() - 2)); } else { // TODO: Figure out what we should do in case there are no other available versions } } else { // Regular mode versioning.setRelease(versions.get(versions.size() - 1)); } } private static void sortVersions(List<String> versions) { // Sort the versions in order to set <release> by figuring out the most recent upload if (versions != null) { Collections.sort(versions); } } public static SnapshotVersion createSnapshotVersion(String groupId, String artifactId, String version, String classifier, String extension) { Artifact artifact = new DetachedArtifact(groupId, artifactId, version, null, classifier); return createSnapshotVersion(artifact, extension); } public static SnapshotVersion createSnapshotVersion(Artifact artifact, String extension) { SnapshotVersion snapshotVersion = new SnapshotVersion(); snapshotVersion.setVersion(artifact.getVersion()); snapshotVersion.setExtension(extension); snapshotVersion.setUpdated(getDateFormatInstance().format(Calendar.getInstance().getTime())); if (artifact.getClassifier() != null) { snapshotVersion.setClassifier(artifact.getClassifier()); } return snapshotVersion; } public static void setupSnapshotVersioning(Versioning snapshotVersioning) { if (!snapshotVersioning.getSnapshotVersions().isEmpty()) { SnapshotVersion latestSnapshot = snapshotVersioning.getSnapshotVersions().get(snapshotVersioning.getSnapshotVersions().size() - 1); String timestamp = ArtifactUtils.getSnapshotTimestamp(latestSnapshot.getVersion()); // Potentially revisit this for timestamps with custom formats int buildNumber = Integer.parseInt(ArtifactUtils.getSnapshotBuildNumber(latestSnapshot.getVersion())); if (!StringUtils.isEmpty(timestamp) || !StringUtils.isEmpty(buildNumber)) { Snapshot snapshot = new Snapshot(); snapshot.setTimestamp(timestamp); snapshot.setBuildNumber(buildNumber); snapshotVersioning.setSnapshot(snapshot); } } } public static boolean containsTimestampedSnapshotVersion(Metadata metadata, String timestampedSnapshotVersion) { return containsTimestampedSnapshotVersion(metadata, timestampedSnapshotVersion, null); } public static boolean containsTimestampedSnapshotVersion(Metadata metadata, String timestampedSnapshotVersion, String classifier) { for (SnapshotVersion snapshotVersion : metadata.getVersioning().getSnapshotVersions()) { if (snapshotVersion.getVersion().equals(timestampedSnapshotVersion) && classifier == null || snapshotVersion.getClassifier().equals(classifier)) { return true; } } return false; } public static boolean containsVersion(Metadata metadata, String version) { return metadata.getVersioning().getVersions().contains(version); } /** * Returns artifact metadata File * * @param artifactBasePath Path * @return File */ public static Path getMetadataFile(Path artifactBasePath) throws FileNotFoundException { if (Files.exists(artifactBasePath)) { return artifactBasePath.resolve(MAVEN_METADATA_XML); } else { throw new FileNotFoundException("Could not find " + new File(artifactBasePath.toFile().getAbsolutePath() + "/maven-metadata.xml") + "!"); } } public static File getArtifactMetadataFile(Path artifactBasePath) { return getMetadataFile(artifactBasePath, null, MetadataType.ARTIFACT_ROOT_LEVEL); } public static File getSnapshotMetadataFile(Path artifactBasePath, String version) { return getMetadataFile(artifactBasePath, version, MetadataType.SNAPSHOT_VERSION_LEVEL); } public static File getPluginMetadataFile(Path artifactBasePath) { return getMetadataFile(artifactBasePath, null, MetadataType.PLUGIN_GROUP_LEVEL); } /** * Returns artifact metadata File * * @param artifactBasePath Path * @return File */ public static File getMetadataFile(Path artifactBasePath, String version, MetadataType metadataType) { switch (metadataType) { case PLUGIN_GROUP_LEVEL: return new File(artifactBasePath.getParent() .toFile() .getAbsolutePath() + "/" + MAVEN_METADATA_XML); case SNAPSHOT_VERSION_LEVEL: return new File(artifactBasePath.toFile() .getAbsolutePath() + "/" + version + "/" + MAVEN_METADATA_XML); case ARTIFACT_ROOT_LEVEL: default: return new File(artifactBasePath.toFile() .getAbsolutePath() + "/" + MAVEN_METADATA_XML); } } public static Path getMetadataPath(Path artifactBasePath, String version, MetadataType metadataType) { return getMetadataFile(artifactBasePath, version, metadataType).toPath(); } }