Skip to content

Commit

Permalink
Merge branch 'main' into snyk-upgrade-4fbbb693df8d96642730c9bd38cd4ead
Browse files Browse the repository at this point in the history
  • Loading branch information
wistefan authored Aug 1, 2024
2 parents 84a7b47 + 83b678f commit 2e88bc2
Show file tree
Hide file tree
Showing 8 changed files with 697 additions and 638 deletions.
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@
<version.io.kokuwa.micronaut.codegen>2.2.1</version.io.kokuwa.micronaut.codegen>

<!-- json -->
<version.com.google.guava>33.0.0-jre</version.com.google.guava>
<version.com.github.jsonld-java>0.13.4</version.com.github.jsonld-java>
<version.com.google.guava>33.2.0-jre</version.com.google.guava>
<version.com.github.jsonld-java>0.13.6</version.com.github.jsonld-java>
<version.com.apicatalog.titanium-json-ld>1.4.0</version.com.apicatalog.titanium-json-ld>
<version.org.glassfish.jakarta-json>2.0.1</version.org.glassfish.jakarta-json>
<version.de.grundid.opendatalab.geojson-jackson>1.14</version.de.grundid.opendatalab.geojson-jackson>
Expand Down
366 changes: 187 additions & 179 deletions src/main/java/org/fiware/mintaka/context/LdContextCache.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,184 +39,192 @@
@RequiredArgsConstructor
public class LdContextCache {

private final ContextProperties contextProperties;

private URL coreContextUrl;
private Object coreContext;

private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

@PostConstruct
public void initDefaultContext() {
try {
coreContextUrl = new URL(contextProperties.getDefaultUrl());
coreContext = JsonUtils.fromURLJavaNet(coreContextUrl);
} catch (IOException e) {
throw new ContextRetrievalException("Invalid core context configured.", e, contextProperties.getDefaultUrl());
}
}

/**
* Get context from the given url. Will be cached.
*
* @param url - url to get the context from
* @return the context
*/
@Cacheable
public Object getContextFromURL(URL url) {
try {
if (url.toURI().equals(coreContextUrl.toURI())) {
return coreContext;
}
return JsonUtils.fromURLJavaNet(url);
} catch (IOException e) {
throw new ContextRetrievalException(String.format("Was not able to retrieve context from %s.", url), e, url.toString());
} catch (URISyntaxException uriSyntaxException) {
throw new IllegalArgumentException(String.format("Received an invalid url: %s", url), uriSyntaxException);
}
}

/**
* Expand all given attributes with the given contexts.
*
* @param stringsToExpand - strings to be expanded
* @param contextUrls - urls of contexts to be used for expansion
* @return list of expanded attribute-ids
*/
public List<String> expandStrings(List<String> stringsToExpand, List<URL> contextUrls) {
Map contextMap = (Map) getContext(contextUrls);

return stringsToExpand.stream()
.map(stringToExpand -> expandString(stringToExpand, contextMap))
.collect(Collectors.toList());
}

/**
* Expand the given string with the provided contexts.
*
* @param stringToExpand - string to be expanded
* @param contextUrls - urls of contexts to be used for expansion
* @return the expanded attribute-id
*/
public String expandString(String stringToExpand, List<URL> contextUrls) {
return expandString(stringToExpand, (Map) getContext(contextUrls));
}

private String expandString(String stringToExpand, Map contextMap) {
String jsonLdString = getJsonLdString(stringToExpand);
try {
Map jsonLdObject = (Map) JsonUtils.fromString(jsonLdString);
jsonLdObject.put(JsonLdConsts.CONTEXT, contextMap.get(JsonLdConsts.CONTEXT));
return getIdFromJsonLDObject(jsonLdObject);
} catch (IOException e) {
throw new StringExpansionException(String.format("Was not able expand %s.", jsonLdString), e);
}
}

/**
* Retrieve the context as a JsonDocument
*
* @param contextURLs - either be a (URL)String, a URL or a list of urls/urlstrings.
* @return the context
*/
public Document getContextDocument(Object contextURLs) {
try {
Object context = getContext(contextURLs);
return JsonDocument.of(new ByteArrayInputStream(OBJECT_MAPPER.writeValueAsString(context).getBytes(StandardCharsets.UTF_8)));
} catch (JsonLdError | JsonProcessingException e) {
throw new IllegalArgumentException(String.format("No valid context available via %s", contextURLs), e);
}
}

/**
* Get the context from the given object. Should either be a (URL)String, a URL or a list of urls/urlstrings.
* We use the Json-ld-java lib for retrieval, since the titanium lib is not able to combine context objects.
*
* @param contextURLs - either be a (URL)String, a URL or a list of urls/urlstrings.
* @return the context
*/
private Object getContext(Object contextURLs) {
if (contextURLs instanceof List) {
return Map.of(JsonLdConsts.CONTEXT, ((List) contextURLs).stream()
.map(this::getContext)
.map(contextMap -> ((Map<String, Object>) contextMap).get(JsonLdConsts.CONTEXT))
.map(contextObject -> {
// follow potential list-contexts
if (contextObject instanceof List) {
return getContext((List) contextObject);
} else {
return contextObject;
}
})
.flatMap(map -> ((Map<String, Object>) map).entrySet().stream())
.collect(Collectors.toMap(e -> ((Map.Entry<String, Object>) e).getKey(), e -> ((Map.Entry<String, Object>) e).getValue(), (e1, e2) -> e2)));
} else if (contextURLs instanceof URL) {
return getContextFromURL((URL) contextURLs);
} else if (contextURLs instanceof String) {
return getContextFromURL((String) contextURLs);
} else if (contextURLs instanceof URI) {
return getContextFromURL(contextURLs.toString());
}
throw new ContextRetrievalException(String.format("Did not receive a valid context: %s.", contextURLs), contextURLs.toString());
}


/**
* Get the context from the given url
*
* @param urlString - string containing the url
* @return the context
*/
private Object getContextFromURL(String urlString) {
try {
return getContextFromURL(new URL(urlString));
} catch (MalformedURLException e) {
throw new ContextRetrievalException(String.format("Was not able to convert %s to URL.", urlString), e, urlString);
}
}


/**
* Extract the context urls from the link header. CORE_CONTEXT will be automatically added.
*
* @param headerString - content of the link header
* @return list of context urls, will either be only the core context or the core-context + the header context
*/
public List<URL> getContextURLsFromLinkHeader(String headerString) {

Optional<String> linkedContextString = Optional.empty();

if (headerString != null && !headerString.isEmpty() && !headerString.isBlank()) {
linkedContextString = Optional.of(headerString.split(";")[0].replace("<", "").replace(">", ""));
}

return linkedContextString
.map(lCS -> {
try {
return new URL(lCS);
} catch (MalformedURLException e) {
throw new IllegalArgumentException("Context url is invalid.", e);
}
})
.map(url -> List.of(url, coreContextUrl)).orElse(List.of(coreContextUrl));
}

// extract the Id from the expanded object
private String getIdFromJsonLDObject(Map<String, Object> jsonLdObject) {
Map<String, Object> expandedObject = (Map<String, Object>) JsonLdProcessor.expand(jsonLdObject)
.stream()
.findFirst()
.orElseThrow(() -> new StringExpansionException(String.format("Was not able to get an expanded object for %s.", jsonLdObject)));
Set<String> expandedKeys = expandedObject.keySet();
if (expandedKeys.size() != 1) {
throw new StringExpansionException(String.format("Was not able to correctly expand key. Got multiple keys: %s", expandedKeys));
}
return expandedKeys.iterator().next();
}

// create a json object for json-ld api to be used for extending the key.
private String getJsonLdString(String string) {
return String.format("{\"%s\":\"\"}", string);
}
private final ContextProperties contextProperties;

private URL coreContextUrl;
private Object coreContext;

private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

@PostConstruct
public void initDefaultContext() {
try {
coreContextUrl = new URL(contextProperties.getDefaultUrl());
coreContext = JsonUtils.fromURLJavaNet(coreContextUrl);
} catch (IOException e) {
throw new ContextRetrievalException("Invalid core context configured.", e, contextProperties.getDefaultUrl());
}
}

/**
* Get context from the given url. Will be cached.
*
* @param url - url to get the context from
* @return the context
*/
@Cacheable
public Object getContextFromURL(URL url) {
try {
if (url.toURI().equals(coreContextUrl.toURI())) {
return coreContext;
}
return JsonUtils.fromURLJavaNet(url);
} catch (IOException e) {
throw new ContextRetrievalException(String.format("Was not able to retrieve context from %s.", url), e, url.toString());
} catch (URISyntaxException uriSyntaxException) {
throw new IllegalArgumentException(String.format("Received an invalid url: %s", url), uriSyntaxException);
}
}

/**
* Expand all given attributes with the given contexts.
*
* @param stringsToExpand - strings to be expanded
* @param contextUrls - urls of contexts to be used for expansion
* @return list of expanded attribute-ids
*/
public List<String> expandStrings(List<String> stringsToExpand, List<URL> contextUrls) {
Map contextMap = (Map) getContext(contextUrls);

return stringsToExpand.stream()
.map(stringToExpand -> expandString(stringToExpand, contextMap))
.collect(Collectors.toList());
}

/**
* Expand the given string with the provided contexts.
*
* @param stringToExpand - string to be expanded
* @param contextUrls - urls of contexts to be used for expansion
* @return the expanded attribute-id
*/
public String expandString(String stringToExpand, List<URL> contextUrls) {
return expandString(stringToExpand, (Map) getContext(contextUrls));
}

private String expandString(String stringToExpand, Map contextMap) {
String jsonLdString = getJsonLdString(stringToExpand);
try {
Map jsonLdObject = (Map) JsonUtils.fromString(jsonLdString);
jsonLdObject.put(JsonLdConsts.CONTEXT, contextMap.get(JsonLdConsts.CONTEXT));
return getIdFromJsonLDObject(jsonLdObject);
} catch (IOException e) {
throw new StringExpansionException(String.format("Was not able expand %s.", jsonLdString), e);
}
}

/**
* Retrieve the context as a JsonDocument
*
* @param contextURLs - either be a (URL)String, a URL or a list of urls/urlstrings.
* @return the context
*/
public Document getContextDocument(Object contextURLs) {
try {
Object context = getContext(contextURLs);
return JsonDocument.of(new ByteArrayInputStream(OBJECT_MAPPER.writeValueAsString(context).getBytes(StandardCharsets.UTF_8)));
} catch (JsonLdError | JsonProcessingException e) {
throw new IllegalArgumentException(String.format("No valid context available via %s", contextURLs), e);
}
}

/**
* Get the context from the given object. Should either be a (URL)String, a URL or a list of urls/urlstrings.
* We use the Json-ld-java lib for retrieval, since the titanium lib is not able to combine context objects.
*
* @param contextURLs - either be a (URL)String, a URL or a list of urls/urlstrings.
* @return the context
*/
private Object getContext(Object contextURLs) {
if (contextURLs instanceof List) {
var m = Map.of(JsonLdConsts.CONTEXT, ((List) contextURLs).stream()
.map(url -> getContext(url))
.map(contextMap -> ((Map<String, Object>) contextMap).get(JsonLdConsts.CONTEXT))
.map(contextObject -> {
// follow potential list-contexts
if (contextObject instanceof List) {
return getContext((List) contextObject);
}
return contextObject;
})
.map(co -> {
if (co instanceof Map<?, ?> coMap) {
if (coMap.containsKey(JsonLdConsts.CONTEXT)) {
return coMap.get(JsonLdConsts.CONTEXT);
}
}
return co;
})
.flatMap(map -> ((Map<String, Object>) map).entrySet().stream())
.collect(Collectors.toMap(e -> ((Map.Entry<String, Object>) e).getKey(), e -> ((Map.Entry<String, Object>) e).getValue(), (e1, e2) -> e2)));
return m;
} else if (contextURLs instanceof URL) {
return getContextFromURL((URL) contextURLs);
} else if (contextURLs instanceof String) {
return getContextFromURL((String) contextURLs);
} else if (contextURLs instanceof URI) {
return getContextFromURL(contextURLs.toString());
}
throw new ContextRetrievalException(String.format("Did not receive a valid context: %s.", contextURLs), contextURLs.toString());
}


/**
* Get the context from the given url
*
* @param urlString - string containing the url
* @return the context
*/
private Object getContextFromURL(String urlString) {
try {
return getContextFromURL(new URL(urlString));
} catch (MalformedURLException e) {
throw new ContextRetrievalException(String.format("Was not able to convert %s to URL.", urlString), e, urlString);
}
}


/**
* Extract the context urls from the link header. CORE_CONTEXT will be automatically added.
*
* @param headerString - content of the link header
* @return list of context urls, will either be only the core context or the core-context + the header context
*/
public List<URL> getContextURLsFromLinkHeader(String headerString) {

Optional<String> linkedContextString = Optional.empty();

if (headerString != null && !headerString.isEmpty() && !headerString.isBlank()) {
linkedContextString = Optional.of(headerString.split(";")[0].replace("<", "").replace(">", ""));
}

return linkedContextString
.map(lCS -> {
try {
return new URL(lCS);
} catch (MalformedURLException e) {
throw new IllegalArgumentException("Context url is invalid.", e);
}
})
.map(url -> List.of(url, coreContextUrl)).orElse(List.of(coreContextUrl));
}

// extract the Id from the expanded object
private String getIdFromJsonLDObject(Map<String, Object> jsonLdObject) {
Map<String, Object> expandedObject = (Map<String, Object>) JsonLdProcessor.expand(jsonLdObject)
.stream()
.findFirst()
.orElseThrow(() -> new StringExpansionException(String.format("Was not able to get an expanded object for %s.", jsonLdObject)));
Set<String> expandedKeys = expandedObject.keySet();
if (expandedKeys.size() != 1) {
throw new StringExpansionException(String.format("Was not able to correctly expand key. Got multiple keys: %s", expandedKeys));
}
return expandedKeys.iterator().next();
}

// create a json object for json-ld api to be used for extending the key.
private String getJsonLdString(String string) {
return String.format("{\"%s\":\"\"}", string);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ public void serialize(EntityTemporalVO value, JsonGenerator gen, SerializerProvi
throw new JacksonConversionException("Was not able to deserialize the retrieved object.", e);
} catch (JsonLdError jsonLdError) {
log.error("Was not able to deserialize object", jsonLdError);
throw new JacksonConversionException(jsonLdError.getMessage());
throw new JacksonConversionException(jsonLdError.getMessage());
}
}

Expand Down
Loading

0 comments on commit 2e88bc2

Please sign in to comment.