Commit f9f568a8 authored by Daniel Gerhardt's avatar Daniel Gerhardt

Extract interface from EntityService

parent 13e18671
...@@ -6,7 +6,7 @@ import de.thm.arsnova.entities.User; ...@@ -6,7 +6,7 @@ import de.thm.arsnova.entities.User;
import java.util.List; import java.util.List;
public interface CommentService { public interface CommentService extends EntityService<Comment> {
boolean save(Comment comment); boolean save(Comment comment);
int count(String sessionKey); int count(String sessionKey);
......
...@@ -24,7 +24,7 @@ import java.util.List; ...@@ -24,7 +24,7 @@ import java.util.List;
* Performs all comment related operations. * Performs all comment related operations.
*/ */
@Service @Service
public class CommentServiceImpl extends EntityService<Comment> implements CommentService, ApplicationEventPublisherAware { public class CommentServiceImpl extends DefaultEntityServiceImpl<Comment> implements CommentService, ApplicationEventPublisherAware {
private UserService userService; private UserService userService;
private CommentRepository commentRepository; private CommentRepository commentRepository;
......
...@@ -27,7 +27,7 @@ import java.util.Map; ...@@ -27,7 +27,7 @@ import java.util.Map;
/** /**
* The functionality the question service should provide. * The functionality the question service should provide.
*/ */
public interface ContentService { public interface ContentService extends EntityService<Content> {
Content save(Content content); Content save(Content content);
Content get(String id); Content get(String id);
......
...@@ -63,7 +63,7 @@ import java.util.stream.Collectors; ...@@ -63,7 +63,7 @@ import java.util.stream.Collectors;
* Performs all content and answer related operations. * Performs all content and answer related operations.
*/ */
@Service @Service
public class ContentServiceImpl extends EntityService<Content> implements ContentService, ApplicationEventPublisherAware { public class ContentServiceImpl extends DefaultEntityServiceImpl<Content> implements ContentService, ApplicationEventPublisherAware {
private UserService userService; private UserService userService;
private LogEntryRepository dbLogger; 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; 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.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.PreAuthorize;
import org.springframework.security.access.prepost.PreFilter; import org.springframework.security.access.prepost.PreFilter;
...@@ -13,62 +8,22 @@ import java.io.IOException; ...@@ -13,62 +8,22 @@ import java.io.IOException;
import java.util.Collection; import java.util.Collection;
import java.util.Map; import java.util.Map;
public class EntityService<T extends Entity> { public interface 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;
}
@PreAuthorize("hasPermission(#id, #this.this.getTypeName(), 'read')") @PreAuthorize("hasPermission(#id, #this.this.getTypeName(), 'read')")
public T get(final String id) { T get(String id);
return repository.findOne(id);
}
@PreAuthorize("hasPermission(#entity, 'create')") @PreAuthorize("hasPermission(#entity, 'create')")
public T create(final T entity) { T create(T entity);
if (entity.getId() != null || entity.getRevision() != null) {
throw new IllegalArgumentException("Entity is not new.");
}
return repository.save(entity);
}
@PreAuthorize("hasPermission(#oldEntity, 'update')") @PreAuthorize("hasPermission(#oldEntity, 'update')")
public T update(final T oldEntity, final T newEntity) { T update(T oldEntity, T newEntity);
newEntity.setId(oldEntity.getId());
return repository.save(newEntity);
}
@PreAuthorize("hasPermission(#entity, 'update')") @PreAuthorize("hasPermission(#entity, 'update')")
public T patch(final T entity, final Map<String, Object> changes) throws IOException { T patch(T entity, 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);
}
@PreFilter(value = "hasPermission(filterObject, 'update')", filterTarget = "entities") @PreFilter(value = "hasPermission(filterObject, 'update')", filterTarget = "entities")
public Iterable<T> patch(final Collection<T> entities, final Map<String, Object> changes) throws IOException { Iterable<T> patch(Collection<T> entities, 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);
}
@PreAuthorize("hasPermission(#entity, 'delete')") @PreAuthorize("hasPermission(#entity, 'delete')")
public void delete(final T entity) { void delete(T entity);
repository.delete(entity);
}
public String getTypeName() {
return type.getSimpleName().toLowerCase();
}
} }
...@@ -26,7 +26,7 @@ import java.util.List; ...@@ -26,7 +26,7 @@ import java.util.List;
/** /**
* The functionality the motd service should provide. * The functionality the motd service should provide.
*/ */
public interface MotdService { public interface MotdService extends EntityService<Motd> {
Motd getByKey(String keyword); Motd getByKey(String keyword);
List<Motd> getAdminMotds(); //all w/o the sessionmotds List<Motd> getAdminMotds(); //all w/o the sessionmotds
......
...@@ -41,7 +41,7 @@ import java.util.StringTokenizer; ...@@ -41,7 +41,7 @@ import java.util.StringTokenizer;
* Performs all question, interposed question, and answer related operations. * Performs all question, interposed question, and answer related operations.
*/ */
@Service @Service
public class MotdServiceImpl extends EntityService<Motd> implements MotdService { public class MotdServiceImpl extends DefaultEntityServiceImpl<Motd> implements MotdService {
private UserService userService; private UserService userService;
private SessionService sessionService; private SessionService sessionService;
......
...@@ -31,7 +31,7 @@ import java.util.UUID; ...@@ -31,7 +31,7 @@ import java.util.UUID;
/** /**
* The functionality the session service should provide. * The functionality the session service should provide.
*/ */
public interface SessionService { public interface SessionService extends EntityService<Session> {
Session getByKey(String keyword); Session getByKey(String keyword);
Session getForAdmin(final String keyword); Session getForAdmin(final String keyword);
......
...@@ -43,7 +43,6 @@ import de.thm.arsnova.exceptions.BadRequestException; ...@@ -43,7 +43,6 @@ import de.thm.arsnova.exceptions.BadRequestException;
import de.thm.arsnova.exceptions.ForbiddenException; import de.thm.arsnova.exceptions.ForbiddenException;
import de.thm.arsnova.exceptions.NotFoundException; import de.thm.arsnova.exceptions.NotFoundException;
import de.thm.arsnova.exceptions.PayloadTooLargeException; import de.thm.arsnova.exceptions.PayloadTooLargeException;
import de.thm.arsnova.exceptions.UnauthorizedException;
import de.thm.arsnova.persistance.SessionRepository; import de.thm.arsnova.persistance.SessionRepository;
import de.thm.arsnova.persistance.VisitedSessionRepository; import de.thm.arsnova.persistance.VisitedSessionRepository;
import org.ektorp.UpdateConflictException; import org.ektorp.UpdateConflictException;
...@@ -71,7 +70,7 @@ import java.util.UUID; ...@@ -71,7 +70,7 @@ import java.util.UUID;
* Performs all session related operations. * Performs all session related operations.
*/ */
@Service @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 long SESSION_INACTIVITY_CHECK_INTERVAL_MS = 30 * 60 * 1000L;
private static final Logger logger = LoggerFactory.getLogger(SessionServiceImpl.class); private static final Logger logger = LoggerFactory.getLogger(SessionServiceImpl.class);
......
...@@ -33,7 +33,7 @@ import static org.junit.Assert.*; ...@@ -33,7 +33,7 @@ import static org.junit.Assert.*;
@WebAppConfiguration @WebAppConfiguration
@ContextConfiguration(classes = {AppConfig.class, TestAppConfig.class, TestPersistanceConfig.class, TestSecurityConfig.class}) @ContextConfiguration(classes = {AppConfig.class, TestAppConfig.class, TestPersistanceConfig.class, TestSecurityConfig.class})
@ActiveProfiles("test") @ActiveProfiles("test")
public class EntityServiceTest { public class DefaultEntityServiceImplTest {
@Autowired @Autowired
@Qualifier("defaultJsonMessageConverter") @Qualifier("defaultJsonMessageConverter")
private MappingJackson2HttpMessageConverter jackson2HttpMessageConverter; private MappingJackson2HttpMessageConverter jackson2HttpMessageConverter;
...@@ -45,7 +45,7 @@ public class EntityServiceTest { ...@@ -45,7 +45,7 @@ public class EntityServiceTest {
@WithMockUser(username="TestUser") @WithMockUser(username="TestUser")
public void testPatch() throws IOException { public void testPatch() throws IOException {
final ObjectMapper objectMapper = jackson2HttpMessageConverter.getObjectMapper(); 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()); when(sessionRepository.save(any(Session.class))).then(returnsFirstArg());
...@@ -78,7 +78,7 @@ public class EntityServiceTest { ...@@ -78,7 +78,7 @@ public class EntityServiceTest {
@WithMockUser(username="TestUser") @WithMockUser(username="TestUser")
public void testPatchWithList() throws IOException { public void testPatchWithList() throws IOException {
final ObjectMapper objectMapper = jackson2HttpMessageConverter.getObjectMapper(); 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()); when(sessionRepository.save(any(Session.class))).then(returnsFirstArg());
......
Markdown is supported
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