Skip to content

Method: isResourceIdentifier(Object)

1: /*
2: * JOPA
3: * Copyright (C) 2024 Czech Technical University in Prague
4: *
5: * This library is free software; you can redistribute it and/or
6: * modify it under the terms of the GNU Lesser General Public
7: * License as published by the Free Software Foundation; either
8: * version 3.0 of the License, or (at your option) any later version.
9: *
10: * This library is distributed in the hope that it will be useful,
11: * but WITHOUT ANY WARRANTY; without even the implied warranty of
12: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13: * Lesser General Public License for more details.
14: *
15: * You should have received a copy of the GNU Lesser General Public
16: * License along with this library.
17: */
18: package cz.cvut.kbss.ontodriver.rdf4j.util;
19:
20: import cz.cvut.kbss.jopa.datatype.xsd.XsdDatatypeMapper;
21: import cz.cvut.kbss.jopa.datatype.xsd.XsdTemporalMapper;
22: import cz.cvut.kbss.ontodriver.model.Assertion;
23: import cz.cvut.kbss.ontodriver.model.LangString;
24: import cz.cvut.kbss.ontodriver.model.NamedResource;
25: import cz.cvut.kbss.ontodriver.util.IdentifierUtils;
26: import org.eclipse.rdf4j.model.*;
27: import org.eclipse.rdf4j.model.vocabulary.RDF;
28: import org.eclipse.rdf4j.model.vocabulary.XSD;
29: import org.slf4j.LoggerFactory;
30:
31: import java.math.BigDecimal;
32: import java.math.BigInteger;
33: import java.net.URI;
34: import java.time.temporal.TemporalAccessor;
35: import java.time.temporal.TemporalAmount;
36: import java.util.Date;
37:
38: /**
39: * Utility methods for the RDF4J driver.
40: */
41: public final class Rdf4jUtils {
42:
43: private Rdf4jUtils() {
44: // Private constructor
45: }
46:
47: /**
48: * Gets value of the specified literal as the corresponding Java object.
49: * <p>
50: * Primitives are returned boxed. If the type cannot be mapped to a corresponding Java type, it is returned as
51: * {@link cz.cvut.kbss.ontodriver.model.Literal}.
52: *
53: * @param literal RDF literal value
54: * @return Java value corresponding to datatype
55: */
56: public static Object getLiteralValue(Literal literal) {
57: assert literal != null;
58:
59: final IRI datatype = literal.getDatatype();
60: assert datatype != null;
61:
62: if (datatype.equals(RDF.LANGSTRING)) {
63: return new LangString(literal.stringValue(), literal.getLanguage().orElse(null));
64: } else {
65: final cz.cvut.kbss.ontodriver.model.Literal lit = cz.cvut.kbss.ontodriver.model.Literal.from(
66: literal.getLabel(), datatype.stringValue());
67: return XsdDatatypeMapper.getInstance().map(lit).orElse(lit);
68: }
69: }
70:
71: /**
72: * Checks whether the language of the specified literal matches the specified assertion language.
73: * <p>
74: * If the assertion does not specify a language, any literal will match. If the literal is not a string, it matches
75: * as well.
76: *
77: * @param literal Literal to check
78: * @param assertion Assertion
79: * @return {@code false} if the literal is a string literal and its language does not match the one specified by the
80: * assertion, {@code true} otherwise
81: */
82: public static boolean doesLanguageMatch(Literal literal, Assertion assertion) {
83: assert assertion != null;
84: if (!assertion.hasLanguage()) {
85: return true;
86: }
87: final String language = assertion.getLanguage();
88: final IRI datatype = literal.getDatatype();
89: if (datatype.equals(XSD.STRING) || datatype.equals(XSD.NORMALIZEDSTRING) ||
90: datatype.equals(RDF.LANGSTRING)) {
91: return language == null || literal.getLanguage().isEmpty() ||
92: literal.getLanguage().get().equals(language);
93: }
94: return true;
95: }
96:
97: /**
98: * Creates RDF4J literal from the specified value.
99: *
100: * @param value The value to transform
101: * @param language Language to add to string literals, optional
102: * @param vf RDF4J value factory
103: * @return RFD4J Literal
104: * @throws IllegalArgumentException If the type of the value is not supported
105: */
106: public static Literal createLiteral(Object value, String language, ValueFactory vf) {
107: assert value != null;
108:
109: if (value instanceof Integer) {
110: return vf.createLiteral((Integer) value);
111: } else if (value instanceof String) {
112: return language != null ? vf.createLiteral((String) value, language) : vf.createLiteral((String) value);
113: } else if (value instanceof LangString ls) {
114: return ls.getLanguage().isPresent() ? vf.createLiteral(ls.getValue(), ls.getLanguage().get()) :
115: vf.createLiteral(ls.getValue());
116: } else if (value instanceof Byte) {
117: return vf.createLiteral((Byte) value);
118: } else if (value instanceof Short) {
119: return vf.createLiteral((Short) value);
120: } else if (value instanceof Boolean) {
121: return vf.createLiteral((Boolean) value);
122: } else if (value instanceof Float) {
123: return vf.createLiteral((Float) value);
124: } else if (value instanceof Double) {
125: return vf.createLiteral((Double) value);
126: } else if (value instanceof Long) {
127: return vf.createLiteral((Long) value);
128: } else if (value instanceof BigInteger) {
129: return vf.createLiteral((BigInteger) value);
130: } else if (value instanceof BigDecimal) {
131: return vf.createLiteral((BigDecimal) value);
132: } else if (value instanceof Date) {
133: final cz.cvut.kbss.ontodriver.model.Literal ontoLiteral = XsdTemporalMapper.map(((Date) value).toInstant());
134: return createLiteral(vf, ontoLiteral);
135: } else if (value instanceof TemporalAccessor) {
136: final cz.cvut.kbss.ontodriver.model.Literal ontoLiteral = XsdTemporalMapper.map((TemporalAccessor) value);
137: return createLiteral(vf, ontoLiteral);
138: } else if (value instanceof TemporalAmount) {
139: final cz.cvut.kbss.ontodriver.model.Literal ontoLiteral = XsdTemporalMapper.map((TemporalAmount) value);
140: return createLiteral(vf, ontoLiteral);
141: } else if (value.getClass().isEnum()) {
142: return vf.createLiteral(value.toString());
143: } else if (value instanceof cz.cvut.kbss.ontodriver.model.Literal ontoLiteral) {
144: return createLiteral(vf, ontoLiteral);
145: } else {
146: throw new IllegalArgumentException("Unsupported literal type " + value.getClass());
147: }
148: }
149:
150: private static Literal createLiteral(ValueFactory vf, cz.cvut.kbss.ontodriver.model.Literal ontoLiteral) {
151: return vf.createLiteral(ontoLiteral.getLexicalForm(), vf.createIRI(ontoLiteral.getDatatype()));
152: }
153:
154: /**
155: * Checks whether the specified value is a blank node.
156: *
157: * @param value The value to check
158: * @return {@code true} if the value is a blank node, {@code false} otherwise
159: */
160: public static boolean isBlankNode(Value value) {
161: assert value != null;
162: return value instanceof BNode;
163: }
164:
165: /**
166: * Resolves whether the specified value is a resource identifier.
167: * <p>
168: * Only values of supported identifier types are considered identifiers.
169: *
170: * @param value The value to check
171: * @return {@code true} if the value is either a URI or a URL
172: */
173: public static boolean isResourceIdentifier(Object value) {
174:• return value != null && IdentifierUtils.isResourceIdentifierType(value.getClass());
175: }
176:
177: /**
178: * Constructs a RDF4J IRI from the specified java.net.URI.
179: *
180: * @param javaUri The uri to convert
181: * @param factory RDF4J value factory used for the conversion
182: * @return RDF4J IRI
183: */
184: public static IRI toRdf4jIri(java.net.URI javaUri, ValueFactory factory) {
185: return (javaUri != null ? factory.createIRI(javaUri.toString()) : null);
186: }
187:
188: /**
189: * Constructs a RDF4J IRI from identifier of the specified resource.
190: *
191: * @param resource Resource whose identifier to transform
192: * @param factory RDF4J value factory used for the conversion
193: * @return RDF4J IRI
194: * @see #toRdf4jIri(URI, ValueFactory)
195: */
196: public static IRI toRdf4jIri(NamedResource resource, ValueFactory factory) {
197: return toRdf4jIri(resource.getIdentifier(), factory);
198: }
199:
200: public static java.net.URI toJavaUri(Resource resource) {
201: if (resource instanceof BNode) {
202: // We have to check for BNode explicitly, because java's URI treats
203: // BNode's identifier as a valid URI
204: return null;
205: }
206: try {
207: return java.net.URI.create(resource.stringValue());
208: } catch (IllegalArgumentException e) {
209: // This shouldn't happen
210: LoggerFactory.getLogger(Rdf4jUtils.class).error("RDF4J resource is not a valid URI.", e);
211: return null;
212: }
213: }
214: }