Skip to content

Commit

Permalink
closes #214
Browse files Browse the repository at this point in the history
  • Loading branch information
justinhrobbins committed Jan 24, 2016
1 parent ceb2fdc commit 4f67edd
Show file tree
Hide file tree
Showing 27 changed files with 527 additions and 143 deletions.
14 changes: 14 additions & 0 deletions FlashCards_Repository/FlashCards_Repository_Commons/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,20 @@
<artifactId>javax.inject</artifactId>
</dependency>

<!-- Jackson -->
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-hibernate4</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>

</dependencies>
<build>
<finalName>FlashCards_Repository_Commons</finalName>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@

package org.robbins.flashcards.jackson;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
import com.fasterxml.jackson.datatype.hibernate4.Hibernate4Module;
import com.fasterxml.jackson.datatype.hibernate4.Hibernate4Module.Feature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;

public class CustomObjectMapper extends ObjectMapper {

Expand All @@ -15,10 +17,14 @@ public CustomObjectMapper() {
this.registerModule(hm);

this.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
this.registerModule(new JavaTimeModule());

SimpleFilterProvider filterProvider = new SimpleFilterProvider();
filterProvider.setFailOnUnknownId(false);
this.setFilters(filterProvider);

this.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
this.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
}

public void setPrettyPrint(final boolean prettyPrint) {
Expand Down
5 changes: 5 additions & 0 deletions FlashCards_Repository/FlashCards_Repository_Jpa/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@
<artifactId>FlashCards_Repository_Jpa_Commons</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.robbins.flashcards</groupId>
<artifactId>FlashCards_Repository_Commons</artifactId>
<version>${project.version}</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
package org.robbins.flashcards.model.util;


import java.time.LocalDateTime;

import org.robbins.flashcards.model.common.AbstractAuditable;

import java.time.LocalDateTime;

public class EntityAuditingUtil
{

public static void configureCreatedByAndTime(final AbstractAuditable entity, final Long auditingUserId) {
entity.setCreatedBy(auditingUserId);
entity.setCreatedDate(LocalDateTime.now());
if (entity.isNew()) {
entity.setCreatedBy(auditingUserId);
entity.setCreatedDate(LocalDateTime.now());
}
}

}
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@

package org.robbins.flashcards.repository.facade.base;

import java.io.Serializable;
import java.util.List;
import java.util.Optional;
import java.util.Set;

import javax.inject.Inject;

import org.apache.commons.collections.CollectionUtils;
import org.robbins.flashcards.dto.BatchLoadingReceiptDto;
import org.robbins.flashcards.exceptions.FlashCardsException;
Expand All @@ -24,6 +17,12 @@
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.inject.Inject;
import java.io.Serializable;
import java.util.List;
import java.util.Optional;
import java.util.Set;

@Transactional
public abstract class AbstractCrudRepositoryFacadeImpl<D, E extends AbstractAuditable, ID extends Serializable> implements GenericCrudFacade<D, ID>,
RepositoryFacade<D, E, ID> {
Expand All @@ -43,11 +42,16 @@ public Long getAuditingUserId() {
@Override
public D save(final D dto) throws RepositoryException {
final E entity = getConverter().getEntity(dto);
EntityAuditingUtil.configureCreatedByAndTime(entity, getAuditingUserId());
configureCreatedByAndTime(entity);
final E result = getRepository().save(entity);
return convertAndInitializeEntity(result);
}

public void configureCreatedByAndTime(final E entity)
{
EntityAuditingUtil.configureCreatedByAndTime(entity, getAuditingUserId());
}

@Transactional(propagation= Propagation.NEVER)
@Override
public BatchLoadingReceiptDto save(final List<D> dtos) throws FlashCardsException
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

import com.google.common.collect.Lists;
import com.google.common.collect.Sets;

import org.robbins.flashcards.conversion.DtoConverter;
import org.robbins.flashcards.dto.FlashCardDto;
import org.robbins.flashcards.dto.TagDto;
Expand All @@ -22,7 +21,6 @@
import org.springframework.transaction.annotation.Transactional;

import javax.inject.Inject;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -61,7 +59,7 @@ public FlashCardRepository<FlashCard, Tag, Long> getRepository() {
@Override
public FlashCardDto save(final FlashCardDto dto) throws RepositoryException {
final FlashCard entity = getConverter().getEntity(dto);
EntityAuditingUtil.configureCreatedByAndTime(entity, getAuditingUserId());
configureCreatedByAndTime(entity);
entity.setTags(configureTags(dto.getTags()));
final FlashCard result = repository.save(entity);
return convertAndInitializeEntity(result);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@

package org.robbins.flashcards.repository.facade.impl;

import org.robbins.flashcards.conversion.DtoConverter;
import org.robbins.flashcards.dto.UserDto;
import org.robbins.flashcards.exceptions.RepositoryException;
import org.robbins.flashcards.facade.UserFacade;
import org.robbins.flashcards.model.User;
import org.robbins.flashcards.repository.UserRepository;
import org.robbins.flashcards.conversion.DtoConverter;
import org.robbins.flashcards.repository.facade.base.AbstractCrudRepositoryFacadeImpl;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
Expand Down Expand Up @@ -49,14 +49,15 @@ public UserDto findUserByOpenid(final String openid) throws RepositoryException

@Override
public UserDto save(final UserDto dto) throws RepositoryException {
User entity = getConverter().getEntity(dto);
final User entity = getConverter().getEntity(dto);

if (!dto.isNew()) {
User orig = repository.findOne(dto.getId());
entity.setCreatedBy(orig.getCreatedBy());
entity.setCreatedDate(orig.getCreatedDate());
}

return super.save(dto);
configureCreatedByAndTime(entity);
final User result = getRepository().save(entity);
return convertAndInitializeEntity(result);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@

package org.robbins.flashcards.repository.populator;

import org.robbins.flashcards.model.FlashCard;
import org.robbins.flashcards.model.util.EntityAuditingUtil;
import org.robbins.flashcards.repository.facade.impl.DefaultFlashCardRepositoryFacade;
import org.springframework.stereotype.Component;

@Component("populatingFlashcardRepositoryFacade")
public class PopulatingFlashCardRepositoryFacade extends DefaultFlashCardRepositoryFacade
{
@Override
public void configureCreatedByAndTime(FlashCard entity) {
EntityAuditingUtil.configureCreatedByAndTime(entity, 1L);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@

package org.robbins.flashcards.repository.populator;

import org.robbins.flashcards.model.Tag;
import org.robbins.flashcards.model.util.EntityAuditingUtil;
import org.robbins.flashcards.repository.facade.impl.DefaultTagRepositoryFacade;
import org.springframework.stereotype.Component;

@Component("populatingTagRepositoryFacade")
public class PopulatingTagRepositoryFacade extends DefaultTagRepositoryFacade {

@Override
public void configureCreatedByAndTime(Tag entity) {
EntityAuditingUtil.configureCreatedByAndTime(entity, 1L);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@

package org.robbins.flashcards.repository.populator;

import org.robbins.flashcards.model.User;
import org.robbins.flashcards.model.util.EntityAuditingUtil;
import org.robbins.flashcards.repository.facade.impl.DefaultUserRepositoryFacade;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

@Component("populatingUserRepositoryFacade")
public class PopulatingUserRepositoryFacade extends DefaultUserRepositoryFacade {

@Override
public void configureCreatedByAndTime(User entity) {
EntityAuditingUtil.configureCreatedByAndTime(entity, 1L);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package org.robbins.flashcards.repository.populator;


public interface RepositoryPopulator {
void populate();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package org.robbins.flashcards.repository.populator;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;

@Component
public class RepositoryPopulatorListener implements ApplicationListener<ContextRefreshedEvent>,
ApplicationContextAware {

@Autowired
private RepositoryPopulator populator;

private ApplicationContext context;

/*
* (non-Javadoc)
* @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
*/
public void setApplicationContext(ApplicationContext applicationContext) {
this.context = applicationContext;
}

/*
* (non-Javadoc)
* @see org.springframework.context.ApplicationListener#onApplicationEvent(org.springframework.context.ApplicationEvent)
*/
public void onApplicationEvent(ContextRefreshedEvent event) {

if (event.getApplicationContext().equals(context)) {
populator.populate();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package org.robbins.flashcards.repository.populator;


import com.fasterxml.jackson.databind.ObjectMapper;
import org.robbins.flashcards.facade.base.GenericCrudFacade;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.data.repository.init.Jackson2ResourceReader;
import org.springframework.data.repository.init.ResourceReader;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Component
public class ResourceReaderRepositoryPopulator implements RepositoryPopulator, InitializingBean {

private static final Logger LOGGER = LoggerFactory.getLogger(ResourceReaderRepositoryPopulator.class);

@Autowired
private ObjectMapper mapper;

@javax.annotation.Resource(name = "dtoToFacadeMap")
private Map<String, GenericCrudFacade> dtoToFacadeMap;

@javax.annotation.Resource(name = "initResourceNames")
@Autowired
private List<String> initResourceNames;

private ResourceReader reader;
private List<Resource> resources;

@Override
public void afterPropertiesSet() throws Exception {
reader = new Jackson2ResourceReader(mapper);
resources = getResources();
}

public void populate() {
resources.forEach(this::populateResource);
}

private void populateResource(final Resource resource) {
LOGGER.info(String.format("Reading resource: %s", resource));

final Object result = readObjectFrom(resource);

if (result instanceof Collection) {
((Collection<?>) result).forEach(this::populateElement);
} else {
persist(result);
}
}

private void populateElement(final Object element) {
if (element != null) {
persist(element);
} else {
LOGGER.info("Skipping null element found in unmarshal result!");
}
}

private Object readObjectFrom(Resource resource) {
try {
return getResourceReader().readFrom(resource, null);
} catch (Exception e) {
throw new RuntimeException(e);
}
}

private void persist(Object object) {

final String dtoName = object.getClass().getSimpleName();
final GenericCrudFacade facade = dtoToFacadeMap.get(dtoName);
LOGGER.debug(String.format("Persisting %s using repository %s", object, facade));
facade.save(object);
}

private List<Resource> getResources() {
if (initResourceNames == null) return new ArrayList<>();

return initResourceNames
.stream()
.map(ClassPathResource::new)
.collect(Collectors.toList());
}

private ResourceReader getResourceReader() {
return reader;
}

}
Loading

0 comments on commit 4f67edd

Please sign in to comment.