Skip to content

Commit

Permalink
feat: create implementation to annotation operation
Browse files Browse the repository at this point in the history
Signed-off-by: Otavio Santana <otaviopolianasantana@gmail.com>
  • Loading branch information
otaviojava committed Dec 27, 2023
1 parent 717b419 commit 0811d09
Show file tree
Hide file tree
Showing 2 changed files with 152 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,33 +15,95 @@
package org.eclipse.jnosql.mapping.core.query;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;

@SuppressWarnings({"rawtypes", "unchecked"})
public enum AnnotationOperation {
INSERT {
@Override
public Object invoke(Operation operation) throws Throwable {
if (operation.params.length != 1) {
throw new UnsupportedOperationException("The insert method requires one parameter");
}
Object entity = operation.params[0];
public Object invoke(Operation operation) {
checkParameterNumber(operation);
Object param = operation.params[0];
boolean isVoid = operation.method.getReturnType().equals(Void.TYPE);
if(entity instanceof Iterable entities){
if (param instanceof Iterable entities) {
Iterable<?> result = operation.repository.insertAll(entities);
return isVoid? Void.TYPE:result;
return isVoid ? Void.TYPE : result;
} else if (param.getClass().isArray()) {
Iterable<?> result = operation.repository.insertAll(Arrays.asList((Object[]) param));
return isVoid ? Void.TYPE : result;
} else {
Object result = operation.repository.insert(entity);
Object result = operation.repository.insert(param);
return isVoid ? Void.TYPE : result;
}
}
}, UPDATE {
@Override
public Object invoke(Operation operation) {
checkParameterNumber(operation);
Object param = operation.params[0];
boolean isVoid = operation.method.getReturnType().equals(Void.TYPE);
boolean isBoolean = operation.method.getReturnType().equals(Boolean.class)
|| operation.method.getReturnType().equals(Boolean.TYPE);
boolean isInt = operation.method.getReturnType().equals(Integer.class)
|| operation.method.getReturnType().equals(Integer.TYPE);
boolean isSame = operation.method.getReturnType().equals(param.getClass());
if (param instanceof Iterable entities) {
return executeIterable(operation, entities, isVoid, isBoolean, isInt, isSame);
} else if (param.getClass().isArray()) {
List<Object> entities = Arrays.asList((Object[]) param);
return executeIterable(operation, entities, isVoid, isBoolean, isInt, isSame);
} else {
return executeSingleEntity(operation, param, isVoid, isBoolean, isInt, isSame);
}
}

private static Object executeSingleEntity(Operation operation, Object param, boolean isVoid, boolean isBoolean, boolean isInt, boolean isSame) {
boolean result = operation.repository.update(param);
if(isVoid) {
return Void.TYPE;
} else if(isBoolean) {
return result;
} else if(isInt) {
return 1;
} else if(isSame) {
return param;
} else {
throw new UnsupportedOperationException("We don't have support to this return at update operation, please check the method: "
+ operation.method);
}
}

private static Object executeIterable(Operation operation, Iterable entities, boolean isVoid, boolean isBoolean, boolean isInt, boolean isSame) {
int count = operation.repository.updateAll(entities);
if (isVoid) {
return Void.TYPE;
} else if (isBoolean) {
return true;
} else if (isInt) {
return count;
} else if (isSame) {
return entities;
} else {
throw new UnsupportedOperationException("We don't have support to this return at update operation, please check the method: "
+ operation.method);
}
}
};

public abstract Object invoke(Operation operation) throws Throwable;
private static void checkParameterNumber(Operation operation) {
if (operation.params.length != 1) {
throw new UnsupportedOperationException("The method operation requires one parameter, please check the method: "
+ operation.method);
}
}

public abstract Object invoke(Operation operation);




public record Operation(Object instance, Method method, Object[] params, AbstractRepository repository){
public record Operation(Method method, Object[] params, AbstractRepository repository){

}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,83 @@
/*
* Copyright (c) 2023 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.query;

import jakarta.data.repository.DataRepository;
import org.assertj.core.api.Assertions;
import org.eclipse.jnosql.mapping.core.entities.Person;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;

import java.lang.reflect.Method;
import java.util.List;

import static org.junit.jupiter.api.Assertions.*;

@ExtendWith(MockitoExtension.class)
class AnnotationOperationTest {


@Mock
private AbstractRepository<Person, Long> repository;


@Test
void shouldInsertSingleParameter() throws Throwable {
Method method = PersonRepository.class.getDeclaredMethod("same", Person.class);
Person person = Person.builder().build();
Mockito.when(repository.insert(person)).thenReturn(person);
Object invoked = AnnotationOperation.INSERT.invoke(new AnnotationOperation.Operation(method, new Object[]{person}, repository));
Mockito.verify(repository).insert(person);
Assertions.assertThat(person).isEqualTo(invoked);
}

@Test
void shouldInsertIterableParameter() throws Throwable {
Method method = PersonRepository.class.getDeclaredMethod("iterable", List.class);
Person person = Person.builder().build();
Mockito.when(repository.insertAll(List.of(person))).thenReturn(List.of(person));
Object invoked = AnnotationOperation.INSERT.invoke(new AnnotationOperation.Operation(method, new Object[]{List.of(person)}, repository));
Mockito.verify(repository).insertAll(List.of(person));
Assertions.assertThat(List.of(person)).isEqualTo(invoked);
}


@Test
void shouldInsertArrayParameter() throws Throwable {
Method method = PersonRepository.class.getDeclaredMethod("array", Person[].class);
Person person = Person.builder().build();
Mockito.when(repository.insertAll(List.of(person))).thenReturn(List.of(person));
Object invoked = AnnotationOperation.INSERT.invoke(new AnnotationOperation.Operation(method, new Object[]{new Person[]{person}},
repository));
Mockito.verify(repository).insertAll(List.of(person));
Assertions.assertThat(List.of(person)).isEqualTo(invoked);
}




interface PersonRepository extends DataRepository<Person, Long>{

void methodVoid(Person person);

Person same(Person person);

Person[] array(Person[] people);

List<Person> iterable(List<Person> people);
}
}

0 comments on commit 0811d09

Please sign in to comment.