diff --git a/src/main/java/tla/backend/api/ApiController.java b/src/main/java/tla/backend/api/ApiController.java index 8c857ac3..04a5e8f9 100644 --- a/src/main/java/tla/backend/api/ApiController.java +++ b/src/main/java/tla/backend/api/ApiController.java @@ -1,20 +1,27 @@ package tla.backend.api; import java.io.IOException; +import java.util.List; import java.util.Map; import java.util.stream.Collectors; +import java.util.ArrayList; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.info.BuildProperties; import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; import tla.backend.es.model.Metadata; +import tla.backend.es.repo.LemmaRepo; import tla.backend.service.MetadataService; +import tla.backend.api.LemmaController; + @RestController @RequestMapping("/") @@ -36,7 +43,7 @@ public class ApiController { public ResponseEntity listEndpoints() { return new ResponseEntity<>( String.join( - "\n", + "
", handlerMapping.getHandlerMethods().keySet().stream().flatMap( mapping -> mapping.getPatternValues().stream() ).sorted().collect( @@ -72,5 +79,4 @@ public ResponseEntity getVersionInfo() throws IOException { statusCode ); } - } diff --git a/src/main/java/tla/backend/api/EntityController.java b/src/main/java/tla/backend/api/EntityController.java index 4bdb6f0f..63075571 100644 --- a/src/main/java/tla/backend/api/EntityController.java +++ b/src/main/java/tla/backend/api/EntityController.java @@ -61,7 +61,23 @@ public ResponseEntity> get(@PathVar log.error("could not find entity {}", id); throw new ObjectNotFoundException(id, this.getService().getModelClass().getSimpleName()); } - + + + /** + * Returns a //TODO a single document and all documents it references. + */ + public Boolean existsById(String id) { + Boolean result = false; + result = getService().existsById(id); + return result; + } + + /** + * Returns the path of the service. + */ + public String getPath() { + return this.getService().getModelPath(); + } @CrossOrigin @RequestMapping( diff --git a/src/main/java/tla/backend/api/TokenController.java b/src/main/java/tla/backend/api/TokenController.java new file mode 100644 index 00000000..20ca4b49 --- /dev/null +++ b/src/main/java/tla/backend/api/TokenController.java @@ -0,0 +1,23 @@ +package tla.backend.api; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import tla.backend.es.model.SentenceEntity; +import tla.backend.service.EntityService; +import tla.backend.service.TokenService; +import tla.domain.dto.SentenceDto; + +@RestController +public class TokenController extends EntityController { + + @Autowired + private TokenService service; + + @Override + public EntityService getService() { + return this.service; + } + +} \ No newline at end of file diff --git a/src/main/java/tla/backend/api/TypeOfIdController.java b/src/main/java/tla/backend/api/TypeOfIdController.java new file mode 100644 index 00000000..6cc199f7 --- /dev/null +++ b/src/main/java/tla/backend/api/TypeOfIdController.java @@ -0,0 +1,74 @@ +package tla.backend.api; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; + + +@RestController +@RequestMapping("/typeofid") +public class TypeOfIdController { + + //Controller Beginn + @Autowired + private LemmaController lemmaController; + + @Autowired + private SentenceController sentenceController; + + @Autowired + private TextController textController; + + @Autowired + private CorpusObjectController corpusObjectController; + + @Autowired + private ThesaurusController thesaurusController; + + @Autowired + private TokenController tokenController; + //Controller Ende + + @Autowired + private RequestMappingHandlerMapping handlerMapping; + + /** + * checks if id exists and returns index name + */ + @RequestMapping( + value = "/{id}", + method = RequestMethod.GET, + consumes = MediaType.ALL_VALUE, + produces = MediaType.ALL_VALUE + ) + public ResponseEntity getTypeOfId(@PathVariable String id){ + //TODO List of Controller aus Vererbung + EntityController [] controllers = { + lemmaController, + sentenceController, + textController, + corpusObjectController, + thesaurusController, + tokenController + }; + for(EntityController controller : controllers) { + System.out.println(controller.existsById(id)); + if(controller.existsById(id)) { + return new ResponseEntity( + controller.getPath(), + HttpStatus.OK + ); + } + } + return new ResponseEntity( + "false", + HttpStatus.OK + ); + } +} diff --git a/src/main/java/tla/backend/es/model/LemmaEntity.java b/src/main/java/tla/backend/es/model/LemmaEntity.java index 1f3877c5..01e2abbc 100644 --- a/src/main/java/tla/backend/es/model/LemmaEntity.java +++ b/src/main/java/tla/backend/es/model/LemmaEntity.java @@ -61,8 +61,8 @@ public class LemmaEntity extends TLAEntity { @JsonAlias({"time_span"}) private TimeSpan timeSpan; - @Field(type = FieldType.Keyword) - private Integer attestedSentencesCount; + @Field(type = FieldType.Integer) + private int attestedSentencesCount; @Singular @Field(type = FieldType.Object) diff --git a/src/main/java/tla/backend/es/model/TextObjectEntity.java b/src/main/java/tla/backend/es/model/TextObjectEntity.java new file mode 100644 index 00000000..11572674 --- /dev/null +++ b/src/main/java/tla/backend/es/model/TextObjectEntity.java @@ -0,0 +1,67 @@ +package tla.backend.es.model; + +import java.util.List; + +import org.springframework.data.elasticsearch.annotations.Document; +import org.springframework.data.elasticsearch.annotations.Field; +import org.springframework.data.elasticsearch.annotations.FieldType; +import org.springframework.data.elasticsearch.annotations.Setting; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.experimental.SuperBuilder; +import tla.backend.es.model.meta.Recursable; +import tla.backend.es.model.meta.UserFriendlyEntity; +import tla.backend.es.model.parts.ObjectPath; +import tla.backend.es.model.parts.Translations; +import tla.domain.dto.TextDto; +import tla.domain.model.meta.BTSeClass; +import tla.domain.model.meta.TLADTO; + +/** + * Text and Subtext model + */ +@Getter +@Setter +@SuperBuilder +@NoArgsConstructor +@BTSeClass("BTSText") +@TLADTO(TextDto.class) +@Document(indexName = "text") +@Setting(settingPath = "/elasticsearch/settings/indices/text.json") +public class TextObjectEntity extends UserFriendlyEntity implements Recursable { + + @Field(type = FieldType.Search_As_You_Type, name = "hash") + private String SUID; + + @Field(type = FieldType.Keyword) + private String corpus; + + @Field(type = FieldType.Object) + private ObjectPath[] paths; + + @Field(type = FieldType.Object) + private List translations; + + @Field(type = FieldType.Object) + private WordCount wordCount; + + @Getter + @Setter + @NoArgsConstructor + public static class WordCount { + @Field(type = FieldType.Integer) + int min = 0; + @Field(type = FieldType.Integer) + int max = 0; + /** + * for compatibility + */ + public WordCount(int count) { + this.min = count; + this.max = count; + } + } + +} diff --git a/src/main/java/tla/backend/es/model/ThsEntryEntity.java b/src/main/java/tla/backend/es/model/ThsEntryEntity.java index 494cefaf..6f60c535 100644 --- a/src/main/java/tla/backend/es/model/ThsEntryEntity.java +++ b/src/main/java/tla/backend/es/model/ThsEntryEntity.java @@ -60,69 +60,9 @@ public class ThsEntryEntity extends UserFriendlyEntity implements Recursable { @Field(type = FieldType.Search_As_You_Type, name = "hash") private String SUID; - @Field(type = FieldType.Object) - private Translations translations; - @Field(type = FieldType.Object) private ObjectPath[] paths; - /** - * Returns translations of a thesaurus entry's label. If no explicit translations exist, this method - * attempts to extract translations from the synonym_group field of the passport. - */ - public Translations getTranslations() { - if (this.translations != null) { - return this.translations; - } else { - return this.extractTranslationsFromPassport(); - } - } - - /** - * Convert multilingual synonyms extracted from passport to {@link Translations} object. - * - * @return {@link Translations} instance or null if no synonyms are in passport - */ - private Translations extractTranslationsFromPassport() { - Translations res = null; - if (this.getPassport() != null) { - List nodes = this.getPassport().extractProperty( - SYNONYMS_PASSPORT_PATH - ); - Map> synonyms = new HashMap<>(); - nodes.stream().filter( - n -> n.containsKey(SYNONYM_LANG_PATH) && n.containsKey(SYNONYM_VALUE_PATH) - ).forEach( - n -> { - List translations = n.extractProperty(SYNONYM_VALUE_PATH).stream().map( - leafNode -> leafNode.getLeafNodeValue() - ).collect( - Collectors.toList() - ); - n.extractProperty(SYNONYM_LANG_PATH).forEach( - langValueNode -> { - String lang = langValueNode.getLeafNodeValue(); - if (synonyms.containsKey(lang)) { - synonyms.get(lang).addAll(translations); - } else { - synonyms.put(lang, new ArrayList(translations)); - } - } - ); - } - ); - try { - res = objectMapper.readValue( - objectMapper.writeValueAsString(synonyms), - Translations.class - ); - } catch (Exception e) { - log.error("something went wrong during synonum extraction", e); - } - } - return res; - } - /** * Returns the timespan represented by a thesaurus entry in the form of a list * of size 2 containing first and last year. diff --git a/src/main/java/tla/backend/es/model/meta/ModelConfig.java b/src/main/java/tla/backend/es/model/meta/ModelConfig.java index c822aeeb..af2d85bd 100644 --- a/src/main/java/tla/backend/es/model/meta/ModelConfig.java +++ b/src/main/java/tla/backend/es/model/meta/ModelConfig.java @@ -256,11 +256,7 @@ protected static ModelMapper initModelMapper() { LemmaEntity::getRevisionState, LemmaDto::setReviewState ); modelMapper.createTypeMap(ThsEntryEntity.class, ThsEntryDto.class) - .addMappings( - m -> m.using(translationsToMapConverter).map( - ThsEntryEntity::getTranslations, ThsEntryDto::setTranslations - ) - ).addMapping( + .addMapping( ThsEntryEntity::getRevisionState, ThsEntryDto::setReviewState ); modelMapper.createTypeMap(TextEntity.class, TextDto.class) diff --git a/src/main/java/tla/backend/es/query/ESQueryBuilder.java b/src/main/java/tla/backend/es/query/ESQueryBuilder.java index ecb577ab..73b5c4fe 100644 --- a/src/main/java/tla/backend/es/query/ESQueryBuilder.java +++ b/src/main/java/tla/backend/es/query/ESQueryBuilder.java @@ -4,8 +4,10 @@ import static org.elasticsearch.index.query.QueryBuilders.idsQuery; import static org.elasticsearch.index.query.QueryBuilders.matchQuery; +import java.util.HashMap; import java.util.LinkedList; import java.util.List; +import java.util.Map; import org.elasticsearch.index.query.BoolQueryBuilder; import org.elasticsearch.search.aggregations.AbstractAggregationBuilder; @@ -42,7 +44,22 @@ public ESQueryBuilder() { this.nativeAggregationBuilders = new LinkedList<>(); this.dependencies = new LinkedList<>(); } - + static final Map criterias; + static { criterias = new HashMap(); + criterias.put("timeSpan.begin_asc", "timeSpan.end_asc"); + criterias.put("timeSpan.begin_desc","timeSpan.end_desc"); + criterias.put("timeSpan.end_asc", "timeSpan.begin_asc"); + criterias.put("timeSpan.end_desc", "timeSpan.begin_desc"); + //TODO Sortierkriterien vom Frontend mappen und nicht direkt auf ES zugreifen lassen + //TODO Mapping for other criterias sortKey,attestedSentenceCounts + }; + + public void setTimeSpanCriterias(String criteria) { + if(criterias.containsKey(criteria)) { + this.sortSpec.addSortingByString(criterias.get(criteria)); + } + } + /** * Put together an actual Elasticsearch query ready for execution. */ diff --git a/src/main/java/tla/backend/es/query/LemmaSearchQueryBuilder.java b/src/main/java/tla/backend/es/query/LemmaSearchQueryBuilder.java index 939df45b..1c31e5df 100644 --- a/src/main/java/tla/backend/es/query/LemmaSearchQueryBuilder.java +++ b/src/main/java/tla/backend/es/query/LemmaSearchQueryBuilder.java @@ -6,7 +6,9 @@ import static org.elasticsearch.index.query.QueryBuilders.termQuery; import static org.elasticsearch.index.query.QueryBuilders.regexpQuery; +import java.util.HashMap; import java.util.List; +import java.util.Map; import org.elasticsearch.index.query.BoolQueryBuilder; import org.elasticsearch.index.query.Operator; @@ -24,229 +26,202 @@ @Getter @ModelClass(LemmaEntity.class) public class LemmaSearchQueryBuilder extends ESQueryBuilder implements MultiLingQueryBuilder { + static List facetSpecs = List.of(FacetSpec.field("wordClass.type", "type"), + FacetSpec.field("wordClass.subtype", "subtype"), FacetSpec.script("script", + "if (doc['id'].value.startsWith('d')) {return 'demotic';} if (!doc['type'].value.equals('root')) {return 'hieratic';}")); + + public void setScript(List