Skip to content

Commit

Permalink
Merge pull request #454 from SSHOC/bugfix/SSHOC-423_concepts_codes_en…
Browse files Browse the repository at this point in the history
…coding

Bugfix/sshoc 423 concepts codes encoding
  • Loading branch information
KlausIllmayer authored Aug 14, 2024
2 parents cf88472 + 6a754d7 commit 2f390dd
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,32 @@
import eu.sshopencloud.marketplace.dto.vocabularies.ConceptCore;
import eu.sshopencloud.marketplace.dto.vocabularies.RelatedConceptCore;
import eu.sshopencloud.marketplace.dto.vocabularies.VocabularyId;
import eu.sshopencloud.marketplace.model.vocabularies.*;
import eu.sshopencloud.marketplace.model.vocabularies.Concept;
import eu.sshopencloud.marketplace.model.vocabularies.ConceptId;
import eu.sshopencloud.marketplace.model.vocabularies.ConceptRelatedConcept;
import eu.sshopencloud.marketplace.model.vocabularies.Vocabulary;
import eu.sshopencloud.marketplace.repositories.vocabularies.ConceptRepository;
import eu.sshopencloud.marketplace.validators.ValidationException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.BeanPropertyBindingResult;
import org.springframework.validation.Errors;
import org.springframework.web.util.UriUtils;

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Optional;


@Service
@Transactional
@RequiredArgsConstructor
@Slf4j
public class ConceptFactory {

private final ConceptRepository conceptRepository;
Expand Down Expand Up @@ -62,14 +69,13 @@ public Concept create(ConceptCore conceptCore, Vocabulary vocabulary, String cod

concept.setDefinition(conceptCore.getDefinition());

if (StringUtils.isBlank(conceptCore.getUri())) {
concept.setUri(vocabulary.getNamespace() + concept.getCode());
if (StringUtils.isNotBlank(conceptCore.getUri()) &&
!StringUtils.equals(conceptCore.getUri(), vocabulary.getNamespace() + concept.getCode()) &&
!StringUtils.equals(conceptCore.getUri(), vocabulary.getNamespace() + URLEncoder.encode(concept.getCode(), StandardCharsets.UTF_8))) {
errors.rejectValue("uri", "field.invalid",
"Uri is not consistent with vocabulary namespace and concept code.");
} else {
if (conceptCore.getUri().equals(vocabulary.getNamespace() + concept.getCode())) {
concept.setUri(conceptCore.getUri());
} else {
errors.rejectValue("uri", "field.invalid", "Uri is not consistent with vocabulary namespace and concept code.");
}
concept.setUri(vocabulary.getNamespace() + (isURLEncoded(concept.getCode()) ? concept.getCode() : UriUtils.encode(concept.getCode(), StandardCharsets.UTF_8)));
}

if (errors.hasErrors())
Expand All @@ -78,6 +84,20 @@ public Concept create(ConceptCore conceptCore, Vocabulary vocabulary, String cod
return concept;
}

private boolean isURLEncoded(String code) {
try {
String decoded = UriUtils.decode(code, StandardCharsets.UTF_8);
String reEncoded = UriUtils.encode(decoded, StandardCharsets.UTF_8);
if (code.equals(reEncoded)) {
return true;
}
} catch (IllegalArgumentException e) {
log.debug(e.getMessage());
return false;
}
return false;
}

public List<ConceptRelatedConcept> createConceptRelations(Concept concept, List<RelatedConceptCore> relatedConcepts) throws ValidationException {

BeanPropertyBindingResult errors = new BeanPropertyBindingResult(relatedConcepts, "Concept");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ public void shouldCreateNewCandidateConcept() throws Exception {
.andExpect(jsonPath("$.code", is("New Candidate")))
.andExpect(jsonPath("$.label", is("New candidate concept")))
.andExpect(jsonPath("$.candidate", is(true)))
.andExpect(jsonPath("$.uri", is("http://purl.org/ontology/bibo/New Candidate")))
.andExpect(jsonPath("$.uri", is("http://purl.org/ontology/bibo/New%20Candidate")))
.andExpect(jsonPath("$.relatedConcepts[0].code", is("Journal")))
.andExpect(jsonPath("$.relatedConcepts[1].code", is("Book")))
.andExpect(jsonPath("$.relatedConcepts[2].code", is("Conference")));
Expand Down Expand Up @@ -447,7 +447,7 @@ public void shouldDeleteAndCreateConcept() throws Exception {
.andExpect(jsonPath("$.code", is("New Candidate")))
.andExpect(jsonPath("$.label", is("New candidate concept")))
.andExpect(jsonPath("$.candidate", is(true)))
.andExpect(jsonPath("$.uri", is("http://purl.org/ontology/bibo/New Candidate")))
.andExpect(jsonPath("$.uri", is("http://purl.org/ontology/bibo/New%20Candidate")))
.andExpect(jsonPath("$.relatedConcepts[0].code", is("Journal")))
.andExpect(jsonPath("$.relatedConcepts[1].code", is("Conference")));

Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
package eu.sshopencloud.marketplace.util;

import lombok.experimental.UtilityClass;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;


@UtilityClass
public class MatcherUtils {

public Matcher<Number> equalValue(long value) {
public static Matcher<Number> equalValue(long value) {
return new TypeSafeMatcher<>() {
@Override
protected boolean matchesSafely(Number item) {
Expand Down

0 comments on commit 2f390dd

Please sign in to comment.