Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,10 @@ public Object invoke(Object proxy, Method method, Object[] params) throws Throwa

switch (methodDescriptor.type()) {
case DEFAULT -> {
return unwrapInvocationTargetException(() -> infrastructureOperatorProvider().defaultMethodOperator().invokeDefault(repository(), method, params));
return unwrapInvocationTargetException(() -> infrastructureOperatorProvider().buildInMethodOperator().invokeDefault(repository(), method, params));
}
case DEFAULT_METHOD -> {
return unwrapInvocationTargetException(() -> infrastructureOperatorProvider().defaultMethodOperator().invokeDefault(proxy, method, params));
}
case OBJECT_METHOD -> {
return unwrapInvocationTargetException(() -> unwrapInvocationTargetException(() ->
Expand All @@ -120,17 +123,17 @@ public Object invoke(Object proxy, Method method, Object[] params) throws Throwa
infrastructureOperatorProvider().customRepositoryMethodOperator().invokeCustomRepository(method, params));
}
case INSERT -> {
RepositoryInvocationContext context = repositoryInvocationContext(params, methodDescriptor);
var context = repositoryInvocationContext(params, methodDescriptor);
return unwrapInvocationTargetException(() -> unwrapInvocationTargetException(() ->
repositoryOperationProvider().insertOperation().execute(context)));
}
case UPDATE -> {
RepositoryInvocationContext context = repositoryInvocationContext(params, methodDescriptor);
var context = repositoryInvocationContext(params, methodDescriptor);
return unwrapInvocationTargetException(() -> unwrapInvocationTargetException(() ->
repositoryOperationProvider().updateOperation().execute(context)));
}
case DELETE -> {
RepositoryInvocationContext context = repositoryInvocationContext(params, methodDescriptor);
var context = repositoryInvocationContext(params, methodDescriptor);
return unwrapInvocationTargetException(() -> unwrapInvocationTargetException(() ->
repositoryOperationProvider().deleteOperation().execute(context)));
}
Expand All @@ -139,6 +142,51 @@ public Object invoke(Object proxy, Method method, Object[] params) throws Throwa
return unwrapInvocationTargetException(() -> unwrapInvocationTargetException(() ->
repositoryOperationProvider().saveOperation().execute(context)));
}
case DELETE_BY -> {
var context = repositoryInvocationContext(params, methodDescriptor);
return unwrapInvocationTargetException(() -> unwrapInvocationTargetException(() ->
repositoryOperationProvider().deleteByOperation().execute(context)));
}
case FIND_BY -> {
var context = repositoryInvocationContext(params, methodDescriptor);
return unwrapInvocationTargetException(() -> unwrapInvocationTargetException(() ->
repositoryOperationProvider().findByOperation().execute(context)));
}
case COUNT_ALL -> {
var context = repositoryInvocationContext(params, methodDescriptor);
return unwrapInvocationTargetException(() -> unwrapInvocationTargetException(() ->
repositoryOperationProvider().countAllOperation().execute(context)));
}
case COUNT_BY -> {
var context = repositoryInvocationContext(params, methodDescriptor);
return unwrapInvocationTargetException(() -> unwrapInvocationTargetException(() ->
repositoryOperationProvider().countByOperation().execute(context)));
}
case CURSOR_PAGINATION -> {
var context = repositoryInvocationContext(params, methodDescriptor);
return unwrapInvocationTargetException(() -> unwrapInvocationTargetException(() ->
repositoryOperationProvider().cursorPaginationOperation().execute(context)));
}
case PARAMETER_BASED -> {
var context = repositoryInvocationContext(params, methodDescriptor);
return unwrapInvocationTargetException(() -> unwrapInvocationTargetException(() ->
repositoryOperationProvider().parameterBasedOperation().execute(context)));
}
case EXISTS_BY -> {
var context = repositoryInvocationContext(params, methodDescriptor);
return unwrapInvocationTargetException(() -> unwrapInvocationTargetException(() ->
repositoryOperationProvider().existsByOperation().execute(context)));
}
case FIND_ALL -> {
var context = repositoryInvocationContext(params, methodDescriptor);
return unwrapInvocationTargetException(() -> unwrapInvocationTargetException(() ->
repositoryOperationProvider().findAllOperation().execute(context)));
}
case QUERY -> {
var context = repositoryInvocationContext(params, methodDescriptor);
return unwrapInvocationTargetException(() -> unwrapInvocationTargetException(() ->
repositoryOperationProvider().queryOperation().execute(context)));
}
default -> throw new UnsupportedOperationException("Method not supported: " + method);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright (c) 2025 Contributors to the Eclipse Foundation
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Apache License v2.0 which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Apache License v2.0 is available at http://www.opensource.org/licenses/apache2.0.php.
*
* You may elect to redistribute this code under either of these licenses.
*
* Contributors:
*
* Otavio Santana
*/
package org.eclipse.jnosql.mapping.core.repository;

import java.lang.reflect.Method;


/**
* Operator responsible for invoking {@code default} methods declared in
* Jakarta Data repository interfaces. Default methods are implemented
* directly on the interface and must be executed outside the semantic
* repository operation pipeline, using the JVM's default-method invocation
* mechanism exposed through {@link java.lang.invoke.MethodHandles}.
*/
public interface DefaultMethodOperator {

/**
* Invokes a default method declared on a repository interface.
*
* @param instance the repository instance used as the invocation target
* @param method the default method being executed
* @param params the method arguments
* @return the result returned by the default method
* @throws Exception if the default method invocation fails
*/
Object invokeDefault(Object instance, Method method, Object[] params) throws Throwable;
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public interface InfrastructureOperatorProvider {
*
* @return the default method operator
*/
BuiltInMethodOperator defaultMethodOperator();
BuiltInMethodOperator buildInMethodOperator();

/**
* Returns the operator responsible for invoking methods inherited from
Expand All @@ -51,4 +51,15 @@ public interface InfrastructureOperatorProvider {
* @return the custom repository method operator
*/
CustomRepositoryMethodOperator customRepositoryMethodOperator();

/**
* Returns the operator responsible for invoking default methods defined
* in repository interfaces. These operators execute default interface
* methods outside the semantic repository operation pipeline, leveraging
* the JVM's default-method invocation mechanism.
*
* @return an instance of DefaultMethodOperator to handle default method
* invocation in repository interfaces
*/
DefaultMethodOperator defaultMethodOperator();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright (c) 2025 Contributors to the Eclipse Foundation
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Apache License v2.0 which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Apache License v2.0 is available at http://www.opensource.org/licenses/apache2.0.php.
*
* You may elect to redistribute this code under either of these licenses.
*
* Contributors:
*
* Otavio Santana
*/
package org.eclipse.jnosql.mapping.core.repository.operations;

import jakarta.enterprise.context.ApplicationScoped;
import org.eclipse.jnosql.mapping.core.repository.DefaultMethodOperator;

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

@ApplicationScoped
class CoreDefaultMethodOperator implements DefaultMethodOperator {

@Override
public Object invokeDefault( Object instance, Method method, Object[] params) throws Throwable {
return InvocationHandler.invokeDefault(instance, method, params);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import jakarta.inject.Inject;
import org.eclipse.jnosql.mapping.core.repository.BuiltInMethodOperator;
import org.eclipse.jnosql.mapping.core.repository.CustomRepositoryMethodOperator;
import org.eclipse.jnosql.mapping.core.repository.DefaultMethodOperator;
import org.eclipse.jnosql.mapping.core.repository.InfrastructureOperatorProvider;
import org.eclipse.jnosql.mapping.core.repository.ObjectMethodOperator;

Expand All @@ -30,22 +31,29 @@ class DefaultInfrastructureOperatorProvider implements InfrastructureOperatorPro

private final CustomRepositoryMethodOperator customRepositoryMethodOperator;

private final DefaultMethodOperator defaultMethodOperator;

@Inject
DefaultInfrastructureOperatorProvider(BuiltInMethodOperator builtInMethodOperator,
ObjectMethodOperator objectMethodOperator,
CustomRepositoryMethodOperator customRepositoryMethodOperator) {
CustomRepositoryMethodOperator customRepositoryMethodOperator,
DefaultMethodOperator defaultMethodOperator) {
this.builtInMethodOperator = builtInMethodOperator;
this.objectMethodOperator = objectMethodOperator;
this.customRepositoryMethodOperator = customRepositoryMethodOperator;
this.defaultMethodOperator = defaultMethodOperator;
}

DefaultInfrastructureOperatorProvider() {
this(null, null, null);
this.builtInMethodOperator = null;
this.objectMethodOperator = null;
this.customRepositoryMethodOperator = null;
this.defaultMethodOperator = null;
}


@Override
public BuiltInMethodOperator defaultMethodOperator() {
public BuiltInMethodOperator buildInMethodOperator() {
return builtInMethodOperator;
}

Expand All @@ -58,4 +66,9 @@ public ObjectMethodOperator objectMethodOperator() {
public CustomRepositoryMethodOperator customRepositoryMethodOperator() {
return customRepositoryMethodOperator;
}

@Override
public DefaultMethodOperator defaultMethodOperator() {
return defaultMethodOperator;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,18 @@
*/
package org.eclipse.jnosql.mapping.core.entities;

import jakarta.data.page.CursoredPage;
import jakarta.data.repository.Delete;
import jakarta.data.repository.Find;
import jakarta.data.repository.Insert;
import jakarta.data.repository.Repository;
import jakarta.data.repository.Save;
import jakarta.data.repository.Update;
import org.eclipse.jnosql.mapping.NoSQLRepository;
import org.eclipse.jnosql.mapping.metadata.repository.spi.CursorPaginationOperation;

import java.util.List;
import java.util.stream.Stream;

@Repository
public interface ComicBookRepository extends NoSQLRepository<ComicBook, String>, BookComponent {
Expand Down Expand Up @@ -88,4 +92,28 @@ public interface ComicBookRepository extends NoSQLRepository<ComicBook, String>,

@Save
ComicBook[] save(ComicBook[] books);


List<ComicBook> findByName(String name);

Stream<ComicBook> findAll();

long countByName(String name);


long countAll();

boolean existsByName(String name);

void deleteByName(String name);

@Find
List<ComicBook> find(String name);

CursoredPage<ComicBook> cursor();

default String defaultMethod() {
return "defaultMethod";
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -110,4 +110,34 @@ void shouldExecuteComponentsMethods() {
Assertions.assertThat(component).isNotNull().isEqualTo("Game based on the Comic Book");
}

@Test
void shouldExecuteDefaultMethod() {
var component = comicBookRepository.defaultMethod();
Assertions.assertThat(component).isNotNull().isEqualTo("defaultMethod");
}

@Test
void shouldReturnUnsupportedError(){
Assertions.assertThatThrownBy(() -> comicBookRepository.findByName("name"))
.isInstanceOf(UnsupportedOperationException.class);

Assertions.assertThatThrownBy(() -> comicBookRepository.countByName("name"))
.isInstanceOf(UnsupportedOperationException.class);

Assertions.assertThatThrownBy(() -> comicBookRepository.countAll())
.isInstanceOf(UnsupportedOperationException.class);

Assertions.assertThatThrownBy(() -> comicBookRepository.existsByName("name"))
.isInstanceOf(UnsupportedOperationException.class);

Assertions.assertThatThrownBy(() -> comicBookRepository.deleteByName("name"))
.isInstanceOf(UnsupportedOperationException.class);

Assertions.assertThatThrownBy(() -> comicBookRepository.find("name"))
.isInstanceOf(UnsupportedOperationException.class);

Assertions.assertThatThrownBy(() -> comicBookRepository.cursor())
.isInstanceOf(UnsupportedOperationException.class);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ class UpdateOperationRepositoryInvocationHandlerTest {
private RepositoriesMetadata repositoriesMetadata;
@Inject
private InfrastructureOperatorProvider infrastructureOperatorProvider;

@Inject
private CoreBaseRepositoryOperationProvider repositoryOperationProvider;
private TestRepositoryExecutor executor;
Expand Down Expand Up @@ -114,6 +113,4 @@ void shouldUpdateArrayReturn() {
Assertions.assertThat(books).isNotNull().isNotEmpty().contains(new ComicBook("1234", "Book"));
Mockito.verify(template).update(Mockito.any(Iterable.class));
}


}