org.metaeffekt.artifact.resolver.deb.ubuntu.UbuntuPoolAdapter Maven / Gradle / Ivy
package org.metaeffekt.artifact.resolver.deb.ubuntu;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.metaeffekt.artifact.resolver.ResolverResult;
import org.metaeffekt.artifact.resolver.deb.DebArtifactReference;
import org.metaeffekt.artifact.resolver.deb.index.pool.UbuntuPoolIndex;
import org.metaeffekt.artifact.resolver.download.WebAccess;
import org.metaeffekt.artifact.resolver.generic.AbstractDownloadingAdapter;
import org.metaeffekt.artifact.resolver.generic.FileLocation;
import org.metaeffekt.artifact.resolver.generic.utils.GenericUtils;
import org.metaeffekt.artifact.resolver.generic.utils.MarkerUtils;
import org.metaeffekt.artifact.resolver.model.DownloadLocation;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
@Slf4j
public class UbuntuPoolAdapter extends AbstractDownloadingAdapter {
private final UbuntuPoolAdapterConfig config;
@NonNull
private final List poolIndices = new ArrayList<>();
public UbuntuPoolAdapter(DownloadLocation downloadLocation, WebAccess webAccess, UbuntuPoolAdapterConfig config) {
super(downloadLocation, webAccess);
// ensure config isn't null
this.config = config;// construct pool indices if possible
if (this.config != null) {
for (final String poolDir : config.getPoolDirs()) {
final UbuntuPoolIndex poolIndex = new UbuntuPoolIndex(downloadLocation, webAccess, poolDir);
poolIndices.add(poolIndex);
}
}
}
/**
* Derives a pool prefix (a, b, liba, libf) from the given reference.
*
* We simply try to match the format that is used by the ubuntu pool.
* See the official repo pool for what this looks like.
* @param binaryPackageRef a valid debian artifact reference
* @return a prefix to be used in url generation
*/
@NonNull
protected String getPoolPrefix(DebArtifactReference binaryPackageRef) {
final String packageName = binaryPackageRef.getName();
if (packageName.startsWith("lib")) {
// they appear to have statically coded special handling of lib names, since there are many libraries.
return packageName.substring(0, 4);
} else {
return packageName.substring(0, 1);
}
}
protected String getFilenameForBinaryPackage(@NonNull DebArtifactReference binaryPackageRef) {
final String versionWithoutEpoch;
// the vesion in filename doesn't seem to include epoch
int colonIndex = binaryPackageRef.getVersion().indexOf(':');
if (colonIndex == -1) {
versionWithoutEpoch = binaryPackageRef.getVersion();
} else {
versionWithoutEpoch = binaryPackageRef.getVersion().substring(colonIndex + 1);
}
return binaryPackageRef.getName() +
"_" + versionWithoutEpoch +
"_" + binaryPackageRef.getArchitecture() + ".deb";
}
@NonNull
protected List getPoolUrls(@NonNull DebArtifactReference binaryPackageRef) {
final String debFilename = getFilenameForBinaryPackage(binaryPackageRef);
List urls = new ArrayList<>();
for (final UbuntuPoolIndex index : poolIndices) {
try {
final List pathsFromIndex = index.getDirectoriesFromFilename(debFilename);
for (String path : pathsFromIndex) {
urls.add(path + "/" + getFilenameForBinaryPackage(binaryPackageRef));
}
} catch (Exception e) {
log.debug("Ignoring unexpected Exception while trying to use index of [{}] while resolving [{}].",
index,
binaryPackageRef,
e);
}
}
return urls;
}
protected File downloadBinaryDeb(@NonNull DebArtifactReference binaryPackageRef,
@NonNull String downloadFilename,
@NonNull String fileUrl) {
if (!binaryPackageRef.isValid()) {
// can't work with invalid references. return failure.
return null;
}
final FileLocation fileLocation = binaryPackageRef.deriveFileLocation(downloadFilename);
final File file = deriveDownloadFile(fileLocation);
final File markerFile = MarkerUtils.deriveMarkerFileFromDestination(file);
final File downloaded = GenericUtils.downloadFile(this.getWebAccess(),
fileUrl,
file,
binaryPackageRef.toString());
// override default marker behaviour: manage markers externally to support multiple download attempts.
if (markerFile.exists() && !markerFile.delete()) {
log.warn("Could not delete marker file for sub-download [{}] to file [{}]. May produce false negative.",
fileUrl,
file);
}
return downloaded;
}
/**
* Tried to get a binary package from any of the configured pool directory.
*
* @param binaryPackageRef binary reference to resolve the deb for
*
* @return downloaded ResolverResult.
*/
public ResolverResult getBinaryFromPool(@NonNull DebArtifactReference binaryPackageRef, DebArtifactReference sourcePackageRef) {
log.trace("Resolving source package [{}] for given [{}].", sourcePackageRef, binaryPackageRef);
if (this.config == null || this.config.getPoolDirs() == null || this.config.getPoolDirs().isEmpty()) {
if (log.isTraceEnabled()) {
log.trace("Not resolving [{}] because this resolver of class [{}] is not configured.",
binaryPackageRef, this.getClass().getSimpleName());
}
return null;
}
// NOTE: config.getPoolDirs is not non-null
if (!binaryPackageRef.isValid()) {
// can't work with an invalid package ref
log.trace("Not resolving invalid package ref [{}].", binaryPackageRef);
return null;
}
final String binaryDebFilename = getFilenameForBinaryPackage(binaryPackageRef);
final File destinationFile = deriveDownloadFile(binaryPackageRef.deriveFileLocation(binaryDebFilename));
final File markerFile = MarkerUtils.deriveMarkerFileFromDestination(destinationFile);
return resolve(MarkerUtils.attemptDownload(markerFile, binaryPackageRef.toString(), () -> {
final List urls = getPoolUrls(binaryPackageRef);
for (String url : urls) {
final File downloaded = GenericUtils.downloadFile(getWebAccess(), url, destinationFile, binaryPackageRef.toString());
if (downloaded != null) {
return downloaded;
}
}
return null;
}), null);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy