Skip to content

Commit

Permalink
Merge pull request #188 from kbss-cvut/development
Browse files Browse the repository at this point in the history
[1.1.0] Release
  • Loading branch information
ledsoft authored Jul 28, 2023
2 parents 62226dc + 37998d7 commit 24ab2d9
Show file tree
Hide file tree
Showing 58 changed files with 863 additions and 362 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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).
Expand Down
2 changes: 1 addition & 1 deletion datatype/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<parent>
<artifactId>jopa-all</artifactId>
<groupId>cz.cvut.kbss.jopa</groupId>
<version>1.0.0</version>
<version>1.1.0</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
2 changes: 1 addition & 1 deletion jopa-api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<parent>
<groupId>cz.cvut.kbss.jopa</groupId>
<artifactId>jopa-all</artifactId>
<version>1.0.0</version>
<version>1.1.0</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -125,6 +126,14 @@ public interface CriteriaBuilder extends PredicateFactory {
*/
Expression<String> upper(Expression<String> x);

/**
* Create expression for extracting language tag from a string literal.
*
* @param x String-valued attribute
* @return Expression to extract language tag
*/
Expression<String> lang(Path<String> x);

/**
* Create an ordering by the ascending value of the expression.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {

/**
Expand Down Expand Up @@ -112,7 +114,8 @@ public interface PredicateFactory {
* @param y expression
* @return greaterThanOrEqual predicate
*/
<Y extends Comparable<? super Y>> Predicate greaterThanOrEqual(Expression<? extends Y> x, Expression<? extends Y> y);
<Y extends Comparable<? super Y>> Predicate greaterThanOrEqual(Expression<? extends Y> x,
Expression<? extends Y> y);

/**
* Create a predicate for testing whether the first argument is greater than or equal to the second.
Expand Down Expand Up @@ -186,6 +189,26 @@ public interface PredicateFactory {
*/
Predicate notLike(Expression<String> 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
*/
<E, C extends Collection<E>> Predicate isMember(E elem, Expression<C> 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
*/
<E, C extends Collection<E>> Predicate isNotMember(E elem, Expression<C> collection);

/**
* Create a negation of the given restriction.
* @param restriction restriction expression
Expand Down
2 changes: 1 addition & 1 deletion jopa-distribution/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<parent>
<groupId>cz.cvut.kbss.jopa</groupId>
<artifactId>jopa-all</artifactId>
<version>1.0.0</version>
<version>1.1.0</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
2 changes: 1 addition & 1 deletion jopa-impl/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<parent>
<groupId>cz.cvut.kbss.jopa</groupId>
<artifactId>jopa-all</artifactId>
<version>1.0.0</version>
<version>1.1.0</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
10 changes: 9 additions & 1 deletion jopa-impl/src/main/antlr4/cz/cvut/kbss/jopa/query/soql/Soql.g4
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ simpleConditionalExpression
: comparisonExpression
| likeExpression
| inExpression
| memberOfExpression
;

inExpression
Expand All @@ -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
Expand All @@ -102,6 +107,7 @@ functionsReturningStrings
| 'SUBSTRING' '(' stringExpression ',' simpleArithmeticExpression ',' simpleArithmeticExpression ')'
| 'LOWER' '(' stringExpression ')'
| 'UPPER' '(' stringExpression ')'
| 'LANG' '(' whereClauseParam ')'
;

simpleArithmeticExpression
Expand Down Expand Up @@ -181,6 +187,8 @@ LIKE: 'LIKE' ;

IN: 'IN' ;

MEMBEROF: 'MEMBER OF' ;

COMPARISON_OPERATOR: '>' | '<' | '>=' | '<=' | '=' | '<>' | '!=' ;

DOT: '.' ;
Expand Down
Original file line number Diff line number Diff line change
@@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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);
}
Expand All @@ -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());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {

Expand All @@ -31,7 +58,7 @@ public CriteriaBuilderImpl(UnitOfWorkImpl uow) {
}

@Override
public <T> CriteriaQuery<T> createQuery(Class<T> resultClass) {
public <T> CriteriaQueryImpl<T> createQuery(Class<T> resultClass) {
return new CriteriaQueryImpl<>(new CriteriaQueryHolder<>(resultClass), uow.getMetamodel(), this);
}

Expand All @@ -41,6 +68,12 @@ public <N extends Number> Expression<N> abs(Expression<N> x) {
return new AbsFunction<>((Class<N>) 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<Integer> count(Expression<?> x) {
validateFunctionArgument(x);
Expand Down Expand Up @@ -101,10 +134,10 @@ public Expression<String> upper(Expression<String> 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<String> lang(Path<String> x) {
validateFunctionArgument(x);
return new LangFunction((AbstractPathExpression) x, this);
}

@Override
Expand Down Expand Up @@ -219,6 +252,18 @@ public <T> In<T> notIn(Expression<? extends T> expression) {
return inExpression;
}

@Override
public <E, C extends Collection<E>> Predicate isMember(E elem, Expression<C> collection) {
return new IsMemberExpression<>(elem, collection, this);
}

@Override
public <E, C extends Collection<E>> Predicate isNotMember(E elem, Expression<C> collection) {
final IsMemberExpression<E> expr = new IsMemberExpression<>(elem, collection, this);
expr.not();
return expr;
}

@Override
public <Y extends Comparable<? super Y>> Predicate greaterThan(Expression<? extends Y> x,
Expression<? extends Y> y) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -34,6 +35,9 @@ public PathImpl(Metamodel metamodel, AbstractPathExpression pathSource, FieldSpe
}

private static <E> Class<E> resolveBindableJavaType(FieldSpecification<?, ?> attribute) {
if (attribute instanceof TypesSpecification) {
return ((TypesSpecification) attribute).getElementType();
}
assert attribute instanceof Bindable;
return ((Bindable<E>) attribute).getBindableJavaType();
}
Expand Down
Loading

0 comments on commit 24ab2d9

Please sign in to comment.