Skip to content

Commit

Permalink
Merge pull request #470 from eclipse/add-operation-annotation
Browse files Browse the repository at this point in the history
Include Support to Annotation operation
  • Loading branch information
otaviojava authored Dec 28, 2023
2 parents 877f742 + 8900efe commit f772d44
Show file tree
Hide file tree
Showing 20 changed files with 1,313 additions and 357 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ and this project adheres to https://semver.org/spec/v2.0.0.html[Semantic Version

- Upgrade Jakarta Data to version 1.0.0-M2

=== Added

- Add support to operations annotations (Insert, Update, Delete and Save) from Jakarta Data

== [1.0.4] - 2023-12-19

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,10 @@
*/
package org.eclipse.jnosql.mapping.column.query;

import jakarta.data.exceptions.MappingException;
import jakarta.data.repository.PageableRepository;
import jakarta.enterprise.inject.spi.CDI;
import org.eclipse.jnosql.communication.column.ColumnDeleteQuery;
import org.eclipse.jnosql.communication.column.ColumnQuery;
import org.eclipse.jnosql.mapping.core.Converters;
import org.eclipse.jnosql.mapping.core.query.RepositoryType;
import org.eclipse.jnosql.mapping.core.repository.DynamicQueryMethodReturn;
import org.eclipse.jnosql.mapping.core.repository.ThrowingSupplier;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
Expand All @@ -34,73 +26,48 @@
* @param <T> the entity type
* @param <K> the K entity
*/
public abstract class AbstractColumnRepositoryProxy<T, K> extends BaseColumnRepository<T> implements InvocationHandler {
public abstract class AbstractColumnRepositoryProxy<T, K> extends BaseColumnRepository<T, K> {

protected abstract PageableRepository<T, K> getRepository();
@Override
protected Object executeQuery(Object instance, Method method, Object[] params) {
Class<?> type = entityMetadata().type();
DynamicQueryMethodReturn methodReturn = DynamicQueryMethodReturn.builder()
.withArgs(params)
.withMethod(method)
.withTypeClass(type)
.withPrepareConverter(q -> template().prepare(q))
.withQueryConverter(q -> template().query(q)).build();
return methodReturn.execute();
}

protected abstract Converters getConverters();
@Override
protected Object executeDeleteByAll(Object instance, Method method, Object[] params) {
ColumnDeleteQuery deleteQuery = deleteQuery(method, params);
template().delete(deleteQuery);
return Void.class;
}

protected abstract Class<?> repositoryType();
@Override
protected Object executeFindAll(Object instance, Method method, Object[] params) {
Class<?> type = entityMetadata().type();
ColumnQuery queryFindAll = ColumnQuery.select().from(entityMetadata().name()).build();
return executeFindByQuery(method, params, type, updateQueryDynamically(params, queryFindAll));
}

@Override
public Object invoke(Object instance, Method method, Object[] args) throws Throwable {
RepositoryType type = RepositoryType.of(method, repositoryType());
Class<?> typeClass = getEntityMetadata().type();
protected Object executeExistByQuery(Object instance, Method method, Object[] params) {
return executeExistsByQuery(query(method, params));
}

switch (type) {
case DEFAULT -> {
return unwrapInvocationTargetException(() -> method.invoke(getRepository(), args));
}
case FIND_BY -> {
return executeFindByQuery(method, args, typeClass, getQuery(method, args));
}
case COUNT_BY -> {
return executeCountByQuery(getQuery(method, args));
}
case EXISTS_BY -> {
return executeExistsByQuery(getQuery(method, args));
}
case FIND_ALL -> {
ColumnQuery queryFindAll = ColumnQuery.select().from(getEntityMetadata().name()).build();
return executeFindByQuery(method, args, typeClass, updateQueryDynamically(args, queryFindAll));
}
case DELETE_BY -> {
ColumnDeleteQuery deleteQuery = getDeleteQuery(method, args);
getTemplate().delete(deleteQuery);
return Void.class;
}
case OBJECT_METHOD -> {
return unwrapInvocationTargetException(() -> method.invoke(this, args));
}
case DEFAULT_METHOD -> {
return unwrapInvocationTargetException(() -> InvocationHandler.invokeDefault(instance, method, args));
}
case ORDER_BY ->
throw new MappingException("Eclipse JNoSQL has not support for method that has OrderBy annotation");
case QUERY -> {
DynamicQueryMethodReturn methodReturn = DynamicQueryMethodReturn.builder()
.withArgs(args)
.withMethod(method)
.withTypeClass(typeClass)
.withPrepareConverter(q -> getTemplate().prepare(q))
.withQueryConverter(q -> getTemplate().query(q)).build();
return methodReturn.execute();
}
case CUSTOM_REPOSITORY -> {
Object customRepository = CDI.current().select(method.getDeclaringClass()).get();
return unwrapInvocationTargetException(() -> method.invoke(customRepository, args));
}
default -> {
return Void.class;
}
}
@Override
protected Object executeCountByQuery(Object instance, Method method, Object[] params) {
return executeCountByQuery(query(method, params));
}

private Object unwrapInvocationTargetException(ThrowingSupplier<Object> supplier) throws Throwable {
try {
return supplier.get();
} catch (InvocationTargetException ex) {
throw ex.getCause();
}
@Override
protected Object executeFindByQuery(Object instance, Method method, Object[] params) {
Class<?> type = entityMetadata().type();
return executeFindByQuery(method, params, type, query(method, params));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import org.eclipse.jnosql.mapping.core.Converters;
import org.eclipse.jnosql.mapping.core.NoSQLPage;
import org.eclipse.jnosql.mapping.column.JNoSQLColumnTemplate;
import org.eclipse.jnosql.mapping.core.query.AbstractRepositoryProxy;
import org.eclipse.jnosql.mapping.metadata.EntityMetadata;
import org.eclipse.jnosql.mapping.core.repository.DynamicReturn;
import org.eclipse.jnosql.mapping.core.util.ParamsBinder;
Expand All @@ -49,7 +50,7 @@
* @param <T> The type of entities managed by the repository.
*
*/
public abstract class BaseColumnRepository<T> {
public abstract class BaseColumnRepository<T, K> extends AbstractRepositoryProxy<T, K> {

private static final SelectQueryParser SELECT_PARSER = new SelectQueryParser();

Expand All @@ -61,48 +62,48 @@ public abstract class BaseColumnRepository<T> {
*
* @return The Converters instance.
*/
protected abstract Converters getConverters();
protected abstract Converters converters();

/**
* Retrieves the metadata information about the entity managed by the repository.
*
* @return The EntityMetadata instance.
*/
protected abstract EntityMetadata getEntityMetadata();
protected abstract EntityMetadata entityMetadata();

/**
* Retrieves the JNoSQLColumnTemplate instance for executing column queries.
*
* @return The JNoSQLColumnTemplate instance.
*/
protected abstract JNoSQLColumnTemplate getTemplate();
protected abstract JNoSQLColumnTemplate template();

private ColumnObserverParser parser;

private ParamsBinder paramsBinder;


protected ColumnQuery getQuery(Method method, Object[] args) {
protected ColumnQuery query(Method method, Object[] args) {
SelectMethodProvider provider = SelectMethodProvider.INSTANCE;
SelectQuery selectQuery = provider.apply(method, getEntityMetadata().name());
ColumnQueryParams queryParams = SELECT_PARSER.apply(selectQuery, getParser());
SelectQuery selectQuery = provider.apply(method, entityMetadata().name());
ColumnQueryParams queryParams = SELECT_PARSER.apply(selectQuery, parser());
ColumnQuery query = queryParams.query();
Params params = queryParams.params();
getParamsBinder().bind(params, getArgs(args), method);
return updateQueryDynamically(getArgs(args), query);
paramsBinder().bind(params, args(args), method);
return updateQueryDynamically(args(args), query);
}

private static Object[] getArgs(Object[] args) {
private static Object[] args(Object[] args) {
return args == null ? EMPTY_PARAM : args;
}

protected ColumnDeleteQuery getDeleteQuery(Method method, Object[] args) {
protected ColumnDeleteQuery deleteQuery(Method method, Object[] args) {
DeleteMethodProvider deleteMethodFactory = DeleteMethodProvider.INSTANCE;
DeleteQuery deleteQuery = deleteMethodFactory.apply(method, getEntityMetadata().name());
ColumnDeleteQueryParams queryParams = DELETE_PARSER.apply(deleteQuery, getParser());
DeleteQuery deleteQuery = deleteMethodFactory.apply(method, entityMetadata().name());
ColumnDeleteQueryParams queryParams = DELETE_PARSER.apply(deleteQuery, parser());
ColumnDeleteQuery query = queryParams.query();
Params params = queryParams.params();
getParamsBinder().bind(params, getArgs(args), method);
paramsBinder().bind(params, args(args), method);
return query;
}

Expand All @@ -112,9 +113,9 @@ protected ColumnDeleteQuery getDeleteQuery(Method method, Object[] args) {
* @return The ColumnObserverParser instance.
*/

protected ColumnObserverParser getParser() {
protected ColumnObserverParser parser() {
if (parser == null) {
this.parser = new RepositoryColumnObserverParser(getEntityMetadata());
this.parser = new RepositoryColumnObserverParser(entityMetadata());
}
return parser;
}
Expand All @@ -124,9 +125,9 @@ protected ColumnObserverParser getParser() {
*
* @return The ParamsBinder instance.
*/
protected ParamsBinder getParamsBinder() {
protected ParamsBinder paramsBinder() {
if (Objects.isNull(paramsBinder)) {
this.paramsBinder = new ParamsBinder(getEntityMetadata(), getConverters());
this.paramsBinder = new ParamsBinder(entityMetadata(), converters());
}
return paramsBinder;
}
Expand All @@ -135,8 +136,8 @@ protected Object executeFindByQuery(Method method, Object[] args, Class<?> typeC
DynamicReturn<?> dynamicReturn = DynamicReturn.builder()
.withClassSource(typeClass)
.withMethodSource(method)
.withResult(() -> getTemplate().select(query))
.withSingleResult(() -> getTemplate().singleResult(query))
.withResult(() -> template().select(query))
.withSingleResult(() -> template().singleResult(query))
.withPagination(DynamicReturn.findPageable(args))
.withStreamPagination(streamPagination(query))
.withSingleResultPagination(getSingleResult(query))
Expand All @@ -146,27 +147,27 @@ protected Object executeFindByQuery(Method method, Object[] args, Class<?> typeC
}

protected Long executeCountByQuery(ColumnQuery query) {
return getTemplate().count(query);
return template().count(query);
}

protected boolean executeExistsByQuery(ColumnQuery query) {
return getTemplate().exists(query);
return template().exists(query);
}


protected Function<Pageable, Page<T>> getPage(ColumnQuery query) {
return p -> {
Stream<T> entities = getTemplate().select(query);
Stream<T> entities = template().select(query);
return NoSQLPage.of(entities.toList(), p);
};
}

protected Function<Pageable, Optional<T>> getSingleResult(ColumnQuery query) {
return p -> getTemplate().singleResult(query);
return p -> template().singleResult(query);
}

protected Function<Pageable, Stream<T>> streamPagination(ColumnQuery query) {
return p -> getTemplate().select(query);
return p -> template().select(query);
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import jakarta.data.repository.PageableRepository;
import org.eclipse.jnosql.mapping.core.Converters;
import org.eclipse.jnosql.mapping.column.JNoSQLColumnTemplate;
import org.eclipse.jnosql.mapping.core.query.AbstractRepository;
import org.eclipse.jnosql.mapping.metadata.EntitiesMetadata;
import org.eclipse.jnosql.mapping.metadata.EntityMetadata;

Expand Down Expand Up @@ -56,22 +57,22 @@ class ColumnRepositoryProxy<T, K> extends AbstractColumnRepositoryProxy<T, K> {
}

@Override
protected PageableRepository<T, K> getRepository() {
protected AbstractRepository<T, K> repository() {
return repository;
}

@Override
protected EntityMetadata getEntityMetadata() {
protected EntityMetadata entityMetadata() {
return entityMetadata;
}

@Override
protected JNoSQLColumnTemplate getTemplate() {
protected JNoSQLColumnTemplate template() {
return template;
}

@Override
protected Converters getConverters() {
protected Converters converters() {
return converters;
}

Expand Down
Loading

0 comments on commit f772d44

Please sign in to comment.