diff --git a/CHANGELOG.md b/CHANGELOG.md index 69225e9be..17c7c8b6a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # JOPA - Change Log +## 1.1.0 - 2023-07-28 +- Add support for MEMBER OF in SOQL/Criteria API (Enhancement #176). +- Support language matching in SOQL/Criteria API (Enhancement #161). +- Allow declaring multiple (or no) scan packages (Enhancement #185). +- Support both legacy and new [RDF4J repository config vocabulary](https://rdf4j.org/documentation/reference/configuration/#migrating-old-configurations). +- Dependency update: RDF4J 4.3.4, Jena 4.9.0. ## 1.0.0 - 2023-06-29 - Add support for disabling inference when loading an entity (e.g., when loaded with disable inference query hint) (Enhancement #144). diff --git a/datatype/pom.xml b/datatype/pom.xml index 94dcc2353..9ca73b822 100644 --- a/datatype/pom.xml +++ b/datatype/pom.xml @@ -6,7 +6,7 @@ jopa-all cz.cvut.kbss.jopa - 1.0.0 + 1.1.0 ../pom.xml diff --git a/jopa-api/pom.xml b/jopa-api/pom.xml index 951fda93c..d5d8c52b8 100644 --- a/jopa-api/pom.xml +++ b/jopa-api/pom.xml @@ -6,7 +6,7 @@ cz.cvut.kbss.jopa jopa-all - 1.0.0 + 1.1.0 ../pom.xml diff --git a/jopa-api/src/main/java/cz/cvut/kbss/jopa/model/metamodel/ManagedType.java b/jopa-api/src/main/java/cz/cvut/kbss/jopa/model/metamodel/ManagedType.java index 276f84b5e..ee8d287d1 100644 --- a/jopa-api/src/main/java/cz/cvut/kbss/jopa/model/metamodel/ManagedType.java +++ b/jopa-api/src/main/java/cz/cvut/kbss/jopa/model/metamodel/ManagedType.java @@ -19,8 +19,7 @@ import java.util.Set; /** - * Instances of the type ManagedType represent entity, mapped superclass, and - * embeddable types. + * Instances of the type ManagedType represent entity, mapped superclass, and embeddable types. * * @param The represented type. */ @@ -33,80 +32,75 @@ public interface ManagedType extends Type { Set> getAttributes(); /** - * Return the attributes declared by the managed type. Returns empty set if - * the managed type has no declared attributes. + * Return the attributes declared by the managed type. Returns empty set if the managed type has no declared + * attributes. * * @return declared attributes of the managed type */ Set> getDeclaredAttributes(); /** - * Return the single-valued attribute of the managed type that corresponds - * to the specified name and Java type. + * Return the single-valued attribute of the managed type that corresponds to the specified name and Java type. * * @param name the name of the represented attribute * @param type the type of the represented attribute * @return single-valued attribute with given name and type * @throws IllegalArgumentException if attribute of the given name and type is not present in the managed type */ - SingularAttribute getSingularAttribute(String name, - Class type); + SingularAttribute getSingularAttribute(String name, Class type); /** - * Return the single-valued attribute declared by the managed type that - * corresponds to the specified name and Java type. + * Return the single-valued attribute declared by the managed type that corresponds to the specified name and Java + * type. * * @param name the name of the represented attribute * @param type the type of the represented attribute * @return declared single-valued attribute of the given name and type * @throws IllegalArgumentException if attribute of the given name and type is not declared in the managed type */ - SingularAttribute getDeclaredSingularAttribute(String name, - Class type); + SingularAttribute getDeclaredSingularAttribute(String name, Class type); /** - * Return the single-valued attributes of the managed type. Returns empty - * set if the managed type has no single-valued attributes. + * Return the single-valued attributes of the managed type. Returns empty set if the managed type has no + * single-valued attributes. * * @return single-valued attributes */ Set> getSingularAttributes(); /** - * Return the single-valued attributes declared by the managed type. Returns - * empty set if the managed type has no declared single-valued attributes. + * Return the single-valued attributes declared by the managed type. Returns empty set if the managed type has no + * declared single-valued attributes. * * @return declared single-valued attributes */ Set> getDeclaredSingularAttributes(); /** - * Return the Collection-valued attribute of the managed type that - * corresponds to the specified name and Java element type. + * Return the Collection-valued attribute of the managed type that corresponds to the specified name and Java + * element type. * * @param name the name of the represented attribute * @param elementType the element type of the represented attribute * @return CollectionAttribute of the given name and element type * @throws IllegalArgumentException if attribute of the given name and type is not present in the managed type */ - CollectionAttribute getCollection(String name, - Class elementType); + CollectionAttribute getCollection(String name, Class elementType); /** - * Return the Collection-valued attribute declared by the managed type that - * corresponds to the specified name and Java element type. + * Return the Collection-valued attribute declared by the managed type that corresponds to the specified name and + * Java element type. * * @param name the name of the represented attribute * @param elementType the element type of the represented attribute * @return declared CollectionAttribute of the given name and element type * @throws IllegalArgumentException if attribute of the given name and type is not declared in the managed type */ - CollectionAttribute getDeclaredCollection(String name, - Class elementType); + CollectionAttribute getDeclaredCollection(String name, Class elementType); /** - * Return the Set-valued attribute of the managed type that corresponds to - * the specified name and Java element type. + * Return the Set-valued attribute of the managed type that corresponds to the specified name and Java element + * type. * * @param name the name of the represented attribute * @param elementType the element type of the represented attribute @@ -116,8 +110,8 @@ CollectionAttribute getDeclaredCollection(String name, SetAttribute getSet(String name, Class elementType); /** - * Return the Set-valued attribute declared by the managed type that - * corresponds to the specified name and Java element type. + * Return the Set-valued attribute declared by the managed type that corresponds to the specified name and Java + * element type. * * @param name the name of the represented attribute * @param elementType the element type of the represented attribute @@ -128,8 +122,8 @@ CollectionAttribute getDeclaredCollection(String name, SetAttribute getDeclaredSet(String name, Class elementType); /** - * Return the List-valued attribute of the managed type that corresponds to - * the specified name and Java element type. + * Return the List-valued attribute of the managed type that corresponds to the specified name and Java element + * type. * * @param name the name of the represented attribute * @param elementType the element type of the represented attribute @@ -139,8 +133,8 @@ CollectionAttribute getDeclaredCollection(String name, ListAttribute getList(String name, Class elementType); /** - * Return the List-valued attribute declared by the managed type that - * corresponds to the specified name and Java element type. + * Return the List-valued attribute declared by the managed type that corresponds to the specified name and Java + * element type. * * @param name the name of the represented attribute * @param elementType the element type of the represented attribute @@ -150,8 +144,8 @@ CollectionAttribute getDeclaredCollection(String name, ListAttribute getDeclaredList(String name, Class elementType); /** - * Return the Map-valued attribute of the managed type that corresponds to - * the specified name and Java key and value types. + * Return the Map-valued attribute of the managed type that corresponds to the specified name and Java key and value + * types. * * @param name the name of the represented attribute * @param keyType the key type of the represented attribute @@ -159,12 +153,11 @@ CollectionAttribute getDeclaredCollection(String name, * @return MapAttribute of the given name and key and value types * @throws IllegalArgumentException if attribute of the given name and type is not present in the managed type */ - MapAttribute getMap(String name, Class keyType, - Class valueType); + MapAttribute getMap(String name, Class keyType, Class valueType); /** - * Return the Map-valued attribute declared by the managed type that - * corresponds to the specified name and Java key and value types. + * Return the Map-valued attribute declared by the managed type that corresponds to the specified name and Java key + * and value types. * * @param name the name of the represented attribute * @param keyType the key type of the represented attribute @@ -172,58 +165,46 @@ MapAttribute getMap(String name, Class keyType, * @return declared MapAttribute of the given name and key and value types * @throws IllegalArgumentException if attribute of the given name and type is not declared in the managed type */ - MapAttribute getDeclaredMap(String name, Class keyType, - Class valueType); + MapAttribute getDeclaredMap(String name, Class keyType, Class valueType); /** - * Return all multi-valued attributes (Collection-, Set-, List-, and - * Map-valued attributes) of the managed type. Returns empty set if the - * managed type has no multi-valued attributes. + * Return all multi-valued attributes (Collection-, Set-, List-, and Map-valued attributes) of the managed type. + * Returns empty set if the managed type has no multi-valued attributes. * * @return Collection-, Set-, List-, and Map-valued attributes */ Set> getPluralAttributes(); /** - * Return all multi-valued attributes (Collection-, Set-, List-, and - * Map-valued attributes) declared by the managed type. Returns empty set if - * the managed type has no declared multi-valued attributes. + * Return all multi-valued attributes (Collection-, Set-, List-, and Map-valued attributes) declared by the managed + * type. Returns empty set if the managed type has no declared multi-valued attributes. * - * @return declared Collection-, Set-, List-, and Map-valued - *

- * attributes + * @return declared Collection-, Set-, List-, and Map-valued attributes */ Set> getDeclaredPluralAttributes(); // String-based: /** - * Return the attribute of the managed type that corresponds to the - * specified name. + * Return the attribute of the managed type that corresponds to the specified name. * * @param name the name of the represented attribute * @return attribute with given name - * @throws IllegalArgumentException if attribute of the given - *

