diff --git a/pom.xml b/pom.xml index 0f7d8dc5..fc619f85 100644 --- a/pom.xml +++ b/pom.xml @@ -46,6 +46,12 @@ + + + commons-codec + commons-codec + 1.16.0 + org.springframework.boot spring-boot-starter-security @@ -64,6 +70,13 @@ lombok true + + + junit + junit + 4.13.2 + test + org.springframework.boot spring-boot-starter-test diff --git a/src/main/java/au/org/aodn/esindexer/service/StacCollectionMapperServiceImpl.java b/src/main/java/au/org/aodn/esindexer/service/StacCollectionMapperServiceImpl.java index ae7467ff..7436f910 100644 --- a/src/main/java/au/org/aodn/esindexer/service/StacCollectionMapperServiceImpl.java +++ b/src/main/java/au/org/aodn/esindexer/service/StacCollectionMapperServiceImpl.java @@ -5,6 +5,7 @@ import au.org.aodn.esindexer.model.*; import au.org.aodn.esindexer.utils.BBoxUtils; import au.org.aodn.esindexer.utils.GeometryUtils; +import au.org.aodn.esindexer.utils.StringUtil; import au.org.aodn.esindexer.utils.TemporalUtils; import au.org.aodn.metadata.iso19115_3_2018.*; import jakarta.xml.bind.JAXBElement; @@ -257,11 +258,11 @@ String mapTitle(MDMetadataType source) { // TODO: Null or empty check AbstractCitationType ac = i.getCitation().getAbstractCitation().getValue(); if(ac instanceof CICitationType2 type2) { - return type2.getTitle().getCharacterString().getValue().toString(); + return StringUtil.toUTF8String(type2.getTitle().getCharacterString().getValue().toString()); } else if(ac instanceof CICitationType type1) { // Backward compatible - type1.getTitle().getCharacterString().getValue().toString(); + return StringUtil.toUTF8String(type1.getTitle().getCharacterString().getValue().toString()); } } } @@ -273,10 +274,10 @@ protected List> mapThemesConcepts(MDKeywordsPropertyType des descriptiveKeyword.getMDKeywords().getKeyword().forEach(keyword -> { if (keyword != null) { if (keyword.getCharacterString().getValue() instanceof AnchorType value) { - keywords.add(Map.of("id", value.getValue(), - "url", value.getHref())); + keywords.add(Map.of("id", StringUtil.toUTF8String(value.getValue()), + "url", StringUtil.toUTF8String(value.getHref()))); } else { - keywords.add(Map.of("id", keyword.getCharacterString().getValue().toString())); + keywords.add(Map.of("id", StringUtil.toUTF8String(keyword.getCharacterString().getValue().toString()))); } } }); @@ -290,12 +291,12 @@ protected String mapThemesTitle(MDKeywordsPropertyType descriptiveKeyword, Strin CharacterStringPropertyType titleString = thesaurusNameType2.getTitle(); if (titleString != null && titleString.getCharacterString().getValue() instanceof AnchorType value) { if (value.getValue() != null) { - return value.getValue(); + return StringUtil.toUTF8String(value.getValue()); } else { return ""; } } else if (titleString != null && titleString.getCharacterString().getValue() instanceof String value) { - return value; + return StringUtil.toUTF8String(value); } } logger.debug("Unable to find themes' title for metadata record: " + uuid); @@ -309,12 +310,12 @@ protected String mapThemesDescription(MDKeywordsPropertyType descriptiveKeyword, CharacterStringPropertyType titleString = thesaurusNameType2.getTitle(); if (titleString != null && titleString.getCharacterString().getValue() instanceof AnchorType value) { if (value.getTitleAttribute() != null) { - return value.getTitleAttribute(); + return StringUtil.toUTF8String(value.getTitleAttribute()); } else { return ""; } } else if (titleString != null && titleString.getCharacterString().getValue() instanceof String value) { - return thesaurusNameType2.getAlternateTitle().stream().map(CharacterStringPropertyType::getCharacterString).map(JAXBElement::getValue).map(Object::toString).collect(Collectors.joining(", ")); + return StringUtil.toUTF8String(thesaurusNameType2.getAlternateTitle().stream().map(CharacterStringPropertyType::getCharacterString).map(JAXBElement::getValue).map(Object::toString).collect(Collectors.joining(", "))); } } logger.debug("Unable to find themes' description for metadata record: " + uuid); @@ -325,7 +326,7 @@ protected String mapThemesScheme(MDKeywordsPropertyType descriptiveKeyword, Stri AbstractCitationPropertyType abstractCitationPropertyType = descriptiveKeyword.getMDKeywords().getThesaurusName(); if (abstractCitationPropertyType != null) { if (descriptiveKeyword.getMDKeywords().getType() != null) { - return descriptiveKeyword.getMDKeywords().getType().getMDKeywordTypeCode().getCodeListValue(); + return StringUtil.toUTF8String(descriptiveKeyword.getMDKeywords().getType().getMDKeywordTypeCode().getCodeListValue()); } else { return ""; } @@ -370,7 +371,7 @@ List mapLinks(MDMetadataType source) { linkModel.setType(Objects.equals(ciOnlineResource.getProtocol().getCharacterString().getValue().toString(), "WWW:LINK-1.0-http--link") ? "text/html" : ""); linkModel.setHref(ciOnlineResource.getLinkage().getCharacterString().getValue().toString()); linkModel.setRel(AppConstants.RECOMMENDED_LINK_REL_TYPE); - linkModel.setTitle(ciOnlineResource.getName() != null ? ciOnlineResource.getName().getCharacterString().getValue().toString() : null); + linkModel.setTitle(ciOnlineResource.getName() != null ? StringUtil.toUTF8String(ciOnlineResource.getName().getCharacterString().getValue().toString()) : null); results.add(linkModel); } } @@ -393,7 +394,7 @@ String mapLicense(MDMetadataType source) { legalConstraintsType.getOtherConstraints().forEach(otherConstraints -> { for (String potentialKey : potentialKeys) { if (otherConstraints.getCharacterString() != null && otherConstraints.getCharacterString().getValue().toString().toLowerCase().contains(potentialKey)) { - licenses.add(otherConstraints.getCharacterString().getValue().toString()); + licenses.add(StringUtil.toUTF8String(otherConstraints.getCharacterString().getValue().toString())); } } }); @@ -403,7 +404,7 @@ String mapLicense(MDMetadataType source) { legalConstraintsType.getReference().forEach(reference -> { if (reference.getAbstractCitation().getValue() instanceof CICitationType2 ciCitationType2) { if (ciCitationType2.getTitle() != null) { - licenses.add(ciCitationType2.getTitle().getCharacterString().getValue().toString()); + licenses.add(StringUtil.toUTF8String(ciCitationType2.getTitle().getCharacterString().getValue().toString())); } } }); @@ -502,23 +503,23 @@ List mapContacts(MDMetadataType source) { protected String mapContactsRole(CIResponsibilityType2 ciResponsibility) { CodeListValueType roleCode = ciResponsibility.getRole().getCIRoleCode(); - if (roleCode != null) { return roleCode.getCodeListValue(); } else { return ""; } + if (roleCode != null) { return StringUtil.toUTF8String(roleCode.getCodeListValue()); } else { return ""; } } protected String mapContactsOrganization(AbstractCIPartyPropertyType2 party) { String organisationString = party.getAbstractCIParty().getValue().getName().getCharacterString().getValue().toString(); - if (organisationString != null) { return organisationString; } else { return ""; } + if (organisationString != null) { return StringUtil.toUTF8String(organisationString); } else { return ""; } } protected String mapContactsName(CIIndividualPropertyType2 individual) { CharacterStringPropertyType nameString = individual.getCIIndividual().getName(); - if (nameString != null) { return individual.getCIIndividual().getName().getCharacterString().getValue().toString(); } else { return ""; } + if (nameString != null) { return StringUtil.toUTF8String(individual.getCIIndividual().getName().getCharacterString().getValue().toString()); } else { return ""; } } protected String mapContactsPosition(CIIndividualPropertyType2 individual) { CharacterStringPropertyType positionString = individual.getCIIndividual().getPositionName(); - if (positionString != null) { return individual.getCIIndividual().getPositionName().getCharacterString().getValue().toString(); } else { return ""; } + if (positionString != null) { return StringUtil.toUTF8String(individual.getCIIndividual().getPositionName().getCharacterString().getValue().toString()); } else { return ""; } } protected Map mapContactsAddress(CIAddressPropertyType2 address) { @@ -527,28 +528,28 @@ protected Map mapContactsAddress(CIAddressPropertyType2 address) address.getCIAddress().getDeliveryPoint().forEach(deliveryPoint -> { String deliveryPointString = deliveryPoint.getCharacterString().getValue().toString(); - deliveryPoints.add(deliveryPointString != null ? deliveryPointString : ""); + deliveryPoints.add(deliveryPointString != null ? StringUtil.toUTF8String(deliveryPointString) : ""); }); addressItem.put("deliveryPoint", deliveryPoints); CharacterStringPropertyType cityString = address.getCIAddress().getCity(); - addressItem.put("city", cityString != null ? cityString.getCharacterString().getValue().toString() : ""); + addressItem.put("city", cityString != null ? StringUtil.toUTF8String(cityString.getCharacterString().getValue().toString()) : ""); CharacterStringPropertyType administrativeAreaString = address.getCIAddress().getAdministrativeArea(); - addressItem.put("administrativeArea", administrativeAreaString != null ? administrativeAreaString.getCharacterString().getValue().toString() : ""); + addressItem.put("administrativeArea", administrativeAreaString != null ? StringUtil.toUTF8String(administrativeAreaString.getCharacterString().getValue().toString()) : ""); CharacterStringPropertyType postalCodeString = address.getCIAddress().getPostalCode(); - addressItem.put("postalCode", postalCodeString != null ? postalCodeString.getCharacterString().getValue().toString() : ""); + addressItem.put("postalCode", postalCodeString != null ? StringUtil.toUTF8String(postalCodeString.getCharacterString().getValue().toString()) : ""); CharacterStringPropertyType countryString = address.getCIAddress().getCountry(); - addressItem.put("country", countryString != null ? countryString.getCharacterString().getValue().toString() : ""); + addressItem.put("country", countryString != null ? StringUtil.toUTF8String(countryString.getCharacterString().getValue().toString()) : ""); return addressItem; } protected String mapContactsEmail(CharacterStringPropertyType electronicMailAddress) { if (electronicMailAddress != null) { - return electronicMailAddress.getCharacterString().getValue().toString(); + return StringUtil.toUTF8String(electronicMailAddress.getCharacterString().getValue().toString()); } else { return ""; } @@ -558,10 +559,10 @@ protected Map mapContactsPhone(CITelephonePropertyType2 phone) { Map phoneItem = new HashMap<>(); CharacterStringPropertyType phoneString = phone.getCITelephone().getNumber(); - phoneItem.put("value", phoneString != null ? phoneString.getCharacterString().getValue().toString() : ""); + phoneItem.put("value", phoneString != null ? StringUtil.toUTF8String(phoneString.getCharacterString().getValue().toString()) : ""); CodeListValueType phoneCode = phone.getCITelephone().getNumberType().getCITelephoneTypeCode(); - phoneItem.put("roles", phoneCode != null ? phoneCode.getCodeListValue() : ""); + phoneItem.put("roles", phoneCode != null ? StringUtil.toUTF8String(phoneCode.getCodeListValue()) : ""); return phoneItem; } @@ -570,13 +571,13 @@ protected Map mapContactsOnlineResource(CIOnlineResourceProperty Map onlineResourceItem = new HashMap<>(); CharacterStringPropertyType linkString = onlineResource.getCIOnlineResource().getLinkage(); - onlineResourceItem.put("href", linkString != null ? linkString.getCharacterString().getValue().toString() : ""); + onlineResourceItem.put("href", linkString != null ? StringUtil.toUTF8String(linkString.getCharacterString().getValue().toString()) : ""); CharacterStringPropertyType resourceNameString = onlineResource.getCIOnlineResource().getName(); - onlineResourceItem.put("title", resourceNameString != null ? resourceNameString.getCharacterString().getValue().toString() : ""); + onlineResourceItem.put("title", resourceNameString != null ? StringUtil.toUTF8String(resourceNameString.getCharacterString().getValue().toString()) : ""); CharacterStringPropertyType linkTypeString = onlineResource.getCIOnlineResource().getProtocol(); - onlineResourceItem.put("type", linkTypeString != null ? linkTypeString.getCharacterString().getValue().toString() : ""); + onlineResourceItem.put("type", linkTypeString != null ? StringUtil.toUTF8String(linkTypeString.getCharacterString().getValue().toString()) : ""); return onlineResourceItem; } @@ -612,7 +613,7 @@ protected List mapLanguages(MDMetadataType source) { protected String mapLanguagesCode(MDDataIdentificationType i) { try { - return i.getDefaultLocale().getPTLocale().getValue().getLanguage().getLanguageCode().getCodeListValue(); + return StringUtil.toUTF8String(i.getDefaultLocale().getPTLocale().getValue().getLanguage().getLanguageCode().getCodeListValue()); } catch (NullPointerException e) { return null; } @@ -646,8 +647,10 @@ protected R createGeometryItems( .map(AbstractEXGeographicExtentPropertyType::getAbstractEXGeographicExtent) .filter(m -> m.getValue() instanceof EXBoundingPolygonType || m.getValue() instanceof EXGeographicBoundingBoxType) .map(m -> { - if (m.getValue() instanceof EXBoundingPolygonType) { - return (EXBoundingPolygonType) m.getValue(); + if (m.getValue() instanceof EXBoundingPolygonType exBoundingPolygonType) { + if (!exBoundingPolygonType.getPolygon().isEmpty() && exBoundingPolygonType.getPolygon().get(0).getAbstractGeometry() != null) { + return exBoundingPolygonType; + } } else if (m.getValue() instanceof EXGeographicBoundingBoxType) { return (EXGeographicBoundingBoxType) m.getValue(); } diff --git a/src/main/java/au/org/aodn/esindexer/utils/StringUtil.java b/src/main/java/au/org/aodn/esindexer/utils/StringUtil.java new file mode 100644 index 00000000..6ae19684 --- /dev/null +++ b/src/main/java/au/org/aodn/esindexer/utils/StringUtil.java @@ -0,0 +1,10 @@ +package au.org.aodn.esindexer.utils; + +import java.nio.charset.StandardCharsets; + +public class StringUtil { + // Static method to convert to UTF-8 String + public static String toUTF8String(String input) { + return new String(input.getBytes(StandardCharsets.UTF_8)); + } +} diff --git a/src/test/StringUtilTest.java b/src/test/StringUtilTest.java new file mode 100644 index 00000000..9e45f56b --- /dev/null +++ b/src/test/StringUtilTest.java @@ -0,0 +1,27 @@ +import au.org.aodn.esindexer.utils.StringUtil; + +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class StringUtilTest { + @Test + public void testToUTF8String_withAsciiString() { + String asciiString = "Hello World"; + String result = StringUtil.toUTF8String(asciiString); + assertEquals(asciiString, result, "The UTF-8 conversion of an ASCII string should not change the string"); + } + + @Test + public void testToUTF8String_withFrenchCharacters() { + String frenchString = "Bonjour le monde! Ça va?"; + String result = StringUtil.toUTF8String(frenchString); + assertEquals(frenchString, result, "The UTF-8 conversion of a string with French characters should not change the string"); + } + + @Test + public void testToUTF8String_withDegreeSign() { + String stringWithDegreeSign = "Temperature: 25°C"; + String result = StringUtil.toUTF8String(stringWithDegreeSign); + assertEquals(stringWithDegreeSign, result, "The UTF-8 conversion of a string with a degree sign should not change the string"); + } +}