View Javadoc
1   package de.dlr.shepard.context.semantic.services;
2   
3   import de.dlr.shepard.common.exceptions.InvalidBodyException;
4   import de.dlr.shepard.common.exceptions.InvalidPathException;
5   import de.dlr.shepard.common.neo4j.entities.Annotatable;
6   import de.dlr.shepard.context.semantic.SemanticRepositoryConnectorFactory;
7   import de.dlr.shepard.context.semantic.daos.SemanticAnnotationDAO;
8   import de.dlr.shepard.context.semantic.entities.SemanticAnnotation;
9   import de.dlr.shepard.context.semantic.entities.SemanticRepository;
10  import de.dlr.shepard.context.semantic.io.SemanticAnnotationIO;
11  import de.dlr.shepard.context.version.daos.VersionableEntityConcreteDAO;
12  import de.dlr.shepard.context.version.entities.VersionableEntity;
13  import io.quarkus.logging.Log;
14  import jakarta.enterprise.context.RequestScoped;
15  import jakarta.inject.Inject;
16  import jakarta.ws.rs.NotFoundException;
17  import java.util.List;
18  
19  @RequestScoped
20  public class SemanticAnnotationService {
21  
22    @Inject
23    SemanticAnnotationDAO semanticAnnotationDAO;
24  
25    @Inject
26    SemanticRepositoryService semanticRepositoryService;
27  
28    @Inject
29    VersionableEntityConcreteDAO versionableEntityConcreteDAO;
30  
31    @Inject
32    SemanticRepositoryConnectorFactory semanticRepositoryConnectorFactory;
33  
34    public List<SemanticAnnotation> getAllAnnotationsByNeo4jId(long entityId) {
35      return semanticAnnotationDAO.findAllSemanticAnnotationsByNeo4jId(entityId);
36    }
37  
38    public List<SemanticAnnotation> getAllAnnotationsByShepardId(long shepardId) {
39      return semanticAnnotationDAO.findAllSemanticAnnotationsByShepardId(shepardId);
40    }
41  
42    /**
43     * Get semantic annotation by neo4j id
44     *
45     * @param id The Neo4j-ID of the semantic annotation
46     * @return Semantic annotation
47     * @throws NotFoundException Semantic annotation is null or deleted
48     */
49    public SemanticAnnotation getAnnotationByNeo4jId(long id) {
50      var annotation = semanticAnnotationDAO.findByNeo4jId(id);
51      if (annotation == null) {
52        String errorMsg = "ID ERROR - Semantic Annotation with id %s is null or deleted".formatted(id);
53        Log.error(errorMsg);
54        throw new NotFoundException(errorMsg);
55      }
56      return annotation;
57    }
58  
59    public SemanticAnnotation createAnnotationByNeo4jId(long entityId, SemanticAnnotationIO annotationIO) {
60      var entity = semanticAnnotationDAO
61        .findAnnotatableByNeo4jIdNotDeleted(entityId)
62        .orElseThrow(InvalidBodyException::new);
63      SemanticAnnotation created = addAnnotationToAnnotatable(entity, annotationIO);
64      semanticAnnotationDAO.saveAnnotatable(entity);
65      return created;
66    }
67  
68    private SemanticAnnotation addAnnotationToAnnotatable(Annotatable entity, SemanticAnnotationIO annotationIO) {
69      SemanticRepository propertyRepository = getRepository(annotationIO.getPropertyRepositoryId());
70      SemanticRepository valueRepository = getRepository(annotationIO.getValueRepositoryId());
71      var propertyName = validateTerm(propertyRepository, annotationIO.getPropertyIRI());
72      var valueName = validateTerm(valueRepository, annotationIO.getValueIRI());
73  
74      SemanticAnnotation toCreate = new SemanticAnnotation();
75      toCreate.setPropertyIRI(annotationIO.getPropertyIRI());
76      toCreate.setValueIRI(annotationIO.getValueIRI());
77      toCreate.setPropertyRepository(propertyRepository);
78      toCreate.setValueRepository(valueRepository);
79      toCreate.setPropertyName(propertyName);
80      toCreate.setValueName(valueName);
81  
82      SemanticAnnotation created = semanticAnnotationDAO.createOrUpdate(toCreate);
83      entity.addAnnotation(created);
84      return created;
85    }
86  
87    public SemanticAnnotation createAnnotationByShepardId(long entityShepardId, SemanticAnnotationIO annotationIO) {
88      VersionableEntity entity = versionableEntityConcreteDAO.findByShepardId(entityShepardId);
89      if (entity == null || entity.isDeleted()) throw new InvalidBodyException("invalid entity");
90      var created = addAnnotationToAnnotatable(entity, annotationIO);
91      versionableEntityConcreteDAO.createOrUpdate(entity);
92      return created;
93    }
94  
95    public boolean deleteAnnotationByNeo4jId(long id) {
96      getAnnotationByNeo4jId(id);
97      return semanticAnnotationDAO.deleteByNeo4jId(id);
98    }
99  
100   private SemanticRepository getRepository(long id) {
101     try {
102       return semanticRepositoryService.getRepository(id);
103     } catch (InvalidPathException ex) {
104       Log.error(ex.getMessage());
105       throw new NotFoundException(ex.getMessage());
106     }
107   }
108 
109   private String validateTerm(SemanticRepository repository, String iri) {
110     var term = semanticRepositoryConnectorFactory
111       .getRepositoryService(repository.getType(), repository.getEndpoint())
112       .getTerm(iri);
113     if (term == null || term.isEmpty()) throw new InvalidBodyException("term could not be found");
114     // Prefer the default label
115     if (term.containsKey("")) return term.get("");
116     // Then prefer the English label
117     if (term.containsKey("en")) return term.get("en");
118     // Fall back to the first label in the list
119     return term.values().iterator().next();
120   }
121 }