data4impact/apps/data4impact-importer/src/main/java/eu/data4impact/Data4ImpactImporter.java

89 lines
2.8 KiB
Java

package eu.data4impact;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.Optional;
import javax.persistence.EntityManagerFactory;
import javax.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Component;
import com.fasterxml.jackson.databind.ObjectMapper;
@Component
public class Data4ImpactImporter {
@Autowired
private ApplicationContext applicationContext;
@Autowired
private EntityManagerFactory entityManagerFactory;
private final ObjectMapper jsonMapper = new ObjectMapper();
@Transactional
public <T> void importFileJson(final Path file, final Class<T> tableClass) {
try {
final LocalDateTime start = LocalDateTime.now();
final JpaRepository<T, ?> repo = findRepositorForTable(tableClass);
Files.lines(file, StandardCharsets.UTF_8).forEach(l -> processLine(l, tableClass, repo));
final LocalDateTime end = LocalDateTime.now();
final double time = Duration.between(start, end).toNanos() / 1000000000.0;
System.out.printf("\nDone in %.3f sec.\n\n", time);
} catch (final IOException e) {
throw new RuntimeException(e);
}
}
@SuppressWarnings("unchecked")
private <T, K> void processLine(final String line, final Class<T> tableClass, final JpaRepository<T, K> repo) {
try {
final T obj = jsonMapper.readValue(line, tableClass);
final K id = (K) entityManagerFactory.getPersistenceUnitUtil().getIdentifier(obj);
processObject(obj, id, repo);
} catch (final IOException | IllegalAccessException | InstantiationException e) {
throw new RuntimeException(e);
}
}
private <T, K> void processObject(final T obj, final K id, final JpaRepository<T, K> repo) throws IllegalAccessException, InstantiationException {
System.out.println(id);
final Optional<T> old = repo.findById(id);
if (old.isPresent()) {
repo.save(ObjectMerger.mergeObjects(old.get(), obj));
} else {
repo.save(obj);
}
}
@Transactional
public <T> void importFileXML(final String file, final Class<?> tableClass) {
throw new RuntimeException("-- NOT IMPLEMENTED --");
}
@SuppressWarnings("unchecked")
private <T, K> JpaRepository<T, K> findRepositorForTable(final Class<T> clazz) {
final String repoName = clazz.getSimpleName() + "Repository";
return applicationContext.getBeansOfType(JpaRepository.class)
.entrySet()
.stream()
.filter(e -> e.getKey().equalsIgnoreCase(repoName))
.map(e -> e.getValue())
.findFirst()
.orElseThrow(() -> new RuntimeException("No repository found for class " + clazz.getName()));
}
}