io.resys.thena.docdb.spi.objects.BlobStateBuilderDefault Maven / Gradle / Ivy
The newest version!
package io.resys.thena.docdb.spi.objects;
import java.time.LocalDateTime;
/*-
* #%L
* thena-docdb-api
* %%
* Copyright (C) 2021 Copyright 2021 ReSys OÜ
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import org.immutables.value.Value;
import io.resys.thena.docdb.api.actions.ImmutableBlobObject;
import io.resys.thena.docdb.api.actions.ImmutableBlobObjects;
import io.resys.thena.docdb.api.actions.ImmutableObjectsResult;
import io.resys.thena.docdb.api.actions.ObjectsActions.BlobObject;
import io.resys.thena.docdb.api.actions.ObjectsActions.BlobObjects;
import io.resys.thena.docdb.api.actions.ObjectsActions.BlobStateBuilder;
import io.resys.thena.docdb.api.actions.ObjectsActions.MatchCriteria;
import io.resys.thena.docdb.api.actions.ObjectsActions.ObjectsResult;
import io.resys.thena.docdb.api.actions.ObjectsActions.ObjectsStatus;
import io.resys.thena.docdb.api.exceptions.RepoException;
import io.resys.thena.docdb.api.models.ImmutableCommit;
import io.resys.thena.docdb.api.models.ImmutableMessage;
import io.resys.thena.docdb.api.models.ImmutableTree;
import io.resys.thena.docdb.api.models.Message;
import io.resys.thena.docdb.api.models.Objects.Blob;
import io.resys.thena.docdb.api.models.Objects.Commit;
import io.resys.thena.docdb.api.models.Objects.Tree;
import io.resys.thena.docdb.api.models.Repo;
import io.resys.thena.docdb.spi.ClientState;
import io.resys.thena.docdb.spi.ClientState.ClientRepoState;
import io.resys.thena.docdb.spi.support.RepoAssert;
import io.smallrye.mutiny.Uni;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
public class BlobStateBuilderDefault implements BlobStateBuilder {
private final ClientState state;
private String repoName;
private String refOrCommitOrTag;
private List blobName = new ArrayList<>();
private List matchCriteria = new ArrayList<>();
@Value.Immutable
public static interface BlobAndTree {
List getBlob();
Tree getTree();
}
@Override
public BlobStateBuilderDefault repo(String repoName) {
this.repoName = repoName;
return this;
}
@Override
public BlobStateBuilderDefault anyId(String refOrCommitOrTag) {
this.refOrCommitOrTag = refOrCommitOrTag;
return this;
}
@Override
public BlobStateBuilderDefault blobName(String blobName) {
this.blobName.add(blobName);
return this;
}
@Override
public BlobStateBuilderDefault blobNames(List blobName) {
this.blobName.addAll(blobName);
return this;
}
@Override
public BlobStateBuilderDefault matchBy(List matchCriteria) {
this.matchCriteria.addAll(matchCriteria);
return this;
}
@Override
public Uni> list() {
RepoAssert.notEmpty(repoName, () -> "repoName is not defined!");
RepoAssert.notEmpty(refOrCommitOrTag, () -> "refOrCommitOrTag is not defined!");
RepoAssert.isTrue(!blobName.isEmpty() || !matchCriteria.isEmpty(), () -> "blobName or matchCriteria is not defined!");
return state.repos().getByNameOrId(repoName).onItem()
.transformToUni((Repo existing) -> {
if(existing == null) {
return Uni.createFrom().item(ImmutableObjectsResult
.builder()
.status(ObjectsStatus.ERROR)
.addMessages(RepoException.builder().notRepoWithName(repoName))
.build());
}
final var ctx = state.withRepo(existing);
return getTagCommit(refOrCommitOrTag, ctx)
.onItem().transformToUni(tag -> {
if(tag == null) {
return getRefCommit(refOrCommitOrTag, ctx);
}
return Uni.createFrom().item(tag);
})
.onItem().transformToUni(commitId -> {
if(commitId == null) {
return getCommit(refOrCommitOrTag, ctx);
}
return getCommit(commitId, ctx);
}).onItem().transformToUni(commit -> {
if(commit == null) {
return ctx.query().commits().find().collect().asList().onItem()
.transform(allCommits -> {
// empty repo, no commits yet
if(allCommits.isEmpty()) {
return ImmutableObjectsResult
.builder()
.status(ObjectsStatus.OK)
.addMessages(emptyRepo(existing))
.objects(ImmutableBlobObjects.builder()
.repo(existing)
.tree(ImmutableTree.builder().id("").build())
.commit(ImmutableCommit.builder().id("").message("").tree("").author("").dateTime(LocalDateTime.now()).build())
.build())
.build();
}
return ImmutableObjectsResult
.builder()
.status(ObjectsStatus.ERROR)
.addMessages(noCommit(existing))
.build();
});
}
return getListState(existing, commit, ctx);
});
});
}
@Override
public Uni> get() {
RepoAssert.notEmpty(repoName, () -> "repoName is not defined!");
RepoAssert.notEmpty(refOrCommitOrTag, () -> "refOrCommitOrTag is not defined!");
RepoAssert.isTrue(!blobName.isEmpty() || !matchCriteria.isEmpty(), () -> "blobName or matchCriteriais not defined!");
return state.repos().getByNameOrId(repoName).onItem()
.transformToUni((Repo existing) -> {
if(existing == null) {
return Uni.createFrom().item(ImmutableObjectsResult
.builder()
.status(ObjectsStatus.ERROR)
.addMessages(RepoException.builder().notRepoWithName(repoName))
.build());
}
final var ctx = state.withRepo(existing);
return getTagCommit(refOrCommitOrTag, ctx)
.onItem().transformToUni(tag -> {
if(tag == null) {
return getRefCommit(refOrCommitOrTag, ctx);
}
return Uni.createFrom().item(tag);
})
.onItem().transformToUni(commitId -> {
if(commitId == null) {
return getCommit(refOrCommitOrTag, ctx);
}
return getCommit(commitId, ctx);
}).onItem().transformToUni(commit -> {
if(commit == null) {
return Uni.createFrom().item(ImmutableObjectsResult
.builder()
.status(ObjectsStatus.ERROR)
.addMessages(noCommit(existing))
.build());
}
return getState(existing, commit, ctx);
});
});
}
private Message noCommit(Repo repo) {
return ImmutableMessage.builder()
.text(new StringBuilder()
.append("Repo with name: '").append(repo.getName()).append("'")
.append(" does not contain: tag, ref or commit with id:")
.append(" '").append(refOrCommitOrTag).append("'")
.toString())
.build();
}
private Message emptyRepo(Repo repo) {
return ImmutableMessage.builder()
.text(new StringBuilder()
.append("Repo with name: '").append(repo.getName()).append("'")
.append(" is empty!")
.toString())
.build();
}
private Message noBlob(Repo repo, Tree tree) {
return ImmutableMessage.builder()
.text(new StringBuilder()
.append("Repo with name: '").append(repo.getName()).append("'")
.append(", tag, ref or commit with id: ").append(" '").append(refOrCommitOrTag).append("'")
.append(" and tree: ").append(tree.toString())
.append(" does not contain a blob with name: ").append("'").append(blobName).append("'").append("!")
.toString())
.build();
}
private Uni> getState(Repo repo, Commit commit, ClientRepoState ctx) {
return getTree(commit, ctx).onItem()
.transformToUni(tree -> getBlob(tree, ctx)).onItem()
.transformToUni(blobTree -> {
if(blobTree.getBlob().size() != 1) {
return Uni.createFrom().item(ImmutableObjectsResult
.builder()
.status(ObjectsStatus.ERROR)
.addMessages(noBlob(repo, blobTree.getTree()))
.build());
}
return Uni.createFrom().item(ImmutableObjectsResult.builder()
.repo(repo)
.objects(ImmutableBlobObject.builder()
.repo(repo)
.tree(blobTree.getTree())
.commit(commit)
.blob(blobTree.getBlob().isEmpty() ? null : blobTree.getBlob().get(0))
.build())
.status(ObjectsStatus.OK)
.build());
});
}
private Uni> getListState(Repo repo, Commit commit, ClientRepoState ctx) {
return getTree(commit, ctx).onItem()
.transformToUni(tree -> getBlob(tree, ctx)).onItem()
.transformToUni(blobAndTree -> {
if(!this.blobName.isEmpty() && this.matchCriteria.isEmpty() && blobAndTree.getBlob().isEmpty()) {
return Uni.createFrom().item(ImmutableObjectsResult
.builder()
.status(ObjectsStatus.ERROR)
.addMessages(noBlob(repo, blobAndTree.getTree()))
.build());
}
return Uni.createFrom().item(ImmutableObjectsResult.builder()
.repo(repo)
.objects(ImmutableBlobObjects.builder()
.repo(repo)
.tree(blobAndTree.getTree())
.commit(commit)
.blob(blobAndTree.getBlob())
.build())
.status(ObjectsStatus.OK)
.build());
});
}
private Uni getTagCommit(String tagName, ClientRepoState ctx) {
return ctx.query().tags().name(tagName).get()
.onItem().transform(tag -> tag == null ? null : tag.getCommit());
}
private Uni getRefCommit(String refName, ClientRepoState ctx) {
return ctx.query().refs().name(refName)
.onItem().transform(ref -> ref == null ? null : ref.getCommit());
}
private Uni getTree(Commit commit, ClientRepoState ctx) {
return ctx.query().trees().id(commit.getTree());
}
private Uni getCommit(String commit, ClientRepoState ctx) {
return ctx.query().commits().id(commit);
}
private Uni getBlob(Tree tree, ClientRepoState ctx) {
final var entry = tree.getValues().entrySet().stream()
.filter(e -> blobName.contains(e.getValue().getName()))
.map(e -> e.getValue().getBlob())
.collect(Collectors.toList());
if(!entry.isEmpty() || !matchCriteria.isEmpty()) {
return ctx.query().blobs()
.id(tree.getId(), entry, matchCriteria)
.onItem().transform(blobs -> ImmutableBlobAndTree.builder().blob(blobs).tree(tree).build());
}
return Uni.createFrom().item(ImmutableBlobAndTree.builder().tree(tree).build());
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy