Skip to content
Snippets Groups Projects
Commit c171a64e authored by Daniel Gerhardt's avatar Daniel Gerhardt
Browse files

Merge branch 'entity-service-interface'

parents 13e18671 f9f568a8
No related merge requests found
Pipeline #10115 passed with warnings with stages
in 3 minutes and 28 seconds
Showing
with 98 additions and 64 deletions
......@@ -6,7 +6,7 @@ import de.thm.arsnova.entities.User;
import java.util.List;
public interface CommentService {
public interface CommentService extends EntityService<Comment> {
boolean save(Comment comment);
int count(String sessionKey);
......
......@@ -24,7 +24,7 @@ import java.util.List;
* Performs all comment related operations.
*/
@Service
public class CommentServiceImpl extends EntityService<Comment> implements CommentService, ApplicationEventPublisherAware {
public class CommentServiceImpl extends DefaultEntityServiceImpl<Comment> implements CommentService, ApplicationEventPublisherAware {
private UserService userService;
private CommentRepository commentRepository;
......
......@@ -27,7 +27,7 @@ import java.util.Map;
/**
* The functionality the question service should provide.
*/
public interface ContentService {
public interface ContentService extends EntityService<Content> {
Content save(Content content);
Content get(String id);
......
......@@ -63,7 +63,7 @@ import java.util.stream.Collectors;
* Performs all content and answer related operations.
*/
@Service
public class ContentServiceImpl extends EntityService<Content> implements ContentService, ApplicationEventPublisherAware {
public class ContentServiceImpl extends DefaultEntityServiceImpl<Content> implements ContentService, ApplicationEventPublisherAware {
private UserService userService;
private LogEntryRepository dbLogger;
......
package de.thm.arsnova.services;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import de.thm.arsnova.entities.Entity;
import de.thm.arsnova.entities.serialization.View;
import org.springframework.data.repository.CrudRepository;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.access.prepost.PreFilter;
import java.io.IOException;
import java.util.Collection;
import java.util.Map;
public class DefaultEntityServiceImpl<T extends Entity> implements EntityService<T> {
protected Class<T> type;
protected CrudRepository<T, String> repository;
private ObjectMapper objectMapper;
public DefaultEntityServiceImpl(Class<T> type, CrudRepository<T, String> repository, ObjectMapper objectMapper) {
this.type = type;
this.repository = repository;
this.objectMapper = objectMapper;
}
@Override
@PreAuthorize("hasPermission(#id, #this.this.getTypeName(), 'read')")
public T get(final String id) {
return repository.findOne(id);
}
@Override
@PreAuthorize("hasPermission(#entity, 'create')")
public T create(final T entity) {
if (entity.getId() != null || entity.getRevision() != null) {
throw new IllegalArgumentException("Entity is not new.");
}
return repository.save(entity);
}
@Override
@PreAuthorize("hasPermission(#oldEntity, 'update')")
public T update(final T oldEntity, final T newEntity) {
newEntity.setId(oldEntity.getId());
return repository.save(newEntity);
}
@Override
@PreAuthorize("hasPermission(#entity, 'update')")
public T patch(final T entity, final Map<String, Object> changes) throws IOException {
ObjectReader reader = objectMapper.readerForUpdating(entity).withView(View.Public.class);
JsonNode tree = objectMapper.valueToTree(changes);
reader.readValue(tree);
return repository.save(entity);
}
@Override
@PreFilter(value = "hasPermission(filterObject, 'update')", filterTarget = "entities")
public Iterable<T> patch(final Collection<T> entities, final Map<String, Object> changes) throws IOException {
JsonNode tree = objectMapper.valueToTree(changes);
for (T entity : entities) {
ObjectReader reader = objectMapper.readerForUpdating(entity).withView(View.Public.class);
reader.readValue(tree);
}
return repository.save(entities);
}
@Override
@PreAuthorize("hasPermission(#entity, 'delete')")
public void delete(final T entity) {
repository.delete(entity);
}
public String getTypeName() {
return type.getSimpleName().toLowerCase();
}
}
package de.thm.arsnova.services;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import de.thm.arsnova.entities.Entity;
import de.thm.arsnova.entities.serialization.View;
import org.springframework.data.repository.CrudRepository;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.access.prepost.PreFilter;
......@@ -13,62 +8,22 @@ import java.io.IOException;
import java.util.Collection;
import java.util.Map;
public class EntityService<T extends Entity> {
protected Class<T> type;
protected CrudRepository<T, String> repository;
private ObjectMapper objectMapper;
public EntityService(Class<T> type, CrudRepository<T, String> repository, ObjectMapper objectMapper) {
this.type = type;
this.repository = repository;
this.objectMapper = objectMapper;
}
public interface EntityService<T extends Entity> {
@PreAuthorize("hasPermission(#id, #this.this.getTypeName(), 'read')")
public T get(final String id) {
return repository.findOne(id);
}
T get(String id);
@PreAuthorize("hasPermission(#entity, 'create')")
public T create(final T entity) {
if (entity.getId() != null || entity.getRevision() != null) {
throw new IllegalArgumentException("Entity is not new.");
}
return repository.save(entity);
}
T create(T entity);
@PreAuthorize("hasPermission(#oldEntity, 'update')")
public T update(final T oldEntity, final T newEntity) {
newEntity.setId(oldEntity.getId());
return repository.save(newEntity);
}
T update(T oldEntity, T newEntity);
@PreAuthorize("hasPermission(#entity, 'update')")
public T patch(final T entity, final Map<String, Object> changes) throws IOException {
ObjectReader reader = objectMapper.readerForUpdating(entity).withView(View.Public.class);
JsonNode tree = objectMapper.valueToTree(changes);
reader.readValue(tree);
return repository.save(entity);
}
T patch(T entity, Map<String, Object> changes) throws IOException;
@PreFilter(value = "hasPermission(filterObject, 'update')", filterTarget = "entities")
public Iterable<T> patch(final Collection<T> entities, final Map<String, Object> changes) throws IOException {
JsonNode tree = objectMapper.valueToTree(changes);
for (T entity : entities) {
ObjectReader reader = objectMapper.readerForUpdating(entity).withView(View.Public.class);
reader.readValue(tree);
}
return repository.save(entities);
}
Iterable<T> patch(Collection<T> entities, Map<String, Object> changes) throws IOException;
@PreAuthorize("hasPermission(#entity, 'delete')")
public void delete(final T entity) {
repository.delete(entity);
}
public String getTypeName() {
return type.getSimpleName().toLowerCase();
}
void delete(T entity);
}
......@@ -26,7 +26,7 @@ import java.util.List;
/**
* The functionality the motd service should provide.
*/
public interface MotdService {
public interface MotdService extends EntityService<Motd> {
Motd getByKey(String keyword);
List<Motd> getAdminMotds(); //all w/o the sessionmotds
......
......@@ -41,7 +41,7 @@ import java.util.StringTokenizer;
* Performs all question, interposed question, and answer related operations.
*/
@Service
public class MotdServiceImpl extends EntityService<Motd> implements MotdService {
public class MotdServiceImpl extends DefaultEntityServiceImpl<Motd> implements MotdService {
private UserService userService;
private SessionService sessionService;
......
......@@ -31,7 +31,7 @@ import java.util.UUID;
/**
* The functionality the session service should provide.
*/
public interface SessionService {
public interface SessionService extends EntityService<Session> {
Session getByKey(String keyword);
Session getForAdmin(final String keyword);
......
......@@ -43,7 +43,6 @@ import de.thm.arsnova.exceptions.BadRequestException;
import de.thm.arsnova.exceptions.ForbiddenException;
import de.thm.arsnova.exceptions.NotFoundException;
import de.thm.arsnova.exceptions.PayloadTooLargeException;
import de.thm.arsnova.exceptions.UnauthorizedException;
import de.thm.arsnova.persistance.SessionRepository;
import de.thm.arsnova.persistance.VisitedSessionRepository;
import org.ektorp.UpdateConflictException;
......@@ -71,7 +70,7 @@ import java.util.UUID;
* Performs all session related operations.
*/
@Service
public class SessionServiceImpl extends EntityService<Session> implements SessionService, ApplicationEventPublisherAware {
public class SessionServiceImpl extends DefaultEntityServiceImpl<Session> implements SessionService, ApplicationEventPublisherAware {
private static final long SESSION_INACTIVITY_CHECK_INTERVAL_MS = 30 * 60 * 1000L;
private static final Logger logger = LoggerFactory.getLogger(SessionServiceImpl.class);
......
......@@ -33,7 +33,7 @@ import static org.junit.Assert.*;
@WebAppConfiguration
@ContextConfiguration(classes = {AppConfig.class, TestAppConfig.class, TestPersistanceConfig.class, TestSecurityConfig.class})
@ActiveProfiles("test")
public class EntityServiceTest {
public class DefaultEntityServiceImplTest {
@Autowired
@Qualifier("defaultJsonMessageConverter")
private MappingJackson2HttpMessageConverter jackson2HttpMessageConverter;
......@@ -45,7 +45,7 @@ public class EntityServiceTest {
@WithMockUser(username="TestUser")
public void testPatch() throws IOException {
final ObjectMapper objectMapper = jackson2HttpMessageConverter.getObjectMapper();
final EntityService<Session> entityService = new EntityService<>(Session.class, sessionRepository, objectMapper);
final DefaultEntityServiceImpl<Session> entityService = new DefaultEntityServiceImpl<>(Session.class, sessionRepository, objectMapper);
when(sessionRepository.save(any(Session.class))).then(returnsFirstArg());
......@@ -78,7 +78,7 @@ public class EntityServiceTest {
@WithMockUser(username="TestUser")
public void testPatchWithList() throws IOException {
final ObjectMapper objectMapper = jackson2HttpMessageConverter.getObjectMapper();
final EntityService<Session> entityService = new EntityService<>(Session.class, sessionRepository, objectMapper);
final DefaultEntityServiceImpl<Session> entityService = new DefaultEntityServiceImpl<>(Session.class, sessionRepository, objectMapper);
when(sessionRepository.save(any(Session.class))).then(returnsFirstArg());
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment