SemanticAnnotationDAO.java

package de.dlr.shepard.context.semantic.daos;

import static de.dlr.shepard.common.util.CypherDslHelper.internalIdIs;
import static de.dlr.shepard.common.util.CypherDslHelper.notDeleted;

import de.dlr.shepard.common.neo4j.daos.GenericDAO;
import de.dlr.shepard.common.neo4j.entities.Annotatable;
import de.dlr.shepard.common.util.Constants;
import de.dlr.shepard.common.util.CypherQueryHelper;
import de.dlr.shepard.common.util.CypherQueryHelper.Neighborhood;
import de.dlr.shepard.context.semantic.entities.SemanticAnnotation;
import jakarta.enterprise.context.RequestScoped;
import jakarta.ws.rs.InternalServerErrorException;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.StreamSupport;
import org.neo4j.cypherdsl.core.Cypher;

@RequestScoped
public class SemanticAnnotationDAO extends GenericDAO<SemanticAnnotation> {

  public List<SemanticAnnotation> findAllSemanticAnnotationsByNeo4jId(long entityId) {
    String query;
    query = "MATCH (e)-[ha:has_annotation]->(a:SemanticAnnotation) WHERE ID(e)=%d WITH a %s".formatted(
        entityId,
        CypherQueryHelper.getReturnPart("a", Neighborhood.OUTGOING)
      );
    var queryResult = findByQuery(query, Collections.emptyMap());
    return StreamSupport.stream(queryResult.spliterator(), false).toList();
  }

  public List<SemanticAnnotation> findAllSemanticAnnotationsByShepardId(long shepardId) {
    String query;
    query = String.format(
      "MATCH (e)-[ha:has_annotation]->(a:SemanticAnnotation) WHERE e." + Constants.SHEPARD_ID + "=%d WITH a %s",
      shepardId,
      CypherQueryHelper.getReturnPart("a", Neighborhood.OUTGOING)
    );
    var queryResult = findByQuery(query, Collections.emptyMap());
    return StreamSupport.stream(queryResult.spliterator(), false).toList();
  }

  public Optional<Annotatable> findAnnotatableByNeo4jIdNotDeleted(long entityId) {
    var node = Cypher.anyNode().named("n");
    var relatedTo = Cypher.anyNode();
    var rels = node.relationshipTo(relatedTo);
    var query = Cypher.match(node.where(notDeleted(node).and(internalIdIs(node, entityId))), rels, relatedTo)
      .returning(node, rels, relatedTo)
      .build()
      .getCypher();
    var result = session.query(query, Map.of());
    var optionalResult = StreamSupport.stream(result.spliterator(), false).findFirst();
    try {
      return optionalResult.map(resultMap -> (Annotatable) resultMap.get("n"));
    } catch (ClassCastException e) {
      throw new InternalServerErrorException("Requested entity does not implement Annotatable interface!");
    }
  }

  public void saveAnnotatable(Annotatable annotatable) {
    session.save(annotatable);
  }

  @Override
  public Class<SemanticAnnotation> getEntityType() {
    return SemanticAnnotation.class;
  }
}