package org.molgenis.data.meta; import com.google.common.collect.Lists; import com.google.common.collect.TreeTraverser; import org.molgenis.data.AbstractRepositoryDecorator; import org.molgenis.data.DataService; import org.molgenis.data.Repository; import org.molgenis.data.meta.model.EntityType; import org.molgenis.data.meta.model.Package; import javax.annotation.Nonnull; import java.util.List; import java.util.stream.Stream; import java.util.stream.StreamSupport; import static com.google.common.collect.Lists.reverse; import static java.util.Objects.requireNonNull; import static org.molgenis.data.meta.model.EntityTypeMetadata.ENTITY_TYPE_META_DATA; public class PackageRepositoryDecorator extends AbstractRepositoryDecorator<Package> { private final Repository<Package> decoratedRepo; private final DataService dataService; private final EntityTypeDependencyResolver entityTypeDependencyResolver; public PackageRepositoryDecorator(Repository<Package> decoratedRepo, DataService dataService, EntityTypeDependencyResolver entityTypeDependencyResolver) { this.decoratedRepo = requireNonNull(decoratedRepo); this.dataService = requireNonNull(dataService); this.entityTypeDependencyResolver = requireNonNull(entityTypeDependencyResolver); } @Override protected Repository<Package> delegate() { return decoratedRepo; } @Override public void delete(Package entity) { deletePackage(entity); } @Override public void delete(Stream<Package> entities) { entities.forEach(this::deletePackage); } @Override public void deleteById(Object id) { deletePackage(findOneById(id)); } @Override public void deleteAll(Stream<Object> ids) { findAll(ids).forEach(this::deletePackage); } @Override public void deleteAll() { forEach(this::deletePackage); } private void deletePackage(Package package_) { // recursively delete sub packages getPackageTreeTraversal(package_).forEach(this::deletePackageAndContents); } private void deletePackageAndContents(Package package_) { // delete entities in package Repository<EntityType> entityRepo = getEntityRepository(); List<EntityType> entityTypes = Lists.newArrayList(package_.getEntityTypes()); entityRepo.delete(reverse(entityTypeDependencyResolver.resolve(entityTypes)).stream()); // delete row from package table decoratedRepo.delete(package_); } private static Stream<Package> getPackageTreeTraversal(Package package_) { return StreamSupport.stream(new PackageTreeTraverser().postOrderTraversal(package_).spliterator(), false); } private Repository<EntityType> getEntityRepository() { return dataService.getRepository(ENTITY_TYPE_META_DATA, EntityType.class); } private static class PackageTreeTraverser extends TreeTraverser<Package> { @Override public Iterable<Package> children(@Nonnull Package packageEntity) { return packageEntity.getChildren(); } } }