com.artipie.nuget.http.content.PackageContent Maven / Gradle / Ivy
/*
* The MIT License (MIT) Copyright (c) 2020-2023 artipie.com
* https://github.com/nuget-adapter/artipie/LICENSE.txt
*/
package com.artipie.nuget.http.content;
import com.artipie.asto.Key;
import com.artipie.http.Headers;
import com.artipie.http.Response;
import com.artipie.http.async.AsyncResponse;
import com.artipie.http.rs.RsStatus;
import com.artipie.http.rs.RsWithStatus;
import com.artipie.nuget.PackageIdentity;
import com.artipie.nuget.Repository;
import com.artipie.nuget.http.Resource;
import com.artipie.nuget.http.Route;
import com.artipie.nuget.http.RsWithBodyNoHeaders;
import com.artipie.nuget.http.metadata.ContentLocation;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.ByteBuffer;
import java.util.Optional;
import org.reactivestreams.Publisher;
/**
* Package content route.
* See Package Content
*
* @since 0.1
*/
public final class PackageContent implements Route, ContentLocation {
/**
* Base URL of repository.
*/
private final URL base;
/**
* Repository to read content from.
*/
private final Repository repository;
/**
* Ctor.
*
* @param base Base URL of repository.
* @param repository Repository to read content from.
*/
public PackageContent(final URL base, final Repository repository) {
this.base = base;
this.repository = repository;
}
@Override
public String path() {
return "/content";
}
@Override
public Resource resource(final String path) {
return new PackageResource(path, this.repository);
}
@Override
public URL url(final PackageIdentity identity) {
final String relative = String.format(
"%s%s/%s",
this.base.getPath(),
this.path(),
identity.nupkgKey().string()
);
try {
return new URL(this.base, relative);
} catch (final MalformedURLException ex) {
throw new IllegalStateException(
String.format("Failed to build URL from base: '%s'", this.base),
ex
);
}
}
/**
* Package content resource.
*
* @since 0.1
*/
private class PackageResource implements Resource {
/**
* Resource path.
*/
private final String path;
/**
* Repository to read content from.
*/
private final Repository repository;
/**
* Ctor.
*
* @param path Resource path.
* @param repository Storage to read content from.
*/
PackageResource(final String path, final Repository repository) {
this.path = path;
this.repository = repository;
}
@Override
public Response get(final Headers headers) {
return this.key().map(
key -> new AsyncResponse(
this.repository.content(key).thenApply(
existing -> existing.map(
data -> new RsWithBodyNoHeaders(new RsWithStatus(RsStatus.OK), data)
).orElse(new RsWithStatus(RsStatus.NOT_FOUND))
)
)
).orElse(new RsWithStatus(RsStatus.NOT_FOUND));
}
@Override
public Response put(
final Headers headers,
final Publisher body) {
return new RsWithStatus(RsStatus.METHOD_NOT_ALLOWED);
}
/**
* Tries to build key to storage value from path.
*
* @return Key to storage value, if there is one.
*/
private Optional key() {
final String prefix = String.format("%s/", path());
final Optional parsed;
if (this.path.startsWith(prefix)) {
parsed = Optional.of(new Key.From(this.path.substring(prefix.length())));
} else {
parsed = Optional.empty();
}
return parsed;
}
}
}