Java tutorial
/* * This program is part of the OpenLMIS logistics management information system platform software. * Copyright 2017 VillageReach * * This program is free software: you can redistribute it and/or modify it under the terms * of the GNU Affero General Public License as published by the Free Software Foundation, either * version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Affero General Public License for more details. You should have received a copy of * the GNU Affero General Public License along with this program. If not, see * http://www.gnu.org/licenses. For additional information contact info@OpenLMIS.org. */ package org.openlmis.fulfillment; import static org.openlmis.fulfillment.util.Pagination.DEFAULT_PAGE_NUMBER; import org.javers.core.Javers; import org.javers.core.metamodel.object.CdoSnapshot; import org.javers.repository.jql.QueryBuilder; import org.javers.spring.annotation.JaversSpringDataAuditable; import org.openlmis.fulfillment.domain.BaseEntity; import org.slf4j.ext.XLogger; import org.slf4j.ext.XLoggerFactory; import org.slf4j.profiler.Profiler; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Profile; import org.springframework.core.annotation.Order; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; import java.util.List; import java.util.Map; import javax.annotation.Resource; /** * AuditLogInitializer runs after its associated Spring application has loaded. * It examines each domain object in the database and registers them with JaVers * if they haven't already been so. This is, in part, a fix for * <a href="https://github.com/javers/javers/issues/214">this issue</a>. */ @Component @Profile("refresh-db") @Order(20) @Transactional public class AuditLogInitializer implements CommandLineRunner { private static final XLogger LOGGER = XLoggerFactory.getXLogger(AuditLogInitializer.class); @Autowired private ApplicationContext applicationContext; @Resource(name = "javersProvider") private Javers javers; /** * This method is part of CommandLineRunner and is called automatically by Spring. * @param args Main method arguments. */ @Override public void run(String... args) { LOGGER.entry(); Profiler profiler = new Profiler("RUN_AUDIT_LOG_INIT"); profiler.setLogger(LOGGER); profiler.start("GET_AUDITABLE_REPOSITORIES"); //Get all JaVers repositories. Map<String, Object> repositoryMap = applicationContext .getBeansWithAnnotation(JaversSpringDataAuditable.class); //For each one... for (Map.Entry<String, Object> entry : repositoryMap.entrySet()) { String beanName = entry.getKey(); Object bean = entry.getValue(); profiler.start("CREATE_SNAPSHOTS_OF_" + beanName); createSnapshots(bean); } profiler.stop().log(); LOGGER.exit(); } private void createSnapshots(Object bean) { if (bean instanceof PagingAndSortingRepository) { createSnapshots((PagingAndSortingRepository<?, ?>) bean); } else if (bean instanceof CrudRepository) { createSnapshots((CrudRepository<?, ?>) bean); } } private void createSnapshots(PagingAndSortingRepository<?, ?> repository) { Pageable pageable = new PageRequest(DEFAULT_PAGE_NUMBER, 2000); while (true) { Page<?> page = repository.findAll(pageable); if (!page.hasContent()) { break; } page.forEach(this::createSnapshot); pageable = pageable.next(); } } private void createSnapshots(CrudRepository<?, ?> repository) { //... retrieve all of its domain objects and... repository.findAll().forEach(this::createSnapshot); } private void createSnapshot(Object object) { //...check whether there exists a snapshot for it in the audit log. // Note that we don't care about checking for logged changes, per se, // and thus use findSnapshots() rather than findChanges() BaseEntity baseEntity = (BaseEntity) object; QueryBuilder jqlQuery = QueryBuilder.byInstanceId(baseEntity.getId(), object.getClass()); List<CdoSnapshot> snapshots = javers.findSnapshots(jqlQuery.build()); //If there are no snapshots of the domain object, then take one if (snapshots.size() == 0) { javers.commit("System: AuditLogInitializer", baseEntity); } } }