-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #5 from MEITREX/abstract-parent-service-class
enable sonar analysis add utility method for graphql queries add abstract service for typical operations
- Loading branch information
Showing
8 changed files
with
595 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
jacoco { | ||
toolVersion = "0.8.11" | ||
} | ||
|
||
test { | ||
finalizedBy jacocoTestReport | ||
} | ||
|
||
|
||
jacocoTestReport { | ||
reports { | ||
xml.required.set(true) | ||
html.required.set(true) | ||
html.outputLocation = layout.buildDirectory.dir('jacocoHtml') | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
lombok.addLombokGeneratedAnnotation = true | ||
config.stopBubbling = true |
196 changes: 196 additions & 0 deletions
196
src/main/java/de/unistuttgart/iste/meitrex/common/service/AbstractCrudService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,196 @@ | ||
package de.unistuttgart.iste.meitrex.common.service; | ||
|
||
import de.unistuttgart.iste.meitrex.common.exception.MeitrexNotFoundException; | ||
import de.unistuttgart.iste.meitrex.common.persistence.IWithId; | ||
import de.unistuttgart.iste.meitrex.common.persistence.MeitrexRepository; | ||
import org.modelmapper.ModelMapper; | ||
|
||
import java.util.List; | ||
import java.util.Optional; | ||
import java.util.function.Consumer; | ||
import java.util.function.Supplier; | ||
|
||
/** | ||
* Abstract service for CRUD operations. | ||
* Services extending this class can utilize the helper methods to perform CRUD operations on entities. | ||
* | ||
* @param <I> the type of the entity id, e.g., UUID | ||
* @param <E> the type of the entity, e.g., UserEntity | ||
* @param <D> the type of the DTO, e.g., User | ||
*/ | ||
public abstract class AbstractCrudService<I, E extends IWithId<I>, D> { | ||
|
||
/** | ||
* @return the class of the entity, e.g., UserEntity.class | ||
*/ | ||
protected abstract Class<E> getEntityClass(); | ||
|
||
/** | ||
* @return the class of the DTO, e.g., User.class | ||
*/ | ||
protected abstract Class<D> getDtoClass(); | ||
|
||
/** | ||
* Get the model mapper used to map between entities and DTOs. | ||
* This method should return a pre-configured model mapper. | ||
* The model mapper should be set up to map between the entity and DTO classes, | ||
* and between input classes and the entity class. | ||
* | ||
* @return the model mapper used to map between entities and DTOs | ||
*/ | ||
protected abstract ModelMapper getModelMapper(); | ||
|
||
/** | ||
* @return the repository used to access the entities | ||
*/ | ||
protected abstract MeitrexRepository<E, I> getRepository(); | ||
|
||
/** | ||
* Get all entities from the repository and convert them to DTOs. | ||
* | ||
* @return a list of all entities as DTOs | ||
*/ | ||
protected List<D> getAll() { | ||
final List<E> entities = getRepository().findAll(); | ||
return convertToDtos(entities); | ||
} | ||
|
||
/** | ||
* Find an entity by its id and convert it to a DTO. | ||
* | ||
* @param id the id of the entity to find | ||
* @return the entity as a DTO, or an empty optional if no entity with the given id exists | ||
*/ | ||
protected Optional<D> find(final I id) { | ||
return getRepository() | ||
.findById(id) | ||
.map(this::convertToDto); | ||
} | ||
|
||
/** | ||
* Gets an entity by its id and convert it to a DTO. | ||
* If no entity with the given id exists, throws an exception. | ||
* | ||
* @param id the id of the entity to get | ||
* @return the entity as a DTO | ||
* @throws MeitrexNotFoundException if no entity with the given id exists | ||
*/ | ||
protected D getOrThrow(final I id) { | ||
return convertToDto(getRepository().findByIdOrThrow(id)); | ||
} | ||
|
||
/** | ||
* Creates an entity using the given entity creator and saves it to the repository. | ||
* | ||
* @param entityCreator supplier that returns the entity to create | ||
* @return the created entity as an entity | ||
*/ | ||
protected E createEntity(final Supplier<E> entityCreator) { | ||
final E entity = entityCreator.get(); | ||
return getRepository().save(entity); | ||
} | ||
|
||
/** | ||
* Creates an entity by mapping the given input to an entity and saves it to the repository. | ||
* Note: This requires the model mapper to be set up correctly. | ||
* | ||
* @param createInput the input to map to an entity | ||
* @return the created entity as an entity | ||
*/ | ||
protected E createEntity(final Object createInput) { | ||
return createEntity(() -> getModelMapper().map(createInput, getEntityClass())); | ||
} | ||
|
||
/** | ||
* Creates an entity using the given entity creator, saves it to the repository | ||
* and converts it to a DTO. | ||
* | ||
* @param entityCreator supplier that returns the entity to create | ||
* @return the created entity as a DTO | ||
*/ | ||
protected D create(final Supplier<E> entityCreator) { | ||
final E entity = createEntity(entityCreator); | ||
|
||
return convertToDto(entity); | ||
} | ||
|
||
/** | ||
* Creates an entity by mapping the given input to an entity, saves it to the repository | ||
* and converts it to a DTO. | ||
* Note: This requires the model mapper to be set up correctly. | ||
* | ||
* @param createInput the input to map to an entity | ||
* @return the created entity as a DTO | ||
*/ | ||
protected D create(final Object createInput) { | ||
return create(() -> getModelMapper().map(createInput, getEntityClass())); | ||
} | ||
|
||
/** | ||
* Updates an entity by its id using the given entity updater and saves it to the repository. | ||
* | ||
* @param id the id of the entity to update | ||
* @param entityUpdater consumer that updates the entity | ||
* @return the updated entity as a DTO | ||
*/ | ||
protected D update(final I id, final Consumer<E> entityUpdater) { | ||
final E entity = getRepository().findByIdOrThrow(id); | ||
entityUpdater.accept(entity); | ||
|
||
final E savedEntity = getRepository().save(entity); | ||
|
||
return convertToDto(savedEntity); | ||
} | ||
|
||
/** | ||
* Updates an entity by its id by mapping the given input | ||
* to the existing entity and saves it to the repository. | ||
* This will not overwrite the entity, but update only the fields | ||
* that are defined in the input. | ||
* | ||
* @param id the id of the entity to update | ||
* @param updateInput the input to map to an entity | ||
* @return the updated entity as a DTO | ||
*/ | ||
protected D update(final I id, final Object updateInput) { | ||
return update(id, entity -> getModelMapper().map(updateInput, entity)); | ||
} | ||
|
||
/** | ||
* Deletes an entity by its id. | ||
* | ||
* @param id the id of the entity to delete | ||
* @return true if the entity was deleted, false if no entity with the given id exists | ||
* @apiNote subclasses will likely require a more sophisticated deletion logic | ||
*/ | ||
protected boolean delete(final I id) { | ||
if (!getRepository().existsById(id)) { | ||
return false; | ||
} | ||
|
||
getRepository().deleteById(id); | ||
return true; | ||
} | ||
|
||
/** | ||
* Converts an entity to a DTO. | ||
* | ||
* @param entity the entity to convert | ||
* @return the entity as a DTO | ||
*/ | ||
protected D convertToDto(final E entity) { | ||
return getModelMapper().map(entity, getDtoClass()); | ||
} | ||
|
||
/** | ||
* Converts a list of entities to a list of DTOs. | ||
* | ||
* @param entities the entities to convert | ||
* @return the entities as DTOs | ||
*/ | ||
protected List<D> convertToDtos(final List<E> entities) { | ||
return entities.stream() | ||
.map(this::convertToDto) | ||
.toList(); | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
src/main/java/de/unistuttgart/iste/meitrex/common/util/GraphQlUtil.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package de.unistuttgart.iste.meitrex.common.util; | ||
|
||
import lombok.NoArgsConstructor; | ||
import org.intellij.lang.annotations.Language; | ||
|
||
@NoArgsConstructor(access = lombok.AccessLevel.PRIVATE) | ||
public class GraphQlUtil { | ||
|
||
/** | ||
* This method is used to mark a string as a GraphQl. | ||
* This is useful for IntelliJ IDEA to provide syntax highlighting and code completion. | ||
* | ||
* @param graphQl the GraphQl string | ||
* @return the GraphQl string | ||
*/ | ||
public static String gql(@Language("GraphQl") final String graphQl) { | ||
return graphQl; | ||
} | ||
} |
Oops, something went wrong.