package org.activityinfo.ui.client.component.form.field.hierarchy; import com.google.common.base.Function; import com.google.common.collect.Maps; import com.google.common.collect.Sets; import org.activityinfo.core.client.InstanceQuery; import org.activityinfo.core.client.ResourceLocator; import org.activityinfo.core.shared.Projection; import org.activityinfo.core.shared.criteria.IdCriteria; import org.activityinfo.model.resource.ResourceId; import org.activityinfo.promise.Promise; import java.util.List; import java.util.Map; import java.util.Set; import static org.activityinfo.core.shared.application.ApplicationProperties.LABEL_PROPERTY; import static org.activityinfo.core.shared.application.ApplicationProperties.PARENT_PROPERTY; class InitialSelection { private final Hierarchy hierarchy; private final Map<ResourceId, Projection> selection = Maps.newHashMap(); public InitialSelection(Hierarchy hierarchy) { this.hierarchy = hierarchy; } public Promise<Void> fetch(ResourceLocator locator, Set<ResourceId> ids) { if(ids == null || ids.isEmpty()) { return Promise.done(); } else { return fetchLabelAndParentIds(locator, ids); } } private Promise<Void> fetchLabelAndParentIds(final ResourceLocator locator, Set<ResourceId> instanceIds) { InstanceQuery query = InstanceQuery .select(LABEL_PROPERTY, PARENT_PROPERTY) .where(new IdCriteria(instanceIds)) .build(); return locator.query(query) .join(new Function<List<Projection>, Promise<Void>>() { @Override public Promise<Void> apply(List<Projection> projections) { Set<ResourceId> parents = populateSelection(projections); if (parents.isEmpty()) { return Promise.done(); } else { return fetchLabelAndParentIds(locator, parents); } } }); } private Set<ResourceId> populateSelection(List<Projection> projections) { Set<ResourceId> parents = Sets.newHashSet(); for(Projection projection : projections) { Level level = hierarchy.getLevel(projection.getRootClassId()); if(level != null) { selection.put(projection.getRootClassId(), projection); if(!level.isRoot()) { ResourceId parentId = projection.getReferenceValue(PARENT_PROPERTY) .iterator().next(); assert parentId != null; parents.add(parentId); } } } parents.removeAll(selection.keySet()); return parents; } public Map<ResourceId, Projection> getSelection() { return selection; } }