package org.molgenis.data.index; import org.molgenis.data.AbstractRepositoryDecorator; import org.molgenis.data.Entity; import org.molgenis.data.Repository; import org.molgenis.data.RepositoryCapability; import java.util.HashSet; import java.util.Set; import java.util.stream.Stream; import static java.util.Objects.requireNonNull; /** * {@link Repository} decorator that registers changes with a {@link IndexActionRegisterServiceImpl}. */ public class IndexActionRepositoryDecorator extends AbstractRepositoryDecorator<Entity> { private final IndexActionRegisterService indexActionRegisterService; private final Repository<Entity> decorated; public IndexActionRepositoryDecorator(Repository<Entity> decorated, IndexActionRegisterService indexActionRegisterService) { this.decorated = decorated; this.indexActionRegisterService = requireNonNull(indexActionRegisterService); } @Override protected Repository<Entity> delegate() { return decorated; } @Override public Set<RepositoryCapability> getCapabilities() { Set<RepositoryCapability> capabilities = new HashSet<>(); capabilities.add(RepositoryCapability.INDEXABLE); capabilities.addAll(delegate().getCapabilities()); return capabilities; } @Override public void update(Entity entity) { delegate().update(entity); indexActionRegisterService.register(getName(), entity.getIdValue().toString()); registerRefEntityIndexActions(); } @Override public void delete(Entity entity) { indexActionRegisterService.register(getName(), entity.getIdValue().toString()); registerRefEntityIndexActions(entity); delegate().delete(entity); } @Override public void deleteById(Object id) { indexActionRegisterService.register(getName(), id.toString()); registerRefEntityIndexActions(); delegate().deleteById(id); } @Override public void deleteAll() { indexActionRegisterService.register(getName(), null); registerRefEntityIndexActions(); delegate().deleteAll(); } @Override public void add(Entity entity) { delegate().add(entity); indexActionRegisterService.register(getName(), entity.getIdValue().toString()); registerRefEntityIndexActions(entity); } @Override public Integer add(Stream<Entity> entities) { indexActionRegisterService.register(getName(), null); registerRefEntityIndexActions(); return delegate().add(entities); } @Override public void update(Stream<Entity> entities) { indexActionRegisterService.register(getName(), null); registerRefEntityIndexActions(); delegate().update(entities); } @Override public void delete(Stream<Entity> entities) { indexActionRegisterService.register(getName(), null); registerRefEntityIndexActions(); delegate().delete(entities); } @Override public void deleteAll(Stream<Object> ids) { indexActionRegisterService.register(getName(), null); registerRefEntityIndexActions(); delegate().deleteAll(ids); } /** * Register index actions for entity types with bidirectional attribute values. */ private void registerRefEntityIndexActions() { // bidirectional attribute: register indexing actions for other side getEntityType().getMappedByAttributes().forEach(mappedByAttr -> { String refEntityName = mappedByAttr.getRefEntity().getName(); indexActionRegisterService.register(refEntityName, null); }); getEntityType().getInversedByAttributes().forEach(inversedByAttr -> { String refEntityName = inversedByAttr.getRefEntity().getName(); indexActionRegisterService.register(refEntityName, null); }); } /** * Register index actions for the given entity for entity types with bidirectional attribute values. * * @param entity entity to add or delete */ private void registerRefEntityIndexActions(Entity entity) { // bidirectional attribute: register indexing actions for other side getEntityType().getMappedByAttributes().forEach(mappedByAttr -> { String refEntityName = mappedByAttr.getRefEntity().getName(); entity.getEntities(mappedByAttr.getName()).forEach( refEntity -> indexActionRegisterService.register(refEntityName, refEntity.getIdValue().toString())); }); getEntityType().getInversedByAttributes().forEach(inversedByAttr -> { Entity refEntity = entity.getEntity(inversedByAttr.getName()); if (refEntity != null) { String refEntityName = inversedByAttr.getRefEntity().getName(); indexActionRegisterService.register(refEntityName, refEntity.getIdValue().toString()); } }); } }