- * name is not present in the managed type + * @throws IllegalArgumentException if attribute of the given name is not present in the managed type */ Attribute getAttribute(String name); /** - * Return the attribute declared by the managed type that corresponds to the - * specified name. + * Return the attribute declared by the managed type that corresponds to the specified name. * * @param name the name of the represented attribute * @return attribute with given name - * @throws IllegalArgumentException if attribute of the given - *

- * name is not declared in the managed type + * @throws IllegalArgumentException if attribute of the given name is not declared in the managed type */ Attribute getDeclaredAttribute(String name); /** - * Return the single-valued attribute of the managed type that corresponds - * to the specified name. + * Return the single-valued attribute of the managed type that corresponds to the specified name. * * @param name the name of the represented attribute * @return single-valued attribute with the given name @@ -232,20 +213,16 @@ MapAttribute getDeclaredMap(String name, Class keyType, SingularAttribute getSingularAttribute(String name); /** - * Return the single-valued attribute declared by the managed type that - * corresponds to the specified name. + * Return the single-valued attribute declared by the managed type that corresponds to the specified name. * * @param name the name of the represented attribute - * @return declared single-valued attribute of the given - *

- * name + * @return declared single-valued attribute of the given name * @throws IllegalArgumentException if attribute of the given name is not declared in the managed type */ SingularAttribute getDeclaredSingularAttribute(String name); /** - * Return the Collection-valued attribute of the managed type that - * corresponds to the specified name. + * Return the Collection-valued attribute of the managed type that corresponds to the specified name. * * @param name the name of the represented attribute * @return CollectionAttribute of the given name @@ -254,8 +231,7 @@ MapAttribute getDeclaredMap(String name, Class keyType, CollectionAttribute getCollection(String name); /** - * Return the Collection-valued attribute declared by the managed type that - * corresponds to the specified name. + * Return the Collection-valued attribute declared by the managed type that corresponds to the specified name. * * @param name the name of the represented attribute * @return declared CollectionAttribute of the given name @@ -264,8 +240,7 @@ MapAttribute getDeclaredMap(String name, Class keyType, CollectionAttribute getDeclaredCollection(String name); /** - * Return the Set-valued attribute of the managed type that corresponds to - * the specified name. + * Return the Set-valued attribute of the managed type that corresponds to the specified name. * * @param name the name of the represented attribute * @return SetAttribute of the given name @@ -274,8 +249,7 @@ MapAttribute getDeclaredMap(String name, Class keyType, SetAttribute getSet(String name); /** - * Return the Set-valued attribute declared by the managed type that - * corresponds to the specified name. + * Return the Set-valued attribute declared by the managed type that corresponds to the specified name. * * @param name the name of the represented attribute * @return declared SetAttribute of the given name @@ -284,8 +258,7 @@ MapAttribute getDeclaredMap(String name, Class keyType, SetAttribute getDeclaredSet(String name); /** - * Return the List-valued attribute of the managed type that corresponds to - * the specified name. + * Return the List-valued attribute of the managed type that corresponds to the specified name. * * @param name the name of the represented attribute * @return ListAttribute of the given name @@ -294,8 +267,7 @@ MapAttribute getDeclaredMap(String name, Class keyType, ListAttribute getList(String name); /** - * Return the List-valued attribute declared by the managed type that - * corresponds to the specified name. + * Return the List-valued attribute declared by the managed type that corresponds to the specified name. * * @param name the name of the represented attribute * @return declared ListAttribute of the given name @@ -304,8 +276,7 @@ MapAttribute getDeclaredMap(String name, Class keyType, ListAttribute getDeclaredList(String name); /** - * Return the Map-valued attribute of the managed type that corresponds to - * the specified name. + * Return the Map-valued attribute of the managed type that corresponds to the specified name. * * @param name the name of the represented attribute * @return MapAttribute of the given name @@ -314,8 +285,7 @@ MapAttribute getDeclaredMap(String name, Class keyType, MapAttribute getMap(String name); /** - * Return the Map-valued attribute declared by the managed type that - * corresponds to the specified name. + * Return the Map-valued attribute declared by the managed type that corresponds to the specified name. * * @param name the name of the represented attribute * @return declared MapAttribute of the given name @@ -331,8 +301,7 @@ MapAttribute getDeclaredMap(String name, Class keyType, Set> getQueryAttributes(); /** - * Check if a query based attribute of the managed type that corresponds to the - * specified name exists. + * Check if a query based attribute of the managed type that corresponds to the specified name exists. * * @param name the name of the represented attribute * @return {@code true} if the query attribute exists @@ -340,14 +309,11 @@ MapAttribute getDeclaredMap(String name, Class keyType, boolean hasQueryAttribute(String name); /** - * Return the query based attribute of the managed type that corresponds to the - * specified name. + * Return the query based attribute of the managed type that corresponds to the specified name. * * @param name the name of the represented attribute * @return attribute with given name - * @throws IllegalArgumentException if attribute of the given - *

- * name is not present in the managed type + * @throws IllegalArgumentException if attribute of the given name is not present in the managed type */ QueryAttribute getQueryAttribute(String name); @@ -371,8 +337,8 @@ MapAttribute getDeclaredMap(String name, Class keyType, /** * Gets specification of a field with the specified name. *

- * In contrast to {@link #getAttribute(String)}, calling this method can also return field specification for - * a query based attribute, types or properties field. + * In contrast to {@link #getAttribute(String)}, calling this method can also return field specification for a query + * based attribute, types or properties field. * * @param fieldName Name of the field * @return Field specification @@ -384,8 +350,8 @@ MapAttribute getDeclaredMap(String name, Class keyType, /** * Gets all field specifications of this entity type. *

- * In contrast to {@link #getAttributes()}, this method returns also specifications of query based attributes, types and properties (if - * present). + * In contrast to {@link #getAttributes()}, this method returns also specifications of query based attributes, types + * and properties (if present). * * @return Field specifications */ diff --git a/jopa-api/src/main/java/cz/cvut/kbss/jopa/sessions/CriteriaBuilder.java b/jopa-api/src/main/java/cz/cvut/kbss/jopa/sessions/CriteriaBuilder.java index 3acb7cf53..b11051101 100644 --- a/jopa-api/src/main/java/cz/cvut/kbss/jopa/sessions/CriteriaBuilder.java +++ b/jopa-api/src/main/java/cz/cvut/kbss/jopa/sessions/CriteriaBuilder.java @@ -18,6 +18,7 @@ import cz.cvut.kbss.jopa.model.query.criteria.Expression; import cz.cvut.kbss.jopa.model.query.criteria.Order; import cz.cvut.kbss.jopa.model.query.criteria.ParameterExpression; +import cz.cvut.kbss.jopa.model.query.criteria.Path; /** * Used to construct criteria queries, compound selections, expressions, predicates, orderings. @@ -125,6 +126,14 @@ public interface CriteriaBuilder extends PredicateFactory { */ Expression upper(Expression x); + /** + * Create expression for extracting language tag from a string literal. + * + * @param x String-valued attribute + * @return Expression to extract language tag + */ + Expression lang(Path x); + /** * Create an ordering by the ascending value of the expression. * diff --git a/jopa-api/src/main/java/cz/cvut/kbss/jopa/sessions/PredicateFactory.java b/jopa-api/src/main/java/cz/cvut/kbss/jopa/sessions/PredicateFactory.java index c9c16b26e..5e485f3d9 100644 --- a/jopa-api/src/main/java/cz/cvut/kbss/jopa/sessions/PredicateFactory.java +++ b/jopa-api/src/main/java/cz/cvut/kbss/jopa/sessions/PredicateFactory.java @@ -17,6 +17,8 @@ import cz.cvut.kbss.jopa.model.query.criteria.Expression; import cz.cvut.kbss.jopa.model.query.criteria.Predicate; +import java.util.Collection; + public interface PredicateFactory { /** @@ -112,7 +114,8 @@ public interface PredicateFactory { * @param y expression * @return greaterThanOrEqual predicate */ - > Predicate greaterThanOrEqual(Expression x, Expression y); + > Predicate greaterThanOrEqual(Expression x, + Expression y); /** * Create a predicate for testing whether the first argument is greater than or equal to the second. @@ -186,6 +189,26 @@ public interface PredicateFactory { */ Predicate notLike(Expression x, String pattern); + /** + * Creates a predicate that tests whether an element is a member of a collection. + * + * If the collection is empty, the predicate will be false. + * @param elem Element + * @param collection Expression + * @return is-member predicate + */ + > Predicate isMember(E elem, Expression collection); + + /** + * Creates a predicate that tests whether an element is not a member of a collection. + * + * If the collection is empty, the predicate will be true. + * @param elem Element + * @param collection Expression + * @return is-member predicate + */ + > Predicate isNotMember(E elem, Expression collection); + /** * Create a negation of the given restriction. * @param restriction restriction expression diff --git a/jopa-distribution/pom.xml b/jopa-distribution/pom.xml index f19d69e7e..45447aac2 100644 --- a/jopa-distribution/pom.xml +++ b/jopa-distribution/pom.xml @@ -6,7 +6,7 @@ cz.cvut.kbss.jopa jopa-all - 1.0.0 + 1.1.0 ../pom.xml diff --git a/jopa-impl/pom.xml b/jopa-impl/pom.xml index 45607fd60..6ddaf75a1 100644 --- a/jopa-impl/pom.xml +++ b/jopa-impl/pom.xml @@ -6,7 +6,7 @@ cz.cvut.kbss.jopa jopa-all - 1.0.0 + 1.1.0 ../pom.xml diff --git a/jopa-impl/src/main/antlr4/cz/cvut/kbss/jopa/query/soql/Soql.g4 b/jopa-impl/src/main/antlr4/cz/cvut/kbss/jopa/query/soql/Soql.g4 index ac9ba1fc3..4d105890b 100644 --- a/jopa-impl/src/main/antlr4/cz/cvut/kbss/jopa/query/soql/Soql.g4 +++ b/jopa-impl/src/main/antlr4/cz/cvut/kbss/jopa/query/soql/Soql.g4 @@ -62,6 +62,7 @@ simpleConditionalExpression : comparisonExpression | likeExpression | inExpression + | memberOfExpression ; inExpression @@ -78,9 +79,13 @@ literal ; likeExpression - : stringExpression ('NOT')? LIKE whereClauseValue + : stringExpression (NOT)? LIKE whereClauseValue ; +memberOfExpression + : inItem (NOT)? MEMBEROF whereClauseParam + ; + comparisonExpression : stringExpression COMPARISON_OPERATOR stringExpression | simpleArithmeticExpression COMPARISON_OPERATOR simpleArithmeticExpression @@ -102,6 +107,7 @@ functionsReturningStrings | 'SUBSTRING' '(' stringExpression ',' simpleArithmeticExpression ',' simpleArithmeticExpression ')' | 'LOWER' '(' stringExpression ')' | 'UPPER' '(' stringExpression ')' + | 'LANG' '(' whereClauseParam ')' ; simpleArithmeticExpression @@ -181,6 +187,8 @@ LIKE: 'LIKE' ; IN: 'IN' ; +MEMBEROF: 'MEMBER OF' ; + COMPARISON_OPERATOR: '>' | '<' | '>=' | '<=' | '=' | '<>' | '!=' ; DOT: '.' ; diff --git a/jopa-impl/src/main/java/cz/cvut/kbss/jopa/exception/SoqlException.java b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/exception/SoqlException.java new file mode 100644 index 000000000..792495192 --- /dev/null +++ b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/exception/SoqlException.java @@ -0,0 +1,13 @@ +package cz.cvut.kbss.jopa.exception; + +import cz.cvut.kbss.jopa.exceptions.OWLPersistenceException; + +/** + * Indicates an error during parsing and translation of SOQL to SPARQL. + */ +public class SoqlException extends OWLPersistenceException { + + public SoqlException(String message) { + super(message); + } +} diff --git a/jopa-impl/src/main/java/cz/cvut/kbss/jopa/loaders/DefaultClasspathScanner.java b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/loaders/DefaultClasspathScanner.java index be469134d..66db6f527 100644 --- a/jopa-impl/src/main/java/cz/cvut/kbss/jopa/loaders/DefaultClasspathScanner.java +++ b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/loaders/DefaultClasspathScanner.java @@ -26,7 +26,11 @@ import java.net.URL; import java.net.URLDecoder; import java.nio.charset.StandardCharsets; -import java.util.*; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.List; +import java.util.Set; import java.util.function.Consumer; import java.util.jar.JarEntry; import java.util.jar.JarFile; @@ -107,7 +111,7 @@ protected static boolean isJar(String filePath) { protected static JarFile createJarFile(URL elementUrl) throws IOException { final String jarPath = sanitizePath(elementUrl).replaceFirst("[.]jar[!].*", JAR_FILE_SUFFIX) - .replaceFirst("file:", ""); + .replaceFirst("file:", ""); return new JarFile(jarPath); } @@ -135,7 +139,8 @@ protected void processJarFile(final JarFile jarFile) { final String entryName = entry.getName(); if (entryName.endsWith(CLASS_FILE_SUFFIX) && entryName.contains(pathPattern)) { String className = entryName.substring(entryName.indexOf(pathPattern)); - className = className.replace(JAVA_CLASSPATH_SEPARATOR, JAVA_PACKAGE_SEPARATOR).replace(WINDOWS_FILE_SEPARATOR, JAVA_PACKAGE_SEPARATOR); + className = className.replace(JAVA_CLASSPATH_SEPARATOR, JAVA_PACKAGE_SEPARATOR) + .replace(WINDOWS_FILE_SEPARATOR, JAVA_PACKAGE_SEPARATOR); className = className.substring(0, className.length() - CLASS_FILE_SUFFIX.length()); processClass(className); } @@ -154,8 +159,9 @@ protected void processClass(String className) { try { final Class cls = Class.forName(className, true, classLoader); listeners.forEach(listener -> listener.accept(cls)); - } catch (ClassNotFoundException e) { - throw new OWLPersistenceException("Unexpected ClassNotFoundException when scanning for entities.", e); + } catch (Throwable e) { + LOG.debug("Unable to load class {}, got error {}: {}. Skipping the class. If it is an entity class, ensure it is available on classpath and is built with supported Java version.", className, e.getClass() + .getName(), e.getMessage()); } } diff --git a/jopa-impl/src/main/java/cz/cvut/kbss/jopa/loaders/PersistenceUnitClassFinder.java b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/loaders/PersistenceUnitClassFinder.java index 9224511a9..443711e64 100644 --- a/jopa-impl/src/main/java/cz/cvut/kbss/jopa/loaders/PersistenceUnitClassFinder.java +++ b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/loaders/PersistenceUnitClassFinder.java @@ -24,6 +24,7 @@ import java.util.Map; import java.util.Objects; import java.util.Set; +import java.util.stream.Stream; /** * Scans classpath to discover classes relevant to persistence unit building. @@ -53,18 +54,13 @@ public class PersistenceUnitClassFinder { */ public void scanClasspath(Configuration configuration) { Objects.requireNonNull(configuration); - if (!configuration.contains(JOPAPersistenceProperties.SCAN_PACKAGE)) { - throw new IllegalArgumentException("Missing the " + JOPAPersistenceProperties.SCAN_PACKAGE + " property."); - } - String toScan = configuration.get(JOPAPersistenceProperties.SCAN_PACKAGE); - if (toScan.isEmpty()) { - throw new IllegalArgumentException(JOPAPersistenceProperties.SCAN_PACKAGE + " property cannot be empty."); - } + String scanPackageConfig = configuration.get(JOPAPersistenceProperties.SCAN_PACKAGE, ""); + final String[] toScan = scanPackageConfig.split(","); final ClasspathScanner classpathScanner = resolveClasspathScanner(configuration); classpathScanner.addListener(entityLoader); classpathScanner.addListener(resultSetMappingLoader); classpathScanner.addListener(converterLoader); - classpathScanner.processClasses(toScan); + Stream.of(toScan).map(String::trim).forEach(classpathScanner::processClasses); this.scanned = true; } diff --git a/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/criteria/CriteriaBuilderImpl.java b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/criteria/CriteriaBuilderImpl.java index 6ff10f6d5..4173da98a 100644 --- a/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/criteria/CriteriaBuilderImpl.java +++ b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/criteria/CriteriaBuilderImpl.java @@ -15,12 +15,39 @@ package cz.cvut.kbss.jopa.query.criteria; import cz.cvut.kbss.jopa.model.CriteriaQueryImpl; -import cz.cvut.kbss.jopa.model.query.criteria.*; -import cz.cvut.kbss.jopa.query.criteria.expressions.*; +import cz.cvut.kbss.jopa.model.query.criteria.Expression; +import cz.cvut.kbss.jopa.model.query.criteria.Order; +import cz.cvut.kbss.jopa.model.query.criteria.ParameterExpression; +import cz.cvut.kbss.jopa.model.query.criteria.Path; +import cz.cvut.kbss.jopa.model.query.criteria.Predicate; +import cz.cvut.kbss.jopa.query.criteria.expressions.AbsFunction; +import cz.cvut.kbss.jopa.query.criteria.expressions.AbstractExpression; +import cz.cvut.kbss.jopa.query.criteria.expressions.AbstractPathExpression; +import cz.cvut.kbss.jopa.query.criteria.expressions.CeilFunction; +import cz.cvut.kbss.jopa.query.criteria.expressions.CountFunction; +import cz.cvut.kbss.jopa.query.criteria.expressions.ExpressionEqualImpl; +import cz.cvut.kbss.jopa.query.criteria.expressions.ExpressionGreaterThanImpl; +import cz.cvut.kbss.jopa.query.criteria.expressions.ExpressionGreaterThanOrEqualImpl; +import cz.cvut.kbss.jopa.query.criteria.expressions.ExpressionInImpl; +import cz.cvut.kbss.jopa.query.criteria.expressions.ExpressionLessThanImpl; +import cz.cvut.kbss.jopa.query.criteria.expressions.ExpressionLessThanOrEqualImpl; +import cz.cvut.kbss.jopa.query.criteria.expressions.ExpressionLikeImpl; +import cz.cvut.kbss.jopa.query.criteria.expressions.ExpressionLiteralImpl; +import cz.cvut.kbss.jopa.query.criteria.expressions.ExpressionNotEqualImpl; +import cz.cvut.kbss.jopa.query.criteria.expressions.ExpressionNotLikeImpl; +import cz.cvut.kbss.jopa.query.criteria.expressions.FloorFunction; +import cz.cvut.kbss.jopa.query.criteria.expressions.IsMemberExpression; +import cz.cvut.kbss.jopa.query.criteria.expressions.LangFunction; +import cz.cvut.kbss.jopa.query.criteria.expressions.LengthFunction; +import cz.cvut.kbss.jopa.query.criteria.expressions.LowerFunction; +import cz.cvut.kbss.jopa.query.criteria.expressions.OrderImpl; +import cz.cvut.kbss.jopa.query.criteria.expressions.ParameterExpressionImpl; +import cz.cvut.kbss.jopa.query.criteria.expressions.UpperFunction; import cz.cvut.kbss.jopa.sessions.CriteriaBuilder; import cz.cvut.kbss.jopa.sessions.UnitOfWorkImpl; import java.util.Arrays; +import java.util.Collection; public class CriteriaBuilderImpl implements CriteriaBuilder { @@ -31,7 +58,7 @@ public CriteriaBuilderImpl(UnitOfWorkImpl uow) { } @Override - public CriteriaQuery createQuery(Class resultClass) { + public CriteriaQueryImpl createQuery(Class resultClass) { return new CriteriaQueryImpl<>(new CriteriaQueryHolder<>(resultClass), uow.getMetamodel(), this); } @@ -41,6 +68,12 @@ public Expression abs(Expression x) { return new AbsFunction<>((Class) x.getJavaType(), (AbstractPathExpression) x, this); } + private void validateFunctionArgument(Expression x) { + if (!(x instanceof AbstractPathExpression)) { + throw new IllegalArgumentException("Function can be applied only to path expressions."); + } + } + @Override public Expression count(Expression x) { validateFunctionArgument(x); @@ -101,10 +134,10 @@ public Expression upper(Expression x) { return new UpperFunction((AbstractPathExpression) x, this); } - private void validateFunctionArgument(Expression x) { - if (!(x instanceof AbstractPathExpression)) { - throw new IllegalArgumentException("Function can be applied only to path expressions."); - } + @Override + public Expression lang(Path x) { + validateFunctionArgument(x); + return new LangFunction((AbstractPathExpression) x, this); } @Override @@ -219,6 +252,18 @@ public In notIn(Expression expression) { return inExpression; } + @Override + public > Predicate isMember(E elem, Expression collection) { + return new IsMemberExpression<>(elem, collection, this); + } + + @Override + public > Predicate isNotMember(E elem, Expression collection) { + final IsMemberExpression expr = new IsMemberExpression<>(elem, collection, this); + expr.not(); + return expr; + } + @Override public > Predicate greaterThan(Expression x, Expression y) { diff --git a/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/criteria/PathImpl.java b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/criteria/PathImpl.java index a3dabc3cb..5bcf0bd46 100644 --- a/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/criteria/PathImpl.java +++ b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/criteria/PathImpl.java @@ -17,6 +17,7 @@ import cz.cvut.kbss.jopa.model.metamodel.Bindable; import cz.cvut.kbss.jopa.model.metamodel.FieldSpecification; import cz.cvut.kbss.jopa.model.metamodel.Metamodel; +import cz.cvut.kbss.jopa.model.metamodel.TypesSpecification; import cz.cvut.kbss.jopa.model.query.criteria.Path; import cz.cvut.kbss.jopa.query.criteria.expressions.AbstractPathExpression; import cz.cvut.kbss.jopa.sessions.CriteriaBuilder; @@ -34,6 +35,9 @@ public PathImpl(Metamodel metamodel, AbstractPathExpression pathSource, FieldSpe } private static Class resolveBindableJavaType(FieldSpecification attribute) { + if (attribute instanceof TypesSpecification) { + return ((TypesSpecification) attribute).getElementType(); + } assert attribute instanceof Bindable; return ((Bindable) attribute).getBindableJavaType(); } diff --git a/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/criteria/expressions/AbstractPathExpression.java b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/criteria/expressions/AbstractPathExpression.java index 67a4f6b78..0cd60bf7c 100644 --- a/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/criteria/expressions/AbstractPathExpression.java +++ b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/criteria/expressions/AbstractPathExpression.java @@ -1,16 +1,14 @@ /** * Copyright (C) 2023 Czech Technical University in Prague - * - * This program is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software - * Foundation, either version 3 of the License, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. You should have received a copy of the GNU General Public License - * along with this program. If not, see . + *

+ * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later + * version. + *

+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. You should have received a copy of the GNU General Public License along with this program. If not, see + * . */ package cz.cvut.kbss.jopa.query.criteria.expressions; @@ -27,7 +25,8 @@ public abstract class AbstractPathExpression extends AbstractExpression im protected AbstractPathExpression pathSource; protected final Metamodel metamodel; - public AbstractPathExpression(Class type, AbstractPathExpression pathSource, Metamodel metamodel, CriteriaBuilder cb) { + public AbstractPathExpression(Class type, AbstractPathExpression pathSource, Metamodel metamodel, + CriteriaBuilder cb) { super(type, cb); this.pathSource = pathSource; this.metamodel = metamodel; @@ -38,6 +37,8 @@ public Path getAttr(String attributeName) { final FieldSpecification fs; if (et.getIdentifier().getName().equals(attributeName)) { fs = et.getIdentifier(); + } else if (et.getTypes() != null && et.getTypes().getName().equals(attributeName)) { + fs = et.getTypes(); } else { fs = et.getAttribute(attributeName); } diff --git a/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/criteria/expressions/IsMemberExpression.java b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/criteria/expressions/IsMemberExpression.java new file mode 100644 index 000000000..53f42689b --- /dev/null +++ b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/criteria/expressions/IsMemberExpression.java @@ -0,0 +1,45 @@ +package cz.cvut.kbss.jopa.query.criteria.expressions; + +import cz.cvut.kbss.jopa.model.query.criteria.Expression; +import cz.cvut.kbss.jopa.model.query.criteria.Predicate; +import cz.cvut.kbss.jopa.query.criteria.AbstractPredicate; +import cz.cvut.kbss.jopa.query.criteria.CriteriaParameterFiller; +import cz.cvut.kbss.jopa.query.soql.SoqlConstants; +import cz.cvut.kbss.jopa.sessions.CriteriaBuilder; + +import java.util.Collection; +import java.util.List; + +public class IsMemberExpression extends AbstractPredicate { + + private final Expression> collectionExpression; + private final Y value; + + public IsMemberExpression(Y value, Expression> collectionExpression, CriteriaBuilder cb) { + super(BooleanOperator.AND, cb); + this.value = value; + this.collectionExpression = collectionExpression; + } + + @Override + public Predicate not() { + super.negate(); + return this; + } + + @Override + public List> getExpressions() { + return List.of(this); + } + + @Override + public void setExpressionToQuery(StringBuilder query, CriteriaParameterFiller parameterFiller) { + final AbstractExpression param = (AbstractExpression) cb.literal(value); + param.setExpressionToQuery(query, parameterFiller); + if (negated) { + query.append(' ').append(SoqlConstants.NOT); + } + query.append(' ').append(SoqlConstants.MEMBER_OF).append(' '); + ((AbstractExpression) collectionExpression).setExpressionToQuery(query, parameterFiller); + } +} diff --git a/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/criteria/expressions/LangFunction.java b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/criteria/expressions/LangFunction.java new file mode 100644 index 000000000..c32d54ee6 --- /dev/null +++ b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/criteria/expressions/LangFunction.java @@ -0,0 +1,19 @@ +package cz.cvut.kbss.jopa.query.criteria.expressions; + +import cz.cvut.kbss.jopa.query.soql.SoqlConstants; +import cz.cvut.kbss.jopa.sessions.CriteriaBuilder; + +/** + * Represents the SOQL {@link SoqlConstants.Functions#LANG} function. + */ +public class LangFunction extends AbstractFunctionExpression { + + public LangFunction(AbstractPathExpression internExpression, CriteriaBuilder cb) { + super(String.class, internExpression, cb); + } + + @Override + public String getFunctionName() { + return SoqlConstants.Functions.LANG; + } +} diff --git a/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/soql/MemberOfOperator.java b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/soql/MemberOfOperator.java new file mode 100644 index 000000000..54b9c0cef --- /dev/null +++ b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/soql/MemberOfOperator.java @@ -0,0 +1,21 @@ +package cz.cvut.kbss.jopa.query.soql; + +/** + * SOQL ({@code NOT}) {@code MEMBER OF} operator. + */ +public class MemberOfOperator implements FilterableExpression { + + @Override + public String toFilterExpression(String parameter, String value) { + return ""; + } + + @Override + public boolean requiresFilterExpression() { + return false; + } + + static MemberOfOperator memberOf() { + return new MemberOfOperator(); + } +} diff --git a/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/soql/SoqlAttribute.java b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/soql/SoqlAttribute.java index a53e5495b..372b8a0c0 100644 --- a/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/soql/SoqlAttribute.java +++ b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/soql/SoqlAttribute.java @@ -14,6 +14,7 @@ */ package cz.cvut.kbss.jopa.query.soql; +import cz.cvut.kbss.jopa.query.sparql.SparqlConstants; import cz.cvut.kbss.jopa.utils.IdentifierTransformer; import java.util.Collections; @@ -162,6 +163,7 @@ public String getBasicGraphPattern(String rootVariable) { } private static String toIri(SoqlNode node) { - return IdentifierTransformer.stringifyIri(node.getIri()); + final String nodeIri = node.getIri(); + return SparqlConstants.RDF_TYPE_SHORTCUT.equals(nodeIri) ? nodeIri : IdentifierTransformer.stringifyIri(nodeIri); } } diff --git a/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/soql/SoqlConstants.java b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/soql/SoqlConstants.java index 337b0036e..afb7f7b01 100644 --- a/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/soql/SoqlConstants.java +++ b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/soql/SoqlConstants.java @@ -44,6 +44,11 @@ public class SoqlConstants { */ public static final String IN = "IN"; + /** + * {@code MEMBER OF} operator. + */ + public static final String MEMBER_OF = "MEMBER OF"; + /** * {@code NOT} operator. */ @@ -121,6 +126,11 @@ public static class Functions { */ public static final String FLOOR = "FLOOR"; + /** + * Returns language tag of a literal, if it has one. Returns an empty string if it has no language tag. + */ + public static final String LANG = "LANG"; + private Functions() { throw new AssertionError(); } diff --git a/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/soql/SoqlFunctionTranslator.java b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/soql/SoqlFunctionTranslator.java index f48befa7e..037f8f76d 100644 --- a/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/soql/SoqlFunctionTranslator.java +++ b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/soql/SoqlFunctionTranslator.java @@ -35,6 +35,7 @@ private static Map initFunctions() { map.put(SoqlConstants.Functions.ABS, "ABS"); map.put(SoqlConstants.Functions.CEIL, "CEIL"); map.put(SoqlConstants.Functions.FLOOR, "FLOOR"); + map.put(SoqlConstants.Functions.LANG, "lang"); return map; } diff --git a/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/soql/SoqlQueryListener.java b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/soql/SoqlQueryListener.java index 868508b46..bc8389ccf 100644 --- a/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/soql/SoqlQueryListener.java +++ b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/soql/SoqlQueryListener.java @@ -14,6 +14,7 @@ */ package cz.cvut.kbss.jopa.query.soql; +import cz.cvut.kbss.jopa.exception.SoqlException; import cz.cvut.kbss.jopa.model.MetamodelImpl; import cz.cvut.kbss.jopa.model.metamodel.Attribute; import cz.cvut.kbss.jopa.model.metamodel.EntityType; @@ -21,6 +22,7 @@ import cz.cvut.kbss.jopa.model.metamodel.PluralAttribute; import cz.cvut.kbss.jopa.model.metamodel.SingularAttribute; import cz.cvut.kbss.jopa.model.metamodel.Type; +import cz.cvut.kbss.jopa.query.sparql.SparqlConstants; import org.antlr.v4.runtime.ParserRuleContext; import org.antlr.v4.runtime.tree.ErrorNode; import org.antlr.v4.runtime.tree.ParseTree; @@ -168,7 +170,7 @@ public void enterCount(SoqlParser.CountContext ctx) { @Override public void exitCount(SoqlParser.CountContext ctx) { - this.projectedVariable = ctx.getChild(1).getText(); + this.projectedVariable = ctx.getChild(2).getText(); } @Override @@ -366,6 +368,22 @@ public void exitLikeExpression(SoqlParser.LikeExpressionContext ctx) { this.isInObjectIdentifierExpression = false; } + @Override + public void enterMemberOfExpression(SoqlParser.MemberOfExpressionContext ctx) { + + } + + @Override + public void exitMemberOfExpression(SoqlParser.MemberOfExpressionContext ctx) { + if (ctx.getChildCount() > 2 && ctx.getChild(1).getText().equals(SoqlConstants.NOT)) { + attrPointer.setNot(true); + } + attrPointer.setOperator(MemberOfOperator.memberOf()); + ParseTree whereClauseValue = ctx.getChild(0); + attrPointer.setValue(whereClauseValue.getText()); + this.isInObjectIdentifierExpression = false; + } + @Override public void enterComparisonExpression(SoqlParser.ComparisonExpressionContext ctx) { } @@ -689,14 +707,24 @@ private IdentifiableEntityType getEntityType(String name) { } private void setAllNodesIris(EntityType entityType, SoqlNode node) { - if (entityType.getIdentifier().getName().equals(node.getValue())) { + final String nodeName = node.getValue(); + if (entityType.getIdentifier().getName().equals(nodeName)) { return; } - final Attribute abstractAttribute = entityType.getAttribute(node.getValue()); + if (entityType.getTypes() != null && entityType.getTypes().getName().equals(node.getValue())) { + node.setIri(SparqlConstants.RDF_TYPE_SHORTCUT); + return; + } + final Attribute att; + try { + att = entityType.getAttribute(node.getValue()); + } catch (IllegalArgumentException e) { + throw new SoqlException("No matching attribute with name '" + node.getValue() + "' found on entity type '" + entityType.getName() + "'."); + } //not implemented case of 3 or more fragments (chained SoqlNodes) - node.setIri(abstractAttribute.getIRI().toString()); + node.setIri(att.getIRI().toString()); if (node.hasChild()) { - final Type type = resolveBindableType(abstractAttribute); + final Type type = resolveBindableType(att); if (type.getPersistenceType() != Type.PersistenceType.ENTITY) { return; } diff --git a/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/sparql/SparqlConstants.java b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/sparql/SparqlConstants.java new file mode 100644 index 000000000..874fa1e39 --- /dev/null +++ b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/sparql/SparqlConstants.java @@ -0,0 +1,26 @@ +package cz.cvut.kbss.jopa.query.sparql; + +/** + * Constants of SPARQL. + */ +public class SparqlConstants { + + /** + * The {@literal SELECT} keyword. + */ + public static final String SELECT = "SELECT"; + + /** + * The {@literal WHERE} keyword. + */ + public static final String WHERE = "WHERE"; + + /** + * The {@literal a} keyword representing the rdf:type IRI. + */ + public static final String RDF_TYPE_SHORTCUT = "a"; + + private SparqlConstants() { + throw new AssertionError(); + } +} diff --git a/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/sparql/SparqlQueryParser.java b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/sparql/SparqlQueryParser.java index 67ae3a8f1..b24e3f16a 100644 --- a/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/sparql/SparqlQueryParser.java +++ b/jopa-impl/src/main/java/cz/cvut/kbss/jopa/query/sparql/SparqlQueryParser.java @@ -34,9 +34,6 @@ */ public class SparqlQueryParser implements QueryParser { - private static final String SELECT = "SELECT"; - private static final String WHERE = "WHERE"; - private final ParameterValueFactory parameterValueFactory; private String query; @@ -195,9 +192,9 @@ private QueryParameter getQueryParameter(Integer position) { } private void wordEnd() { - if (SELECT.equalsIgnoreCase(currentWord.toString())) { + if (SparqlConstants.SELECT.equalsIgnoreCase(currentWord.toString())) { this.inProjection = true; - } else if (inProjection && WHERE.equalsIgnoreCase(currentWord.toString())) { + } else if (inProjection && SparqlConstants.WHERE.equalsIgnoreCase(currentWord.toString())) { this.inProjection = false; } currentWord = new StringBuilder(); diff --git a/jopa-impl/src/test/java/cz/cvut/kbss/jopa/environment/OWLClassF.java b/jopa-impl/src/test/java/cz/cvut/kbss/jopa/environment/OWLClassF.java index da2374667..6485bbd5f 100644 --- a/jopa-impl/src/test/java/cz/cvut/kbss/jopa/environment/OWLClassF.java +++ b/jopa-impl/src/test/java/cz/cvut/kbss/jopa/environment/OWLClassF.java @@ -34,8 +34,7 @@ public class OWLClassF { @OWLDataProperty(iri = Vocabulary.p_f_stringAttribute) private String secondStringAttribute; - @Sequence(type = SequenceType.simple, ObjectPropertyHasNextIRI = "http://krizik.felk.cvut.cz/ontologies/jopa/attributes#F-hasSimpleNext") - @OWLObjectProperty(iri = "http://krizik.felk.cvut.cz/ontologies/jopa/attributes#F-hasSimpleSequence") + @OWLObjectProperty(iri = Vocabulary.p_f_setAttribute) private Set simpleSet; public OWLClassF() { diff --git a/jopa-impl/src/test/java/cz/cvut/kbss/jopa/environment/Person.java b/jopa-impl/src/test/java/cz/cvut/kbss/jopa/environment/Person.java index 9056c733c..61a6d3020 100644 --- a/jopa-impl/src/test/java/cz/cvut/kbss/jopa/environment/Person.java +++ b/jopa-impl/src/test/java/cz/cvut/kbss/jopa/environment/Person.java @@ -14,12 +14,10 @@ */ package cz.cvut.kbss.jopa.environment; -import cz.cvut.kbss.jopa.model.annotations.Id; -import cz.cvut.kbss.jopa.model.annotations.OWLClass; -import cz.cvut.kbss.jopa.model.annotations.OWLDataProperty; -import cz.cvut.kbss.jopa.model.annotations.OWLObjectProperty; +import cz.cvut.kbss.jopa.model.annotations.*; import java.net.URI; +import java.util.Set; @OWLClass(iri = Vocabulary.c_Person) public class Person { @@ -38,4 +36,7 @@ public class Person { @OWLObjectProperty(iri = Vocabulary.p_p_hasPhone) private Phone phone; + + @Types + private Set types; } diff --git a/jopa-impl/src/test/java/cz/cvut/kbss/jopa/environment/Vocabulary.java b/jopa-impl/src/test/java/cz/cvut/kbss/jopa/environment/Vocabulary.java index aea54f9d9..ee37aec5e 100644 --- a/jopa-impl/src/test/java/cz/cvut/kbss/jopa/environment/Vocabulary.java +++ b/jopa-impl/src/test/java/cz/cvut/kbss/jopa/environment/Vocabulary.java @@ -38,6 +38,7 @@ public class Vocabulary { public static final String c_Phone = CLASS_BASE + "Phone"; public static final String p_f_stringAttribute = ATTRIBUTE_BASE + "f-stringAttribute"; + public static final String p_f_setAttribute = ATTRIBUTE_BASE + "f-hasA"; public static final String p_g_hasH = ATTRIBUTE_BASE + "hasH"; public static final String p_h_hasA = ATTRIBUTE_BASE + "hasA"; diff --git a/jopa-impl/src/test/java/cz/cvut/kbss/jopa/environment/utils/MetamodelFactory.java b/jopa-impl/src/test/java/cz/cvut/kbss/jopa/environment/utils/MetamodelFactory.java index a8f58a1fb..084792dae 100644 --- a/jopa-impl/src/test/java/cz/cvut/kbss/jopa/environment/utils/MetamodelFactory.java +++ b/jopa-impl/src/test/java/cz/cvut/kbss/jopa/environment/utils/MetamodelFactory.java @@ -74,6 +74,7 @@ public static void initOWLClassAMocks(IdentifiableEntityType etMock, when(strAttMock.getFetchType()).thenReturn(FetchType.EAGER); when(strAttMock.hasLanguage()).thenReturn(true); when(strAttMock.getLanguage()).thenReturn(Generators.LANG); + when(etMock.getFieldSpecification(strAttMock.getName())).thenReturn(strAttMock); when(typesMock.getJavaField()).thenReturn(OWLClassA.getTypesField()); when(typesMock.getName()).thenReturn(OWLClassA.getTypesField().getName()); when(typesMock.getDeclaringType()).thenReturn(etMock); @@ -81,7 +82,6 @@ public static void initOWLClassAMocks(IdentifiableEntityType etMock, when(typesMock.getElementType()).thenReturn(String.class); when(typesMock.isCollection()).thenReturn(true); when(typesMock.getFetchType()).thenReturn(FetchType.EAGER); - when(etMock.getFieldSpecification(strAttMock.getName())).thenReturn(strAttMock); when(etMock.getFieldSpecification(typesMock.getName())).thenReturn(typesMock); when(etMock.getIdentifier()).thenReturn(idMock); @@ -321,6 +321,7 @@ public static void initOWLClassFMocks(IdentifiableEntityType etMock, when(setAMock.getBindableJavaType()).thenReturn(OWLClassA.class); when(setAMock.getConstraints()).thenReturn(new ParticipationConstraint[]{}); when(setAMock.getDeclaringType()).thenReturn(etMock); + when(setAMock.getName()).thenReturn(OWLClassF.getSimpleSetField().getName()); when(etMock.getAttribute(OWLClassF.getSimpleSetField().getName())).thenReturn(setAMock); when(etMock.getFieldSpecification(OWLClassF.getSimpleSetField().getName())).thenReturn(setAMock); @@ -341,6 +342,7 @@ public static void initOWLClassFMocks(IdentifiableEntityType etMock, when(etMock.getIdentifier()).thenReturn(idMock); when(idMock.getJavaField()).thenReturn(OWLClassF.class.getDeclaredField("uri")); when(idMock.getDeclaringType()).thenReturn(etMock); + when(idMock.getName()).thenReturn("uri"); when(etMock.getLifecycleListenerManager()).thenReturn(EntityLifecycleListenerManager.empty()); } @@ -1286,6 +1288,7 @@ static void initOwlClassUMocks(IdentifiableEntityType et, SingularAtt when(et.getJavaType()).thenReturn(OWLClassU.class); when(id.getJavaField()).thenReturn(OWLClassU.getIdField()); when(id.getDeclaringType()).thenReturn(et); + when(id.getName()).thenReturn(OWLClassU.getIdField().getName()); when(et.getIRI()).thenReturn(IRI.create(OWLClassU.getClassIri())); when(et.getName()).thenReturn(OWLClassU.class.getSimpleName()); when(et.getFieldSpecifications()) @@ -1426,6 +1429,7 @@ public static void initPersonMocks(IdentifiableEntityType etMock, Abstra AbstractAttribute genderAttMock, AbstractAttribute ageAttMock, SingularAttributeImpl phoneAttMock, AbstractIdentifiableType etPhone, + TypesSpecification typesMock, Identifier idMock) throws NoSuchFieldException, SecurityException { when(etMock.getJavaType()).thenReturn(Person.class); when(etMock.getPersistenceType()).thenReturn(Type.PersistenceType.ENTITY); @@ -1474,5 +1478,15 @@ public static void initPersonMocks(IdentifiableEntityType etMock, Abstra when(phoneAttMock.getName()).thenReturn(Person.class.getDeclaredField("phone").getName()); when(phoneAttMock.getType()).thenReturn(etPhone); when(etMock.getAttribute(Person.class.getDeclaredField("phone").getName())).thenReturn(phoneAttMock); + + when(typesMock.getJavaField()).thenReturn(Person.class.getDeclaredField("types")); + when(typesMock.getName()).thenReturn(Person.class.getDeclaredField("types").getName()); + when(typesMock.getDeclaringType()).thenReturn(etMock); + when(typesMock.getJavaType()).thenReturn(Set.class); + when(typesMock.getElementType()).thenReturn(String.class); + when(typesMock.isCollection()).thenReturn(true); + when(typesMock.getFetchType()).thenReturn(FetchType.EAGER); + when(etMock.getTypes()).thenReturn(typesMock); + when(etMock.getFieldSpecification("types")).thenReturn(typesMock); } } diff --git a/jopa-impl/src/test/java/cz/cvut/kbss/jopa/environment/utils/MetamodelMocks.java b/jopa-impl/src/test/java/cz/cvut/kbss/jopa/environment/utils/MetamodelMocks.java index 58075dd6f..640ada740 100644 --- a/jopa-impl/src/test/java/cz/cvut/kbss/jopa/environment/utils/MetamodelMocks.java +++ b/jopa-impl/src/test/java/cz/cvut/kbss/jopa/environment/utils/MetamodelMocks.java @@ -326,6 +326,8 @@ public class MetamodelMocks { private SingularAttributeImpl personAgeAtt; @Mock private SingularAttributeImpl personPhoneAtt; + @Mock + private TypesSpecification personTypes; @Mock private IdentifiableEntityType etPhone; @@ -373,7 +375,7 @@ public MetamodelMocks() throws Exception { qaEntityAtt, idQA); MetamodelFactory.initPhoneMocks(etPhone, phoneNumberAtt, idPhone); MetamodelFactory.initPersonMocks(etPerson, personUsernameAtt, personGenderAtt, personAgeAtt, personPhoneAtt, - etPhone, idPerson); + etPhone, personTypes, idPerson); } public void setMocks(Metamodel metamodel) { @@ -1003,5 +1005,9 @@ public SingularAttributeImpl ageAttribute() { public SingularAttributeImpl phoneAttribute() { return MetamodelMocks.this.personPhoneAtt; } + + public TypesSpecification typesSpecification() { + return MetamodelMocks.this.personTypes; + } } } diff --git a/jopa-impl/src/test/java/cz/cvut/kbss/jopa/loaders/DefaultClasspathScannerTest.java b/jopa-impl/src/test/java/cz/cvut/kbss/jopa/loaders/DefaultClasspathScannerTest.java new file mode 100644 index 000000000..541b5caba --- /dev/null +++ b/jopa-impl/src/test/java/cz/cvut/kbss/jopa/loaders/DefaultClasspathScannerTest.java @@ -0,0 +1,33 @@ +package cz.cvut.kbss.jopa.loaders; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.function.Consumer; + +import static org.mockito.Mockito.verify; + +@ExtendWith(MockitoExtension.class) +class DefaultClasspathScannerTest { + + @Mock + private Consumer> listener; + + @InjectMocks + private DefaultClasspathScanner sut; + + @BeforeEach + void setUp() { + sut.addListener(listener); + } + + @Test + void processClassesFindsAllClassesOnClassPathWhenProvidedPackageIsEmpty() { + sut.processClasses(""); + PersistenceUnitClassFinderTest.ENTITY_CLASSES.forEach(cls -> verify(listener).accept(cls)); + } +} diff --git a/jopa-impl/src/test/java/cz/cvut/kbss/jopa/loaders/PersistenceUnitClassFinderTest.java b/jopa-impl/src/test/java/cz/cvut/kbss/jopa/loaders/PersistenceUnitClassFinderTest.java index 45235744a..5be1599d5 100644 --- a/jopa-impl/src/test/java/cz/cvut/kbss/jopa/loaders/PersistenceUnitClassFinderTest.java +++ b/jopa-impl/src/test/java/cz/cvut/kbss/jopa/loaders/PersistenceUnitClassFinderTest.java @@ -14,21 +14,51 @@ */ package cz.cvut.kbss.jopa.loaders; -import cz.cvut.kbss.jopa.environment.*; +import cz.cvut.kbss.jopa.environment.OWLClassA; +import cz.cvut.kbss.jopa.environment.OWLClassB; +import cz.cvut.kbss.jopa.environment.OWLClassC; +import cz.cvut.kbss.jopa.environment.OWLClassD; +import cz.cvut.kbss.jopa.environment.OWLClassE; +import cz.cvut.kbss.jopa.environment.OWLClassF; +import cz.cvut.kbss.jopa.environment.OWLClassG; +import cz.cvut.kbss.jopa.environment.OWLClassH; +import cz.cvut.kbss.jopa.environment.OWLClassI; +import cz.cvut.kbss.jopa.environment.OWLClassJ; +import cz.cvut.kbss.jopa.environment.OWLClassK; +import cz.cvut.kbss.jopa.environment.OWLClassL; +import cz.cvut.kbss.jopa.environment.OWLClassM; +import cz.cvut.kbss.jopa.environment.OWLClassN; +import cz.cvut.kbss.jopa.environment.OWLClassO; +import cz.cvut.kbss.jopa.environment.OWLClassP; +import cz.cvut.kbss.jopa.environment.OWLClassQ; +import cz.cvut.kbss.jopa.environment.OWLClassR; +import cz.cvut.kbss.jopa.environment.OWLClassS; +import cz.cvut.kbss.jopa.environment.OWLClassT; +import cz.cvut.kbss.jopa.environment.OWLClassU; +import cz.cvut.kbss.jopa.environment.OWLClassWithQueryAttr; +import cz.cvut.kbss.jopa.environment.Person; +import cz.cvut.kbss.jopa.environment.Phone; import cz.cvut.kbss.jopa.model.JOPAPersistenceProperties; import cz.cvut.kbss.jopa.model.annotations.SparqlResultSetMapping; import cz.cvut.kbss.jopa.utils.Configuration; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import java.util.*; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Optional; +import java.util.Set; import java.util.function.Consumer; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; public class PersistenceUnitClassFinderTest { - private static final Set> ENTITY_CLASSES = initEntityClasses(); + static final Set> ENTITY_CLASSES = initEntityClasses(); private static Set> initEntityClasses() { final Set> set = new HashSet<>(); @@ -61,21 +91,19 @@ private static Set> initEntityClasses() { private final PersistenceUnitClassFinder sut = new PersistenceUnitClassFinder(); - @BeforeEach - void setUp() { - TestClasspathScanner.invoked = false; - } - @Test - public void throwsExceptionWhenScanPackageIsNotSupplied() { - final Map properties = Collections.emptyMap(); - assertThrows(IllegalArgumentException.class, () -> sut.scanClasspath(new Configuration(properties))); + public void scanClasspathScansWholeClasspathWhenPackageIsNotProvided() { + sut.scanClasspath(new Configuration(Map.of(JOPAPersistenceProperties.CLASSPATH_SCANNER_CLASS, TestClasspathScanner.class.getName()))); + assertEquals(Map.of(0, ""), TestClasspathScanner.invocations); } @Test - public void throwsExceptionWhenScanPackageIsEmpty() { - final Map properties = Collections.singletonMap(JOPAPersistenceProperties.SCAN_PACKAGE, ""); - assertThrows(IllegalArgumentException.class, () -> sut.scanClasspath(new Configuration(properties))); + public void scanClasspathScansWholeClasspathWhenPackageIsEmpty() { + sut.scanClasspath(new Configuration(Map.of( + JOPAPersistenceProperties.SCAN_PACKAGE, "", + JOPAPersistenceProperties.CLASSPATH_SCANNER_CLASS, TestClasspathScanner.class.getName() + ))); + assertEquals(Map.of(0, ""), TestClasspathScanner.invocations); } @Test @@ -99,7 +127,7 @@ public void loadsEntityClassesWhenAncestorPackageIsSet() { final Map properties = new HashMap<>(); properties.put(JOPAPersistenceProperties.SCAN_PACKAGE, "cz.cvut.kbss.jopa"); properties.put(JOPAPersistenceProperties.CLASSPATH_SCANNER_CLASS, - cz.cvut.kbss.jopa.environment.utils.TestClasspathScanner.class.getCanonicalName()); + cz.cvut.kbss.jopa.environment.utils.TestClasspathScanner.class.getCanonicalName()); sut.scanClasspath(new Configuration(properties)); assertTrue(sut.getEntities().containsAll(ENTITY_CLASSES)); } @@ -134,14 +162,25 @@ void usesConfiguredClasspathScanner() { properties.put(JOPAPersistenceProperties.SCAN_PACKAGE, "cz.cvut.kbss.jopa.environment"); properties.put(JOPAPersistenceProperties.CLASSPATH_SCANNER_CLASS, TestClasspathScanner.class.getName()); sut.scanClasspath(new Configuration(properties)); - assertTrue(TestClasspathScanner.invoked); + assertEquals(Map.of(0, "cz.cvut.kbss.jopa.environment"), TestClasspathScanner.invocations); + } + + @Test + void scanClasspathUsesClasspathScannerToFindEntityClassesInAllProvidedPackages() { + sut.scanClasspath(new Configuration(Map.of( + JOPAPersistenceProperties.SCAN_PACKAGE, "cz.cvut.kbss.jopa.environment,org.example", + JOPAPersistenceProperties.CLASSPATH_SCANNER_CLASS, TestClasspathScanner.class.getName() + ))); + assertEquals(Map.of(0, "cz.cvut.kbss.jopa.environment", + 1, "org.example"), TestClasspathScanner.invocations); } public static class TestClasspathScanner implements ClasspathScanner { - private static boolean invoked = false; + private static Map invocations; public TestClasspathScanner() { + invocations = new LinkedHashMap<>(); } @Override @@ -151,7 +190,7 @@ public void addListener(Consumer> listener) { @Override public void processClasses(String scanPackage) { - invoked = true; + invocations.put(invocations.size(), scanPackage); } } } diff --git a/jopa-impl/src/test/java/cz/cvut/kbss/jopa/query/criteria/CriteriaBuilderTest.java b/jopa-impl/src/test/java/cz/cvut/kbss/jopa/query/criteria/CriteriaBuilderTest.java index 6dfc0187e..94b6709a6 100644 --- a/jopa-impl/src/test/java/cz/cvut/kbss/jopa/query/criteria/CriteriaBuilderTest.java +++ b/jopa-impl/src/test/java/cz/cvut/kbss/jopa/query/criteria/CriteriaBuilderTest.java @@ -14,7 +14,7 @@ */ package cz.cvut.kbss.jopa.query.criteria; -import cz.cvut.kbss.jopa.environment.*; +import cz.cvut.kbss.jopa.environment.OWLClassA; import cz.cvut.kbss.jopa.environment.utils.MetamodelMocks; import cz.cvut.kbss.jopa.model.MetamodelImpl; import cz.cvut.kbss.jopa.model.query.criteria.CriteriaQuery; @@ -24,18 +24,28 @@ import cz.cvut.kbss.jopa.sessions.CriteriaBuilder; import cz.cvut.kbss.jopa.sessions.MetamodelProvider; import cz.cvut.kbss.jopa.sessions.UnitOfWorkImpl; -import org.junit.jupiter.api.*; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; -import org.mockito.MockitoAnnotations; +import org.mockito.junit.jupiter.MockitoExtension; +import org.mockito.junit.jupiter.MockitoSettings; +import org.mockito.quality.Strictness; import java.util.Collections; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +@ExtendWith(MockitoExtension.class) +@MockitoSettings(strictness = Strictness.LENIENT) public class CriteriaBuilderTest { @Mock @@ -50,7 +60,6 @@ static void init() { @BeforeEach void setUp() throws Exception { - MockitoAnnotations.openMocks(this); final MetamodelImpl metamodel = mock(MetamodelImpl.class); new MetamodelMocks().setMocks(metamodel); final MetamodelProvider mpp = mock(MetamodelProvider.class); diff --git a/jopa-impl/src/test/java/cz/cvut/kbss/jopa/query/criteria/CriteriaQueryTranslateQueryTest.java b/jopa-impl/src/test/java/cz/cvut/kbss/jopa/query/criteria/CriteriaQueryTranslateQueryTest.java index 366fbfd3f..dd962d2c8 100644 --- a/jopa-impl/src/test/java/cz/cvut/kbss/jopa/query/criteria/CriteriaQueryTranslateQueryTest.java +++ b/jopa-impl/src/test/java/cz/cvut/kbss/jopa/query/criteria/CriteriaQueryTranslateQueryTest.java @@ -14,22 +14,30 @@ */ package cz.cvut.kbss.jopa.query.criteria; -import cz.cvut.kbss.jopa.environment.*; +import cz.cvut.kbss.jopa.environment.OWLClassA; +import cz.cvut.kbss.jopa.environment.OWLClassA_; +import cz.cvut.kbss.jopa.environment.OWLClassD; +import cz.cvut.kbss.jopa.environment.OWLClassD_; +import cz.cvut.kbss.jopa.environment.OWLClassF; +import cz.cvut.kbss.jopa.environment.OWLClassM; +import cz.cvut.kbss.jopa.environment.OWLClassU; +import cz.cvut.kbss.jopa.environment.utils.Generators; import cz.cvut.kbss.jopa.environment.utils.MetamodelMocks; import cz.cvut.kbss.jopa.model.CriteriaQueryImpl; import cz.cvut.kbss.jopa.model.MetamodelImpl; -import cz.cvut.kbss.jopa.model.query.criteria.CriteriaQuery; import cz.cvut.kbss.jopa.model.query.criteria.ParameterExpression; import cz.cvut.kbss.jopa.model.query.criteria.Predicate; import cz.cvut.kbss.jopa.model.query.criteria.Root; -import cz.cvut.kbss.jopa.sessions.CriteriaBuilder; import cz.cvut.kbss.jopa.sessions.MetamodelProvider; import cz.cvut.kbss.jopa.sessions.UnitOfWorkImpl; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; -import org.mockito.MockitoAnnotations; +import org.mockito.junit.jupiter.MockitoExtension; +import org.mockito.junit.jupiter.MockitoSettings; +import org.mockito.quality.Strictness; import java.util.ArrayList; import java.util.Collections; @@ -41,17 +49,18 @@ import static org.mockito.Mockito.when; +@ExtendWith(MockitoExtension.class) +@MockitoSettings(strictness = Strictness.LENIENT) public class CriteriaQueryTranslateQueryTest { @Mock private UnitOfWorkImpl uowMock; - private CriteriaBuilder cb; + private CriteriaBuilderImpl cb; private CriteriaParameterFiller criteriaParameterFiller; @BeforeEach void setUp() throws Exception { - MockitoAnnotations.openMocks(this); final MetamodelImpl metamodel = mock(MetamodelImpl.class); new MetamodelMocks().setMocks(metamodel); final MetamodelProvider mpp = mock(MetamodelProvider.class); @@ -60,64 +69,61 @@ void setUp() throws Exception { when(metamodel.getEntities()).thenReturn(Collections.emptySet()); when(mpp.isEntityType(any())).thenAnswer(inv -> metamodel.isEntityType(inv.getArgument(0))); - cb = new CriteriaBuilderImpl(uowMock); - criteriaParameterFiller = new CriteriaParameterFiller(); + this.cb = new CriteriaBuilderImpl(uowMock); + this.criteriaParameterFiller = new CriteriaParameterFiller(); } @Test public void testTranslateQuerySelectAll() { - CriteriaQuery query = cb.createQuery(OWLClassA.class); + CriteriaQueryImpl query = cb.createQuery(OWLClassA.class); Root root = query.from(OWLClassA.class); query.select(root); - final String generatedSoqlQuery = - ((CriteriaQueryImpl) query).translateQuery(criteriaParameterFiller); + final String generatedSoqlQuery = query.translateQuery(criteriaParameterFiller); final String expectedSoqlQuery = "SELECT owlclassa FROM OWLClassA owlclassa"; assertEquals(expectedSoqlQuery, generatedSoqlQuery); } @Test public void testTranslateQuerySelectDistinctAll() { - CriteriaQuery query = cb.createQuery(OWLClassA.class); + CriteriaQueryImpl query = cb.createQuery(OWLClassA.class); Root root = query.from(OWLClassA.class); query.select(root).distinct(true); - final String generatedSoqlQuery = - ((CriteriaQueryImpl) query).translateQuery(criteriaParameterFiller); + final String generatedSoqlQuery = query.translateQuery(criteriaParameterFiller); final String expectedSoqlQuery = "SELECT DISTINCT owlclassa FROM OWLClassA owlclassa"; assertEquals(expectedSoqlQuery, generatedSoqlQuery); } @Test public void testTranslateQueryCount() { - CriteriaQuery query = cb.createQuery(Integer.class); + CriteriaQueryImpl query = cb.createQuery(Integer.class); Root root = query.from(OWLClassA.class); query.select(cb.count(root)); - final String generatedSoqlQuery = ((CriteriaQueryImpl) query).translateQuery(criteriaParameterFiller); + final String generatedSoqlQuery = query.translateQuery(criteriaParameterFiller); final String expectedSoqlQuery = "SELECT COUNT(owlclassa) FROM OWLClassA owlclassa"; assertEquals(expectedSoqlQuery, generatedSoqlQuery); } @Test public void testTranslateQueryDistinctCount() { - CriteriaQuery query = cb.createQuery(Integer.class); + CriteriaQueryImpl query = cb.createQuery(Integer.class); Root root = query.from(OWLClassA.class); query.select(cb.count(root)).distinct(true); - final String generatedSoqlQuery = ((CriteriaQueryImpl) query).translateQuery(criteriaParameterFiller); + final String generatedSoqlQuery = query.translateQuery(criteriaParameterFiller); final String expectedSoqlQuery = "SELECT DISTINCT COUNT(owlclassa) FROM OWLClassA owlclassa"; assertEquals(expectedSoqlQuery, generatedSoqlQuery); } @Test public void testTranslateQuerySelectAllOrderByEntityDesc() { - CriteriaQuery query = cb.createQuery(OWLClassA.class); + CriteriaQueryImpl query = cb.createQuery(OWLClassA.class); Root root = query.from(OWLClassA.class); query.select(root).orderBy(cb.desc(root)); - final String generatedSoqlQuery = - ((CriteriaQueryImpl) query).translateQuery(criteriaParameterFiller); + final String generatedSoqlQuery = query.translateQuery(criteriaParameterFiller); final String expectedSoqlQuery = "SELECT owlclassa FROM OWLClassA owlclassa ORDER BY owlclassa DESC"; assertEquals(expectedSoqlQuery, generatedSoqlQuery); } @@ -127,36 +133,33 @@ public void testTranslateQuerySelectAllOrderByEntityDesc() { class StringBasedPropertyQueryTests { @Test public void testTranslateQuerySelectProperty() { - CriteriaQuery query = cb.createQuery(String.class); + CriteriaQueryImpl query = cb.createQuery(String.class); Root root = query.from(OWLClassA.class); query.select(root.getAttr("stringAttribute")); - final String generatedSoqlQuery = - ((CriteriaQueryImpl) query).translateQuery(criteriaParameterFiller); + final String generatedSoqlQuery = query.translateQuery(criteriaParameterFiller); final String expectedSoqlQuery = "SELECT owlclassa.stringAttribute FROM OWLClassA owlclassa"; assertEquals(expectedSoqlQuery, generatedSoqlQuery); } @Test public void testTranslateQuerySelectPropertyPath() { - CriteriaQuery query = cb.createQuery(String.class); + CriteriaQueryImpl query = cb.createQuery(String.class); Root root = query.from(OWLClassD.class); query.select(root.getAttr("owlClassA").getAttr("stringAttribute")); - final String generatedSoqlQuery = - ((CriteriaQueryImpl) query).translateQuery(criteriaParameterFiller); + final String generatedSoqlQuery = query.translateQuery(criteriaParameterFiller); final String expectedSoqlQuery = "SELECT owlclassd.owlClassA.stringAttribute FROM OWLClassD owlclassd"; assertEquals(expectedSoqlQuery, generatedSoqlQuery); } @Test public void testTranslateQueryEqualRestriction() { - CriteriaQuery query = cb.createQuery(OWLClassA.class); + CriteriaQueryImpl query = cb.createQuery(OWLClassA.class); Root root = query.from(OWLClassA.class); query.select(root).where(cb.equal(root.getAttr("stringAttribute"), "value")); - final String generatedSoqlQuery = - ((CriteriaQueryImpl) query).translateQuery(criteriaParameterFiller); + final String generatedSoqlQuery = query.translateQuery(criteriaParameterFiller); final String expectedSoqlQuery = "SELECT owlclassa FROM OWLClassA owlclassa WHERE owlclassa.stringAttribute = :generatedName0"; assertEquals(expectedSoqlQuery, generatedSoqlQuery); @@ -164,12 +167,11 @@ public void testTranslateQueryEqualRestriction() { @Test public void testTranslateQueryNotEqualRestriction() { - CriteriaQuery query = cb.createQuery(OWLClassA.class); + CriteriaQueryImpl query = cb.createQuery(OWLClassA.class); Root root = query.from(OWLClassA.class); query.select(root).where(cb.notEqual(root.getAttr("stringAttribute"), "value")); - final String generatedSoqlQuery = - ((CriteriaQueryImpl) query).translateQuery(criteriaParameterFiller); + final String generatedSoqlQuery = query.translateQuery(criteriaParameterFiller); final String expectedSoqlQuery = "SELECT owlclassa FROM OWLClassA owlclassa WHERE owlclassa.stringAttribute <> :generatedName0"; assertEquals(expectedSoqlQuery, generatedSoqlQuery); @@ -177,12 +179,11 @@ public void testTranslateQueryNotEqualRestriction() { @Test public void testTranslateQueryGreaterThanRestriction() { - CriteriaQuery query = cb.createQuery(OWLClassM.class); + CriteriaQueryImpl query = cb.createQuery(OWLClassM.class); Root root = query.from(OWLClassM.class); query.select(root).where(cb.greaterThan(root.getAttr("intAttribute"), 1)); - final String generatedSoqlQuery = - ((CriteriaQueryImpl) query).translateQuery(criteriaParameterFiller); + final String generatedSoqlQuery = query.translateQuery(criteriaParameterFiller); final String expectedSoqlQuery = "SELECT owlclassm FROM OWLClassM owlclassm WHERE owlclassm.intAttribute > :generatedName0"; assertEquals(expectedSoqlQuery, generatedSoqlQuery); @@ -190,12 +191,11 @@ public void testTranslateQueryGreaterThanRestriction() { @Test public void testTranslateQueryGreaterThanNegated() { - CriteriaQuery query = cb.createQuery(OWLClassM.class); + CriteriaQueryImpl query = cb.createQuery(OWLClassM.class); Root root = query.from(OWLClassM.class); query.select(root).where(cb.greaterThan(root.getAttr("intAttribute"), 1).not()); - final String generatedSoqlQuery = - ((CriteriaQueryImpl) query).translateQuery(criteriaParameterFiller); + final String generatedSoqlQuery = query.translateQuery(criteriaParameterFiller); final String expectedSoqlQuery = "SELECT owlclassm FROM OWLClassM owlclassm WHERE owlclassm.intAttribute <= :generatedName0"; assertEquals(expectedSoqlQuery, generatedSoqlQuery); @@ -203,12 +203,11 @@ public void testTranslateQueryGreaterThanNegated() { @Test public void testTranslateQueryGreaterThanOrEqualRestriction() { - CriteriaQuery query = cb.createQuery(OWLClassM.class); + CriteriaQueryImpl query = cb.createQuery(OWLClassM.class); Root root = query.from(OWLClassM.class); query.select(root).where(cb.greaterThanOrEqual(root.getAttr("intAttribute"), 1)); - final String generatedSoqlQuery = - ((CriteriaQueryImpl) query).translateQuery(criteriaParameterFiller); + final String generatedSoqlQuery = query.translateQuery(criteriaParameterFiller); final String expectedSoqlQuery = "SELECT owlclassm FROM OWLClassM owlclassm WHERE owlclassm.intAttribute >= :generatedName0"; assertEquals(expectedSoqlQuery, generatedSoqlQuery); @@ -216,12 +215,11 @@ public void testTranslateQueryGreaterThanOrEqualRestriction() { @Test public void testTranslateQueryGreaterOrEqualNegated() { - CriteriaQuery query = cb.createQuery(OWLClassM.class); + CriteriaQueryImpl query = cb.createQuery(OWLClassM.class); Root root = query.from(OWLClassM.class); query.select(root).where(cb.greaterThanOrEqual(root.getAttr("intAttribute"), 1).not()); - final String generatedSoqlQuery = - ((CriteriaQueryImpl) query).translateQuery(criteriaParameterFiller); + final String generatedSoqlQuery = query.translateQuery(criteriaParameterFiller); final String expectedSoqlQuery = "SELECT owlclassm FROM OWLClassM owlclassm WHERE owlclassm.intAttribute < :generatedName0"; assertEquals(expectedSoqlQuery, generatedSoqlQuery); @@ -229,12 +227,11 @@ public void testTranslateQueryGreaterOrEqualNegated() { @Test public void testTranslateQueryLessThanRestriction() { - CriteriaQuery query = cb.createQuery(OWLClassM.class); + CriteriaQueryImpl query = cb.createQuery(OWLClassM.class); Root root = query.from(OWLClassM.class); query.select(root).where(cb.lessThan(root.getAttr("intAttribute"), 1)); - final String generatedSoqlQuery = - ((CriteriaQueryImpl) query).translateQuery(criteriaParameterFiller); + final String generatedSoqlQuery = query.translateQuery(criteriaParameterFiller); final String expectedSoqlQuery = "SELECT owlclassm FROM OWLClassM owlclassm WHERE owlclassm.intAttribute < :generatedName0"; assertEquals(expectedSoqlQuery, generatedSoqlQuery); @@ -242,12 +239,11 @@ public void testTranslateQueryLessThanRestriction() { @Test public void testTranslateQueryLessThanNegated() { - CriteriaQuery query = cb.createQuery(OWLClassM.class); + CriteriaQueryImpl query = cb.createQuery(OWLClassM.class); Root root = query.from(OWLClassM.class); query.select(root).where(cb.lessThan(root.getAttr("intAttribute"), 1).not()); - final String generatedSoqlQuery = - ((CriteriaQueryImpl) query).translateQuery(criteriaParameterFiller); + final String generatedSoqlQuery = query.translateQuery(criteriaParameterFiller); final String expectedSoqlQuery = "SELECT owlclassm FROM OWLClassM owlclassm WHERE owlclassm.intAttribute >= :generatedName0"; assertEquals(expectedSoqlQuery, generatedSoqlQuery); @@ -255,12 +251,11 @@ public void testTranslateQueryLessThanNegated() { @Test public void testTranslateQueryLessOrEqualRestriction() { - CriteriaQuery query = cb.createQuery(OWLClassM.class); + CriteriaQueryImpl query = cb.createQuery(OWLClassM.class); Root root = query.from(OWLClassM.class); query.select(root).where(cb.lessThanOrEqual(root.getAttr("intAttribute"), 1)); - final String generatedSoqlQuery = - ((CriteriaQueryImpl) query).translateQuery(criteriaParameterFiller); + final String generatedSoqlQuery = query.translateQuery(criteriaParameterFiller); final String expectedSoqlQuery = "SELECT owlclassm FROM OWLClassM owlclassm WHERE owlclassm.intAttribute <= :generatedName0"; assertEquals(expectedSoqlQuery, generatedSoqlQuery); @@ -268,12 +263,11 @@ public void testTranslateQueryLessOrEqualRestriction() { @Test public void testTranslateQueryLessOrEqualNegated() { - CriteriaQuery query = cb.createQuery(OWLClassM.class); + CriteriaQueryImpl query = cb.createQuery(OWLClassM.class); Root root = query.from(OWLClassM.class); query.select(root).where(cb.lessThanOrEqual(root.getAttr("intAttribute"), 1).not()); - final String generatedSoqlQuery = - ((CriteriaQueryImpl) query).translateQuery(criteriaParameterFiller); + final String generatedSoqlQuery = query.translateQuery(criteriaParameterFiller); final String expectedSoqlQuery = "SELECT owlclassm FROM OWLClassM owlclassm WHERE owlclassm.intAttribute > :generatedName0"; assertEquals(expectedSoqlQuery, generatedSoqlQuery); @@ -281,12 +275,11 @@ public void testTranslateQueryLessOrEqualNegated() { @Test public void testTranslateQueryNegatedRestriction() { - CriteriaQuery query = cb.createQuery(OWLClassA.class); + CriteriaQueryImpl query = cb.createQuery(OWLClassA.class); Root root = query.from(OWLClassA.class); query.select(root).where(cb.equal(root.getAttr("stringAttribute"), "value").not()); - final CriteriaQueryImpl criteriaQuery = (CriteriaQueryImpl) query; - final String generatedSoqlQuery = criteriaQuery.translateQuery(criteriaParameterFiller); + final String generatedSoqlQuery = query.translateQuery(criteriaParameterFiller); final String expectedSoqlQuery = "SELECT owlclassa FROM OWLClassA owlclassa WHERE owlclassa.stringAttribute <> :generatedName0"; assertEquals(expectedSoqlQuery, generatedSoqlQuery); @@ -294,7 +287,7 @@ public void testTranslateQueryNegatedRestriction() { @Test public void testTranslateQueryMultipleOrRestrictions() { - CriteriaQuery query = cb.createQuery(OWLClassA.class); + CriteriaQueryImpl query = cb.createQuery(OWLClassA.class); Root root = query.from(OWLClassA.class); Predicate restrictions = cb.or( cb.equal(root.getAttr("stringAttribute"), "valueOne"), @@ -303,8 +296,7 @@ public void testTranslateQueryMultipleOrRestrictions() { ); query.select(root).where(restrictions); - final String generatedSoqlQuery = - ((CriteriaQueryImpl) query).translateQuery(criteriaParameterFiller); + final String generatedSoqlQuery = query.translateQuery(criteriaParameterFiller); final String expectedSoqlQuery = "SELECT owlclassa FROM OWLClassA owlclassa WHERE owlclassa.stringAttribute = :generatedName0 OR owlclassa.stringAttribute = :generatedName1 OR owlclassa.stringAttribute = :generatedName2"; assertEquals(expectedSoqlQuery, generatedSoqlQuery); @@ -312,7 +304,7 @@ public void testTranslateQueryMultipleOrRestrictions() { @Test public void testTranslateQueryMultipleAndRestrictions() { - CriteriaQuery query = cb.createQuery(OWLClassM.class); + CriteriaQueryImpl query = cb.createQuery(OWLClassM.class); Root root = query.from(OWLClassM.class); Predicate restrictions = cb.and( cb.equal(root.getAttr("intAttribute"), 0), @@ -321,8 +313,7 @@ public void testTranslateQueryMultipleAndRestrictions() { ); query.select(root).where(restrictions); - final String generatedSoqlQuery = - ((CriteriaQueryImpl) query).translateQuery(criteriaParameterFiller); + final String generatedSoqlQuery = query.translateQuery(criteriaParameterFiller); final String expectedSoqlQuery = "SELECT owlclassm FROM OWLClassM owlclassm WHERE owlclassm.intAttribute = :generatedName0 AND owlclassm.doubleAttribute = :generatedName1 AND owlclassm.booleanAttribute = :generatedName2"; assertEquals(expectedSoqlQuery, generatedSoqlQuery); @@ -330,7 +321,7 @@ public void testTranslateQueryMultipleAndRestrictions() { @Test public void testTranslateQueryMultipleRestrictionsWithList() { - CriteriaQuery query = cb.createQuery(OWLClassM.class); + CriteriaQueryImpl query = cb.createQuery(OWLClassM.class); Root root = query.from(OWLClassM.class); List restrictions = new ArrayList<>(); restrictions.add(cb.equal(root.getAttr("intAttribute"), 0)); @@ -338,8 +329,7 @@ public void testTranslateQueryMultipleRestrictionsWithList() { restrictions.add(cb.equal(root.getAttr("booleanAttribute"), true)); query.select(root).where(restrictions); - final String generatedSoqlQuery = - ((CriteriaQueryImpl) query).translateQuery(criteriaParameterFiller); + final String generatedSoqlQuery = query.translateQuery(criteriaParameterFiller); final String expectedSoqlQuery = "SELECT owlclassm FROM OWLClassM owlclassm WHERE owlclassm.intAttribute = :generatedName0 AND owlclassm.doubleAttribute = :generatedName1 AND owlclassm.booleanAttribute = :generatedName2"; assertEquals(expectedSoqlQuery, generatedSoqlQuery); @@ -348,7 +338,7 @@ public void testTranslateQueryMultipleRestrictionsWithList() { @Test public void testTranslateQueryMultipleOrAndRestrictions() { - CriteriaQuery query = cb.createQuery(OWLClassM.class); + CriteriaQueryImpl query = cb.createQuery(OWLClassM.class); Root root = query.from(OWLClassM.class); query.select(root).where(cb.or( cb.and( @@ -361,8 +351,7 @@ public void testTranslateQueryMultipleOrAndRestrictions() { )) ); - final CriteriaQueryImpl criteriaQuery = (CriteriaQueryImpl) query; - final String generatedSoqlQuery = criteriaQuery.translateQuery(criteriaParameterFiller); + final String generatedSoqlQuery = query.translateQuery(criteriaParameterFiller); final String expectedSoqlQuery = "SELECT owlclassm FROM OWLClassM owlclassm WHERE (owlclassm.doubleAttribute = :generatedName0 AND owlclassm.intAttribute = :generatedName1) OR (owlclassm.doubleAttribute = :generatedName2 AND owlclassm.intAttribute = :generatedName3)"; assertEquals(expectedSoqlQuery, generatedSoqlQuery); @@ -370,7 +359,7 @@ public void testTranslateQueryMultipleOrAndRestrictions() { @Test public void testTranslateQueryNegatedMultipleRestrictionsByNotMethod() { - CriteriaQuery query = cb.createQuery(OWLClassA.class); + CriteriaQueryImpl query = cb.createQuery(OWLClassA.class); Root root = query.from(OWLClassA.class); Predicate restrictions = cb.or( cb.equal(root.getAttr("stringAttribute"), "valueOne"), @@ -379,8 +368,7 @@ public void testTranslateQueryNegatedMultipleRestrictionsByNotMethod() { ); query.select(root).where(restrictions.not()); - final String generatedSoqlQuery = - ((CriteriaQueryImpl) query).translateQuery(criteriaParameterFiller); + final String generatedSoqlQuery = query.translateQuery(criteriaParameterFiller); final String expectedSoqlQuery = "SELECT owlclassa FROM OWLClassA owlclassa WHERE owlclassa.stringAttribute <> :generatedName0 AND owlclassa.stringAttribute <> :generatedName1 AND owlclassa.stringAttribute <> :generatedName2"; assertEquals(expectedSoqlQuery, generatedSoqlQuery); @@ -388,7 +376,7 @@ public void testTranslateQueryNegatedMultipleRestrictionsByNotMethod() { @Test public void testTranslateQueryNegatedMultipleRestrictionsByFactory() { - CriteriaQuery query = cb.createQuery(OWLClassA.class); + CriteriaQueryImpl query = cb.createQuery(OWLClassA.class); Root root = query.from(OWLClassA.class); Predicate restrictions = cb.or( cb.equal(root.getAttr("stringAttribute"), "valueOne"), @@ -397,8 +385,7 @@ public void testTranslateQueryNegatedMultipleRestrictionsByFactory() { ); query.select(root).where(cb.not(restrictions)); - final String generatedSoqlQuery = - ((CriteriaQueryImpl) query).translateQuery(criteriaParameterFiller); + final String generatedSoqlQuery = query.translateQuery(criteriaParameterFiller); final String expectedSoqlQuery = "SELECT owlclassa FROM OWLClassA owlclassa WHERE owlclassa.stringAttribute <> :generatedName0 AND owlclassa.stringAttribute <> :generatedName1 AND owlclassa.stringAttribute <> :generatedName2"; assertEquals(expectedSoqlQuery, generatedSoqlQuery); @@ -406,7 +393,7 @@ public void testTranslateQueryNegatedMultipleRestrictionsByFactory() { @Test public void testTranslateQueryLessThanAndGreaterEqualOrNegatedGreaterThanAndEqual() { - CriteriaQuery query = cb.createQuery(OWLClassM.class); + CriteriaQueryImpl query = cb.createQuery(OWLClassM.class); Root root = query.from(OWLClassM.class); query.select(root).where(cb.or( cb.and( @@ -419,8 +406,7 @@ public void testTranslateQueryLessThanAndGreaterEqualOrNegatedGreaterThanAndEqua ).not()) ); - final CriteriaQueryImpl criteriaQuery = (CriteriaQueryImpl) query; - final String generatedSoqlQuery = criteriaQuery.translateQuery(criteriaParameterFiller); + final String generatedSoqlQuery = query.translateQuery(criteriaParameterFiller); final String expectedSoqlQuery = "SELECT owlclassm FROM OWLClassM owlclassm WHERE (owlclassm.doubleAttribute < :generatedName0 AND owlclassm.intAttribute >= :generatedName1) OR (owlclassm.doubleAttribute <= :generatedName2 OR owlclassm.intAttribute <> :generatedName3)"; assertEquals(expectedSoqlQuery, generatedSoqlQuery); @@ -428,12 +414,11 @@ public void testTranslateQueryLessThanAndGreaterEqualOrNegatedGreaterThanAndEqua @Test public void testTranslateQueryLikeRestriction() { - CriteriaQuery query = cb.createQuery(OWLClassA.class); + CriteriaQueryImpl query = cb.createQuery(OWLClassA.class); Root root = query.from(OWLClassA.class); query.select(root).where(cb.like(root.getAttr("stringAttribute"), "pattern")); - final String generatedSoqlQuery = - ((CriteriaQueryImpl) query).translateQuery(criteriaParameterFiller); + final String generatedSoqlQuery = query.translateQuery(criteriaParameterFiller); final String expectedSoqlQuery = "SELECT owlclassa FROM OWLClassA owlclassa WHERE owlclassa.stringAttribute LIKE :generatedName0"; assertEquals(expectedSoqlQuery, generatedSoqlQuery); @@ -441,12 +426,11 @@ public void testTranslateQueryLikeRestriction() { @Test public void testTranslateQueryNotLikeRestriction() { - CriteriaQuery query = cb.createQuery(OWLClassA.class); + CriteriaQueryImpl query = cb.createQuery(OWLClassA.class); Root root = query.from(OWLClassA.class); query.select(root).where(cb.notLike(root.getAttr("stringAttribute"), "pattern")); - final String generatedSoqlQuery = - ((CriteriaQueryImpl) query).translateQuery(criteriaParameterFiller); + final String generatedSoqlQuery = query.translateQuery(criteriaParameterFiller); final String expectedSoqlQuery = "SELECT owlclassa FROM OWLClassA owlclassa WHERE owlclassa.stringAttribute NOT LIKE :generatedName0"; assertEquals(expectedSoqlQuery, generatedSoqlQuery); @@ -454,12 +438,11 @@ public void testTranslateQueryNotLikeRestriction() { @Test public void testTranslateQueryInRestriction() { - CriteriaQuery query = cb.createQuery(OWLClassA.class); + CriteriaQueryImpl query = cb.createQuery(OWLClassA.class); Root root = query.from(OWLClassA.class); query.select(root).where(cb.in(root.getAttr("stringAttribute")).value("value").value("anotherValue")); - final String generatedSoqlQuery = - ((CriteriaQueryImpl) query).translateQuery(criteriaParameterFiller); + final String generatedSoqlQuery = query.translateQuery(criteriaParameterFiller); final String expectedSoqlQuery = "SELECT owlclassa FROM OWLClassA owlclassa WHERE owlclassa.stringAttribute IN (:generatedName0)"; assertEquals(expectedSoqlQuery, generatedSoqlQuery); @@ -467,13 +450,12 @@ public void testTranslateQueryInRestriction() { @Test public void testTranslateQueryInNegatedRestriction() { - CriteriaQuery query = cb.createQuery(OWLClassA.class); + CriteriaQueryImpl query = cb.createQuery(OWLClassA.class); Root root = query.from(OWLClassA.class); query.select(root) .where(cb.not(cb.in(root.getAttr("stringAttribute")).value("value").value("anotherValue"))); - final String generatedSoqlQuery = - ((CriteriaQueryImpl) query).translateQuery(criteriaParameterFiller); + final String generatedSoqlQuery = query.translateQuery(criteriaParameterFiller); final String expectedSoqlQuery = "SELECT owlclassa FROM OWLClassA owlclassa WHERE owlclassa.stringAttribute NOT IN (:generatedName0)"; assertEquals(expectedSoqlQuery, generatedSoqlQuery); @@ -481,12 +463,11 @@ public void testTranslateQueryInNegatedRestriction() { @Test public void testTranslateQueryNotInRestriction() { - CriteriaQuery query = cb.createQuery(OWLClassA.class); + CriteriaQueryImpl query = cb.createQuery(OWLClassA.class); Root root = query.from(OWLClassA.class); query.select(root).where(cb.notIn(root.getAttr("stringAttribute")).value("value").value("anotherValue")); - final String generatedSoqlQuery = - ((CriteriaQueryImpl) query).translateQuery(criteriaParameterFiller); + final String generatedSoqlQuery = query.translateQuery(criteriaParameterFiller); final String expectedSoqlQuery = "SELECT owlclassa FROM OWLClassA owlclassa WHERE owlclassa.stringAttribute NOT IN (:generatedName0)"; assertEquals(expectedSoqlQuery, generatedSoqlQuery); @@ -494,12 +475,11 @@ public void testTranslateQueryNotInRestriction() { @Test public void testTranslateQueryOrderByOnePropertyDesc() { - CriteriaQuery query = cb.createQuery(OWLClassA.class); + CriteriaQueryImpl query = cb.createQuery(OWLClassA.class); Root root = query.from(OWLClassA.class); query.select(root).orderBy(cb.desc(root.getAttr("stringAttribute"))); - final String generatedSoqlQuery = - ((CriteriaQueryImpl) query).translateQuery(criteriaParameterFiller); + final String generatedSoqlQuery = query.translateQuery(criteriaParameterFiller); final String expectedSoqlQuery = "SELECT owlclassa FROM OWLClassA owlclassa ORDER BY owlclassa.stringAttribute DESC"; assertEquals(expectedSoqlQuery, generatedSoqlQuery); @@ -507,55 +487,80 @@ public void testTranslateQueryOrderByOnePropertyDesc() { @Test public void testTranslateQueryOrderByTwoPropertiesAscAndDesc() { - CriteriaQuery query = cb.createQuery(OWLClassM.class); + CriteriaQueryImpl query = cb.createQuery(OWLClassM.class); Root root = query.from(OWLClassM.class); query.select(root).orderBy( cb.asc(root.getAttr("intAttribute")), cb.desc(root.getAttr("doubleAttribute")) ); - final String generatedSoqlQuery = - ((CriteriaQueryImpl) query).translateQuery(criteriaParameterFiller); + final String generatedSoqlQuery = query.translateQuery(criteriaParameterFiller); final String expectedSoqlQuery = "SELECT owlclassm FROM OWLClassM owlclassm ORDER BY owlclassm.intAttribute ASC, owlclassm.doubleAttribute DESC"; assertEquals(expectedSoqlQuery, generatedSoqlQuery); } + + @Test + void translateQueryTranslatesLangMatching() { + final CriteriaQueryImpl query = cb.createQuery(OWLClassU.class); + final Root root = query.from(OWLClassU.class); + query.select(root).where(cb.equal(cb.lang(root.getAttr("singularStringAtt")), "en")); + + final String result = query.translateQuery(criteriaParameterFiller); + final String expectedSoql = "SELECT owlclassu FROM OWLClassU owlclassu WHERE LANG(owlclassu.singularStringAtt) = :generatedName0"; + assertEquals(expectedSoql, result); + } + + @Test + void translateQueryTranslatesIsMemberWithLiteralToMemberOfExpression() { + final CriteriaQueryImpl query = cb.createQuery(OWLClassA.class); + final Root root = query.from(OWLClassA.class); + query.select(root).where(cb.isMember(Generators.createPropertyIdentifier(), root.getAttr("types"))); + final String expectedSoql = "SELECT owlclassa FROM OWLClassA owlclassa WHERE :generatedName0 MEMBER OF owlclassa.types"; + assertEquals(expectedSoql, query.translateQuery(criteriaParameterFiller)); + } + + @Test + void translateQueryTranslatesIsNotMemberWithLiteralToNotMemberOfExpression() { + final CriteriaQueryImpl query = cb.createQuery(OWLClassF.class); + final Root root = query.from(OWLClassF.class); + query.select(root).where(cb.isNotMember(Generators.createPropertyIdentifier(), root.getAttr("simpleSet"))); + final String expectedSoql = "SELECT owlclassf FROM OWLClassF owlclassf WHERE :generatedName0 NOT MEMBER OF owlclassf.simpleSet"; + assertEquals(expectedSoql, query.translateQuery(criteriaParameterFiller)); + } } @Nested class MetamodelBasedPropertyQueryTests { @Test public void testTranslateQuerySelectProperty() { - CriteriaQuery query = cb.createQuery(String.class); + CriteriaQueryImpl query = cb.createQuery(String.class); Root root = query.from(OWLClassA.class); query.select(root.getAttr(OWLClassA_.stringAttribute)); - final String generatedSoqlQuery = - ((CriteriaQueryImpl) query).translateQuery(criteriaParameterFiller); + final String generatedSoqlQuery = query.translateQuery(criteriaParameterFiller); final String expectedSoqlQuery = "SELECT owlclassa.stringAttribute FROM OWLClassA owlclassa"; assertEquals(expectedSoqlQuery, generatedSoqlQuery); } @Test public void testTranslateQuerySelectPropertyPath() { - CriteriaQuery query = cb.createQuery(String.class); + CriteriaQueryImpl query = cb.createQuery(String.class); Root root = query.from(OWLClassD.class); query.select(root.getAttr(OWLClassD_.owlClassA).getAttr(OWLClassA_.stringAttribute)); - final String generatedSoqlQuery = - ((CriteriaQueryImpl) query).translateQuery(criteriaParameterFiller); + final String generatedSoqlQuery = query.translateQuery(criteriaParameterFiller); final String expectedSoqlQuery = "SELECT owlclassd.owlClassA.stringAttribute FROM OWLClassD owlclassd"; assertEquals(expectedSoqlQuery, generatedSoqlQuery); } @Test public void testTranslateQueryRestrictionWithLiteral() { - CriteriaQuery query = cb.createQuery(OWLClassA.class); + CriteriaQueryImpl query = cb.createQuery(OWLClassA.class); Root root = query.from(OWLClassA.class); query.select(root).where(cb.equal(root.getAttr(OWLClassA_.stringAttribute), cb.literal("value"))); - final String generatedSoqlQuery = - ((CriteriaQueryImpl) query).translateQuery(criteriaParameterFiller); + final String generatedSoqlQuery = query.translateQuery(criteriaParameterFiller); final String expectedSoqlQuery = "SELECT owlclassa FROM OWLClassA owlclassa WHERE owlclassa.stringAttribute = :generatedName0"; assertEquals(expectedSoqlQuery, generatedSoqlQuery); @@ -563,17 +568,15 @@ public void testTranslateQueryRestrictionWithLiteral() { @Test public void testTranslateQueryRestrictionWithParameterExpression() { - CriteriaQuery query = cb.createQuery(OWLClassA.class); + CriteriaQueryImpl query = cb.createQuery(OWLClassA.class); Root root = query.from(OWLClassA.class); ParameterExpression parameter = cb.parameter(String.class); query.select(root).where(cb.equal(root.getAttr(OWLClassA_.stringAttribute), parameter)); - final String generatedSoqlQuery = - ((CriteriaQueryImpl) query).translateQuery(criteriaParameterFiller); + final String generatedSoqlQuery = query.translateQuery(criteriaParameterFiller); final String expectedSoqlQuery = "SELECT owlclassa FROM OWLClassA owlclassa WHERE owlclassa.stringAttribute = :generatedName0"; assertEquals(expectedSoqlQuery, generatedSoqlQuery); } - } } diff --git a/jopa-impl/src/test/java/cz/cvut/kbss/jopa/query/soql/SoqlQueryParserTest.java b/jopa-impl/src/test/java/cz/cvut/kbss/jopa/query/soql/SoqlQueryParserTest.java index 4581a62df..feac7d838 100644 --- a/jopa-impl/src/test/java/cz/cvut/kbss/jopa/query/soql/SoqlQueryParserTest.java +++ b/jopa-impl/src/test/java/cz/cvut/kbss/jopa/query/soql/SoqlQueryParserTest.java @@ -1,21 +1,21 @@ /** * Copyright (C) 2023 Czech Technical University in Prague - * - * This program is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software - * Foundation, either version 3 of the License, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. You should have received a copy of the GNU General Public License - * along with this program. If not, see . + *

+ * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later + * version. + *

+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. You should have received a copy of the GNU General Public License along with this program. If not, see + * . */ package cz.cvut.kbss.jopa.query.soql; +import cz.cvut.kbss.jopa.environment.Person; import cz.cvut.kbss.jopa.environment.Vocabulary; import cz.cvut.kbss.jopa.environment.utils.MetamodelMocks; +import cz.cvut.kbss.jopa.exception.SoqlException; import cz.cvut.kbss.jopa.model.MetamodelImpl; import cz.cvut.kbss.jopa.query.QueryHolder; import cz.cvut.kbss.jopa.query.QueryParser; @@ -33,9 +33,13 @@ import org.mockito.junit.jupiter.MockitoSettings; import org.mockito.quality.Strictness; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -726,6 +730,20 @@ void parseQueryWithIdentifierAndAttributeIsCommutative() { parseAndAssertEquality(soqlIdSecond, expectedSparql); } + @Test + void parseQueryWithTypesAndMemberOf() { + final String soql = "SELECT p FROM Person p WHERE :type MEMBER OF p.types"; + final String expectedSparql = "SELECT ?x WHERE { ?x a " + strUri(Vocabulary.c_Person) + " . ?x a ?type . }"; + parseAndAssertEquality(soql, expectedSparql); + } + + @Test + void parseQueryWithMemberOfPluralAttribute() { + final String soql = "SELECT f FROM OWLClassF f WHERE :aInstance MEMBER OF f.simpleSet"; + final String expectedSparql = "SELECT ?x WHERE { ?x a " + strUri(Vocabulary.c_OwlClassF) + " . ?x " + strUri(Vocabulary.p_f_setAttribute) + " ?aInstance . }"; + parseAndAssertEquality(soql, expectedSparql); + } + /** * Bug #178 */ @@ -739,4 +757,35 @@ void parseQueryWithRelatedAttributeAndIdentifierIsCommutative() { parseAndAssertEquality(soqlIdFirst, expectedSparql); parseAndAssertEquality(soqlIdSecond, expectedSparql); } + + @Test + void parseQuerySupportsLangExtractionAndComparison() { + final String soql = "SELECT u FROM OWLClassU u WHERE LANG(u.singularStringAtt) = :language"; + final String expectedSparql = "SELECT ?x WHERE { ?x a " + strUri(Vocabulary.c_OwlClassU) + " . " + + "?x " + strUri(Vocabulary.P_U_SINGULAR_MULTILINGUAL_ATTRIBUTE) + " ?uSingularStringAtt . " + + "FILTER (lang(?uSingularStringAtt) = ?language) }"; + parseAndAssertEquality(soql, expectedSparql); + } + + @Test + void parseQuerySupportsCountById() { + final String soql = "SELECT COUNT(a) FROM OWLClassA a WHERE a.uri = :id"; + final String expectedSparql = "SELECT (COUNT(?id) AS ?count) WHERE { ?id a " + strUri(Vocabulary.c_OwlClassA) + " . }"; + parseAndAssertEquality(soql, expectedSparql); + } + + @Test + void parseQueryThrowsSoqlExceptionWhenUnknownAttributeNameIsUsed() { + final String soql = "SELECT p FROM Person p WHERE p.unknownAttribute = :param"; + when(metamodel.entity(Person.class).getAttribute(anyString())).thenThrow(IllegalArgumentException.class); + final SoqlException ex = assertThrows(SoqlException.class, () -> sut.parseQuery(soql)); + assertThat(ex.getMessage(), containsString("No matching attribute")); + } + + @Test + void parseQueryTranslatesNotMemberOfToFilterNotExists() { + final String soql = "SELECT p FROM Person p WHERE :disabledType NOT MEMBER OF p.types"; + final String expectedSparql = "SELECT ?x WHERE { ?x a " + strUri(Vocabulary.c_Person) + " . FILTER NOT EXISTS { ?x a ?disabledType . } }"; + parseAndAssertEquality(soql, expectedSparql); + } } diff --git a/jopa-impl/src/test/java/cz/cvut/kbss/jopa/utils/IdentifierTransformerTest.java b/jopa-impl/src/test/java/cz/cvut/kbss/jopa/utils/IdentifierTransformerTest.java index 1064fde8e..306343bb0 100644 --- a/jopa-impl/src/test/java/cz/cvut/kbss/jopa/utils/IdentifierTransformerTest.java +++ b/jopa-impl/src/test/java/cz/cvut/kbss/jopa/utils/IdentifierTransformerTest.java @@ -14,13 +14,16 @@ */ package cz.cvut.kbss.jopa.utils; +import cz.cvut.kbss.jopa.environment.utils.Generators; import org.junit.jupiter.api.Test; import java.net.URI; import java.net.URL; import java.util.Date; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; class IdentifierTransformerTest { @@ -53,4 +56,10 @@ void transformThrowsIllegalArgumentForUnsupportedTargetType() { assertThrows(IllegalArgumentException.class, () -> IdentifierTransformer.transformToIdentifier(IDENTIFIER, Date.class)); } + + @Test + void stringifyIriReturnsSpecifiedIriInAngledBrackets() { + final URI uri = Generators.createIndividualIdentifier(); + assertEquals("<" + uri + ">", IdentifierTransformer.stringifyIri(uri)); + } } diff --git a/jopa-integration-tests-jena/pom.xml b/jopa-integration-tests-jena/pom.xml index 3bb41bd76..a9d84a1a0 100644 --- a/jopa-integration-tests-jena/pom.xml +++ b/jopa-integration-tests-jena/pom.xml @@ -5,7 +5,7 @@ cz.cvut.kbss.jopa jopa-all - 1.0.0 + 1.1.0 ../pom.xml 4.0.0 diff --git a/jopa-integration-tests-jena/src/main/java/cz/cvut/kbss/jopa/DummyClass.java b/jopa-integration-tests-jena/src/main/java/cz/cvut/kbss/jopa/DummyClass.java new file mode 100644 index 000000000..bd7a770a3 --- /dev/null +++ b/jopa-integration-tests-jena/src/main/java/cz/cvut/kbss/jopa/DummyClass.java @@ -0,0 +1,8 @@ +package cz.cvut.kbss.jopa; + +/** + * This is just an empty class to prevent AspectJ Maven plugin warnings for missing sources. + */ +@SuppressWarnings("unused") +public class DummyClass { +} diff --git a/jopa-integration-tests-owlapi/pom.xml b/jopa-integration-tests-owlapi/pom.xml index 8fbbe8484..6793d2d47 100644 --- a/jopa-integration-tests-owlapi/pom.xml +++ b/jopa-integration-tests-owlapi/pom.xml @@ -5,7 +5,7 @@ cz.cvut.kbss.jopa jopa-all - 1.0.0 + 1.1.0 ../pom.xml 4.0.0 diff --git a/jopa-integration-tests-owlapi/src/main/java/cz/cvut/kbss/jopa/DummyClass.java b/jopa-integration-tests-owlapi/src/main/java/cz/cvut/kbss/jopa/DummyClass.java new file mode 100644 index 000000000..bd7a770a3 --- /dev/null +++ b/jopa-integration-tests-owlapi/src/main/java/cz/cvut/kbss/jopa/DummyClass.java @@ -0,0 +1,8 @@ +package cz.cvut.kbss.jopa; + +/** + * This is just an empty class to prevent AspectJ Maven plugin warnings for missing sources. + */ +@SuppressWarnings("unused") +public class DummyClass { +} diff --git a/jopa-integration-tests-rdf4j/pom.xml b/jopa-integration-tests-rdf4j/pom.xml index 441b295d8..7bb265dea 100644 --- a/jopa-integration-tests-rdf4j/pom.xml +++ b/jopa-integration-tests-rdf4j/pom.xml @@ -6,7 +6,7 @@ cz.cvut.kbss.jopa jopa-all - 1.0.0 + 1.1.0 ../pom.xml jopa-integration-tests-rdf4j diff --git a/jopa-integration-tests-rdf4j/src/main/java/cz/cvut/kbss/jopa/DummyClass.java b/jopa-integration-tests-rdf4j/src/main/java/cz/cvut/kbss/jopa/DummyClass.java new file mode 100644 index 000000000..bd7a770a3 --- /dev/null +++ b/jopa-integration-tests-rdf4j/src/main/java/cz/cvut/kbss/jopa/DummyClass.java @@ -0,0 +1,8 @@ +package cz.cvut.kbss.jopa; + +/** + * This is just an empty class to prevent AspectJ Maven plugin warnings for missing sources. + */ +@SuppressWarnings("unused") +public class DummyClass { +} diff --git a/jopa-integration-tests/pom.xml b/jopa-integration-tests/pom.xml index 5a698c35c..3e0df19bd 100644 --- a/jopa-integration-tests/pom.xml +++ b/jopa-integration-tests/pom.xml @@ -6,7 +6,7 @@ cz.cvut.kbss.jopa jopa-all - 1.0.0 + 1.1.0 ../pom.xml 4.0.0 diff --git a/jopa-integration-tests/src/main/java/cz/cvut/kbss/jopa/test/query/QueryTestEnvironment.java b/jopa-integration-tests/src/main/java/cz/cvut/kbss/jopa/test/query/QueryTestEnvironment.java index c103d6dce..f841f1a57 100644 --- a/jopa-integration-tests/src/main/java/cz/cvut/kbss/jopa/test/query/QueryTestEnvironment.java +++ b/jopa-integration-tests/src/main/java/cz/cvut/kbss/jopa/test/query/QueryTestEnvironment.java @@ -15,9 +15,11 @@ package cz.cvut.kbss.jopa.test.query; import cz.cvut.kbss.jopa.model.EntityManager; +import cz.cvut.kbss.jopa.model.MultilingualString; import cz.cvut.kbss.jopa.model.descriptors.EntityDescriptor; import cz.cvut.kbss.jopa.test.*; import cz.cvut.kbss.jopa.test.environment.Generators; +import cz.cvut.kbss.jopa.test.environment.TestEnvironment; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -32,7 +34,7 @@ public final class QueryTestEnvironment { private static final int ITEM_COUNT = 10; private static final String BASE_A = "http://krizik.felk.cvut.cz/ontologies/jopa/tests/entityA_"; - private static final String TYPE_A = "http://krizik.felk.cvut.cz/ontologies/jopa/entities#TypeA"; + public static final String COMMON_TYPE = "http://krizik.felk.cvut.cz/ontologies/jopa/entities#TypeA"; private static final String BASE_B = "http://krizik.felk.cvut.cz/ontologies/jopa/tests/entityB_"; private static final String BASE_D = "http://krizik.felk.cvut.cz/ontologies/jopa/tests/entityD_"; @@ -169,18 +171,22 @@ private static Map, List> generate() { m.put(OWLClassJ.class, generateOwlClassJInstances(aa)); m.put(OWLClassM.class, generateOwlClassMInstances()); m.put(OWLClassT.class, generateOwlClassTInstances(aa)); + m.put(OWLClassY.class, generateOwlClassYInstances()); return m; } private static List generateOwlClassAInstances() { final List lst = new ArrayList<>(ITEM_COUNT); + final String typeOne = Generators.generateUri().toString(); + final String typeTwo = Generators.generateUri().toString(); int randomNum = Generators.randomInt(1000); for (int i = 0; i < ITEM_COUNT; i++) { final OWLClassA a = new OWLClassA(); a.setUri(URI.create(BASE_A + randomNum)); a.setStringAttribute("stringAttribute" + randomNum); final Set s = new HashSet<>(); - s.add(TYPE_A); + s.add(COMMON_TYPE); + s.add(Generators.randomBoolean() ? typeOne : typeTwo); a.setTypes(s); lst.add(a); randomNum++; @@ -268,4 +274,25 @@ private static List generateOwlClassMInstances() { } return lst; } + + private static List generateOwlClassYInstances() { + final List lst = new ArrayList<>(); + for (int i = 0; i < ITEM_COUNT; i++) { + final OWLClassY y = new OWLClassY(); + y.setSingularString(MultilingualString.create("Test" + i, TestEnvironment.PERSISTENCE_LANGUAGE)); + switch (Generators.randomPositiveInt(0, 3)) { + case 0: + y.getSingularString().set("Testwert nummer " + i, "de"); + break; + case 1: + y.getSingularString().set("Testovací hodnota číslo " + i, "cs"); + break; + case 2: + y.getSingularString().set("nombre de valeurs de test " + i, "fr"); + break; + } + lst.add(y); + } + return lst; + } } diff --git a/jopa-integration-tests/src/main/java/cz/cvut/kbss/jopa/test/query/runner/CriteriaRunner.java b/jopa-integration-tests/src/main/java/cz/cvut/kbss/jopa/test/query/runner/CriteriaRunner.java index 98a05faa2..2bfc8c167 100644 --- a/jopa-integration-tests/src/main/java/cz/cvut/kbss/jopa/test/query/runner/CriteriaRunner.java +++ b/jopa-integration-tests/src/main/java/cz/cvut/kbss/jopa/test/query/runner/CriteriaRunner.java @@ -26,6 +26,7 @@ import cz.cvut.kbss.jopa.test.OWLClassJ; import cz.cvut.kbss.jopa.test.OWLClassM; import cz.cvut.kbss.jopa.test.OWLClassT; +import cz.cvut.kbss.jopa.test.OWLClassY; import cz.cvut.kbss.jopa.test.environment.DataAccessor; import cz.cvut.kbss.jopa.test.environment.Generators; import cz.cvut.kbss.jopa.test.environment.TestEnvironment; @@ -39,10 +40,12 @@ import java.util.Comparator; import java.util.List; import java.util.Locale; +import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; import static cz.cvut.kbss.jopa.test.environment.util.ContainsSameEntities.containsSameEntities; +import static java.util.function.Predicate.not; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.hasItem; import static org.hamcrest.Matchers.lessThanOrEqualTo; @@ -469,4 +472,35 @@ public void selectByIdAndRelatedAttributeValueIsCommutative() { final OWLClassD resultIdSecond = getEntityManager().createQuery(queryIdSecond).getSingleResult(); assertEquals(instance.getUri(), resultIdSecond.getUri()); } + + @Test + public void selectByLanguageTag() { + final String language = Generators.getRandomItem(List.of("de", "cs", "fr")); + final List expected = QueryTestEnvironment.getData(OWLClassY.class).stream() + .filter(y -> y.getSingularString().getLanguages() + .contains(language)) + .collect(Collectors.toList()); + final CriteriaBuilder cb = getEntityManager().getCriteriaBuilder(); + final CriteriaQuery query = cb.createQuery(OWLClassY.class); + final Root root = query.from(OWLClassY.class); + query.select(root).where(cb.equal(cb.lang(root.getAttr("singularString")), language)); + + final List result = getEntityManager().createQuery(query).getResultList(); + assertThat(result, containsSameEntities(expected)); + } + + @Test + public void selectByTypeContainingMember() { + final OWLClassA sample = Generators.getRandomItem(QueryTestEnvironment.getData(OWLClassA.class)); + final Optional type = sample.getTypes().stream().filter(not(QueryTestEnvironment.COMMON_TYPE::equals)).findFirst(); + assert type.isPresent(); + final CriteriaBuilder cb = getEntityManager().getCriteriaBuilder(); + final CriteriaQuery query = cb.createQuery(OWLClassA.class); + final Root root = query.from(OWLClassA.class); + query.select(root).where(cb.isMember(URI.create(type.get()), root.getAttr("types"))); + + final List result = getEntityManager().createQuery(query).getResultList(); + assertFalse(result.isEmpty()); + result.forEach(r -> assertThat(r.getTypes(), hasItem(type.get()))); + } } diff --git a/jopa-maven-plugin/pom.xml b/jopa-maven-plugin/pom.xml index 27b5538a4..b7e413500 100644 --- a/jopa-maven-plugin/pom.xml +++ b/jopa-maven-plugin/pom.xml @@ -5,7 +5,7 @@ jopa-all cz.cvut.kbss.jopa - 1.0.0 + 1.1.0 ../pom.xml 4.0.0 diff --git a/jopa-owl2java/pom.xml b/jopa-owl2java/pom.xml index a5e361aeb..09041149e 100644 --- a/jopa-owl2java/pom.xml +++ b/jopa-owl2java/pom.xml @@ -6,7 +6,7 @@ cz.cvut.kbss.jopa jopa-all - 1.0.0 + 1.1.0 ../pom.xml diff --git a/jopa-owlapi-utils/pom.xml b/jopa-owlapi-utils/pom.xml index 76e69e45b..11afdbf78 100644 --- a/jopa-owlapi-utils/pom.xml +++ b/jopa-owlapi-utils/pom.xml @@ -6,7 +6,7 @@ cz.cvut.kbss.jopa jopa-all - 1.0.0 + 1.1.0 ../pom.xml diff --git a/modelgen/pom.xml b/modelgen/pom.xml index 4ea57dc8f..629fd0fcc 100644 --- a/modelgen/pom.xml +++ b/modelgen/pom.xml @@ -6,7 +6,7 @@ jopa-all cz.cvut.kbss.jopa - 1.0.0 + 1.1.0 ../pom.xml diff --git a/ontodriver-api/pom.xml b/ontodriver-api/pom.xml index f344ac053..7200883f8 100644 --- a/ontodriver-api/pom.xml +++ b/ontodriver-api/pom.xml @@ -6,7 +6,7 @@ jopa-all cz.cvut.kbss.jopa - 1.0.0 + 1.1.0 ../pom.xml diff --git a/ontodriver-jena/pom.xml b/ontodriver-jena/pom.xml index a5c59ad5b..f29be7caa 100644 --- a/ontodriver-jena/pom.xml +++ b/ontodriver-jena/pom.xml @@ -8,7 +8,7 @@ cz.cvut.kbss.jopa jopa-all - 1.0.0 + 1.1.0 ../pom.xml @@ -17,7 +17,7 @@ Jena implementation of the OntoDriver API - 4.8.0 + 4.9.0 diff --git a/ontodriver-owlapi/pom.xml b/ontodriver-owlapi/pom.xml index 1d4f0e7c3..c31c0cea9 100644 --- a/ontodriver-owlapi/pom.xml +++ b/ontodriver-owlapi/pom.xml @@ -11,7 +11,7 @@ cz.cvut.kbss.jopa jopa-all - 1.0.0 + 1.1.0 ../pom.xml diff --git a/ontodriver-rdf4j/pom.xml b/ontodriver-rdf4j/pom.xml index 63e5f3d9c..e18804626 100644 --- a/ontodriver-rdf4j/pom.xml +++ b/ontodriver-rdf4j/pom.xml @@ -10,11 +10,11 @@ jopa-all cz.cvut.kbss.jopa - 1.0.0 + 1.1.0 - 4.3.2 + 4.3.4 2.0.9 diff --git a/ontodriver-rdf4j/src/main/java/cz/cvut/kbss/ontodriver/rdf4j/connector/init/RepositoryConnectorInitializer.java b/ontodriver-rdf4j/src/main/java/cz/cvut/kbss/ontodriver/rdf4j/connector/init/RepositoryConnectorInitializer.java index 4246f0957..66717d81b 100644 --- a/ontodriver-rdf4j/src/main/java/cz/cvut/kbss/ontodriver/rdf4j/connector/init/RepositoryConnectorInitializer.java +++ b/ontodriver-rdf4j/src/main/java/cz/cvut/kbss/ontodriver/rdf4j/connector/init/RepositoryConnectorInitializer.java @@ -23,6 +23,7 @@ import cz.cvut.kbss.ontodriver.rdf4j.exception.RepositoryNotFoundException; import org.eclipse.rdf4j.model.Model; import org.eclipse.rdf4j.model.Resource; +import org.eclipse.rdf4j.model.vocabulary.CONFIG; import org.eclipse.rdf4j.model.vocabulary.RDF; import org.eclipse.rdf4j.repository.Repository; import org.eclipse.rdf4j.repository.RepositoryException; @@ -163,11 +164,17 @@ private Repository createRepositoryFromConfig() { return manager.getRepository(getRepositoryId()); } + @SuppressWarnings("deprecated") private RepositoryConfig loadRepositoryConfig() { try (final InputStream is = getConfigFileContent()) { final Model configModel = Rio.parse(is, "", RDFFormat.TURTLE); - final Set resources = - configModel.filter(null, RDF.TYPE, RepositoryConfigSchema.REPOSITORY).subjects(); + Set resources = + configModel.filter(null, RDF.TYPE, CONFIG.Rep.Repository).subjects(); + if (resources.isEmpty()) { + // Support for legacy repository configuration vocabulary. + // https://rdf4j.org/documentation/reference/configuration/#migrating-old-configurations + resources = configModel.filter(null, RDF.TYPE, RepositoryConfigSchema.REPOSITORY).subjects(); + } assert resources.size() == 1; return RepositoryConfig.create(configModel, resources.iterator().next()); } catch (IOException e) { diff --git a/ontodriver-rdf4j/src/test/java/cz/cvut/kbss/ontodriver/rdf4j/connector/StorageConnectorTest.java b/ontodriver-rdf4j/src/test/java/cz/cvut/kbss/ontodriver/rdf4j/connector/StorageConnectorTest.java index 64fa14086..64c7a942b 100644 --- a/ontodriver-rdf4j/src/test/java/cz/cvut/kbss/ontodriver/rdf4j/connector/StorageConnectorTest.java +++ b/ontodriver-rdf4j/src/test/java/cz/cvut/kbss/ontodriver/rdf4j/connector/StorageConnectorTest.java @@ -230,6 +230,16 @@ void initializationLoadsRepositoryConfigurationFromFileOnClasspathAndCreatesRepo assertTrue(((SailRepository) repo).getSail() instanceof SchemaCachingRDFSInferencer); } + @Test + void initializationSupportsLegacyRepositoryConfigurationVocabulary() throws Exception { + final DriverConfiguration conf = TestUtils.createDriverConfig("test"); + conf.setProperty(Rdf4jConfigParam.REPOSITORY_CONFIG, "classpath:repo-configs/memory-rdfs-legacy.ttl"); + this.connector = createConnector(conf); + final Repository repo = connector.unwrap(Repository.class); + assertTrue(repo instanceof SailRepository); + assertTrue(((SailRepository) repo).getSail() instanceof SchemaCachingRDFSInferencer); + } + @Test void initializationLoadsRepositoryConfigurationFromFileWithAbsolutePathAndCreatesRepo() throws Exception { final Path file = Files.createTempFile("memory-rdfs", ".ttl"); diff --git a/ontodriver-rdf4j/src/test/resources/repo-configs/memory-rdfs-legacy.ttl b/ontodriver-rdf4j/src/test/resources/repo-configs/memory-rdfs-legacy.ttl new file mode 100644 index 000000000..aae46265f --- /dev/null +++ b/ontodriver-rdf4j/src/test/resources/repo-configs/memory-rdfs-legacy.ttl @@ -0,0 +1,23 @@ +@prefix rdfs: . +@prefix rep: . +@prefix sr: . +@prefix sail: . +@prefix ms: . +@prefix sb: . + + +[] a rep:Repository ; + rep:repositoryID "test" ; + rdfs:label "Memory store with RDF Schema inferencing" ; + rep:repositoryImpl [ + rep:repositoryType "openrdf:SailRepository" ; + sr:sailImpl [ + sail:sailType "rdf4j:SchemaCachingRDFSInferencer" ; + sail:delegate [ + sail:sailType "openrdf:MemoryStore" ; + sail:iterationCacheSyncThreshold "10000"; + ms:persist false ; + sb:evaluationStrategyFactory "org.eclipse.rdf4j.query.algebra.evaluation.impl.StrictEvaluationStrategyFactory" + ] + ] + ]. diff --git a/ontodriver-rdf4j/src/test/resources/repo-configs/memory-rdfs.ttl b/ontodriver-rdf4j/src/test/resources/repo-configs/memory-rdfs.ttl index aae46265f..af4dba7d6 100644 --- a/ontodriver-rdf4j/src/test/resources/repo-configs/memory-rdfs.ttl +++ b/ontodriver-rdf4j/src/test/resources/repo-configs/memory-rdfs.ttl @@ -1,23 +1,18 @@ @prefix rdfs: . -@prefix rep: . -@prefix sr: . -@prefix sail: . -@prefix ms: . -@prefix sb: . +@prefix config: . - -[] a rep:Repository ; - rep:repositoryID "test" ; - rdfs:label "Memory store with RDF Schema inferencing" ; - rep:repositoryImpl [ - rep:repositoryType "openrdf:SailRepository" ; - sr:sailImpl [ - sail:sailType "rdf4j:SchemaCachingRDFSInferencer" ; - sail:delegate [ - sail:sailType "openrdf:MemoryStore" ; - sail:iterationCacheSyncThreshold "10000"; - ms:persist false ; - sb:evaluationStrategyFactory "org.eclipse.rdf4j.query.algebra.evaluation.impl.StrictEvaluationStrategyFactory" - ] +[] a config:Repository ; + config:rep.id "test" ; + rdfs:label "Example memory store with RDF Schema entailment" ; + config:rep.impl [ + config:rep.type "openrdf:SailRepository" ; + config:sail.impl [ + config:sail.type "rdf4j:SchemaCachingRDFSInferencer"; + config:delegate [ + config:sail.type "openrdf:MemoryStore" ; + config:sail.iterationCacheSyncThreshold "10000"; + config:mem.persist false; + config:sail.evaluationStrategyFactory "org.eclipse.rdf4j.query.algebra.evaluation.impl.StrictEvaluationStrategyFactory" + ]; ] ]. diff --git a/ontodriver-rdf4j/src/test/resources/repo-configs/native-lucene.ttl b/ontodriver-rdf4j/src/test/resources/repo-configs/native-lucene.ttl index dfa4fb7dc..daafff115 100644 --- a/ontodriver-rdf4j/src/test/resources/repo-configs/native-lucene.ttl +++ b/ontodriver-rdf4j/src/test/resources/repo-configs/native-lucene.ttl @@ -1,28 +1,20 @@ @prefix rdfs: . -@prefix rep: . -@prefix sr: . -@prefix sail: . -@prefix spin: . -@prefix sail-luc: . -@prefix cgqi: . -@prefix ns: . -@prefix sp: . -@prefix sb: . +@prefix config: . -[] a rep:Repository ; - rep:repositoryID "native-lucene" ; +[] a config:Repository ; + config:rep.id "native-lucene" ; rdfs:label "Native store with Lucene Support" ; - rep:repositoryImpl [ - rep:repositoryType "openrdf:SailRepository" ; - sr:sailImpl [ - sail:sailType "openrdf:LuceneSail"; - sail-luc:indexDir "index/" ; - sail:delegate [ - sail:sailType "openrdf:NativeStore" ; - sail:iterationCacheSyncThreshold "10000"; - ns:tripleIndexes "spoc,posc"; - sb:evaluationStrategyFactory "org.eclipse.rdf4j.query.algebra.evaluation.impl.StrictEvaluationStrategyFactory" + config:rep.impl [ + config:rep.type "openrdf:SailRepository" ; + config:sail.impl [ + config:sail.type "openrdf:LuceneSail"; + config:lucene.indexDir "index/" ; + config:delegate [ + config:sail.type "openrdf:NativeStore" ; + config:sail.iterationCacheSyncThreshold "10000"; + config:native.tripleIndexes "spoc,posc"; + config:sail.evaluationStrategyFactory "org.eclipse.rdf4j.query.algebra.evaluation.impl.StrictEvaluationStrategyFactory" ] ] -]. \ No newline at end of file +]. diff --git a/pom.xml b/pom.xml index 1d0dfcea6..1b470fd7f 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 cz.cvut.kbss.jopa - 1.0.0 + 1.1.0 jopa-all pom JOPA