package org.activityinfo.legacy.shared.adapter.projection; import com.google.common.base.Function; import com.google.common.collect.Lists; import org.activityinfo.core.shared.Projection; import org.activityinfo.core.shared.criteria.Criteria; import org.activityinfo.legacy.shared.command.result.ListResult; import org.activityinfo.legacy.shared.model.*; import org.activityinfo.model.formTree.FieldPath; import org.activityinfo.model.legacy.CuidAdapter; import org.activityinfo.model.resource.ResourceId; import java.util.List; public class SiteProjector implements Function<ListResult<SiteDTO>, List<Projection>> { private final List<ProjectionUpdater<LocationDTO>> locationProjectors; private final List<ProjectionUpdater<PartnerDTO>> partnerProjectors = Lists.newArrayList(); private final List<IndicatorProjectionUpdater> indicatorProjectors = Lists.newArrayList(); private final List<ProjectionUpdater<SiteDTO>> siteProjectors = Lists.newArrayList(); private final List<AttributeProjectionUpdater> attributeProjectors = Lists.newArrayList(); private final List<ProjectionUpdater<ProjectDTO>> projectProjectors = Lists.newArrayList(); private final ActivityFormDTO activity; private final Criteria criteria; public SiteProjector(ActivityFormDTO activity, Criteria criteria, List<FieldPath> fields) { this.activity = activity; this.criteria = criteria; locationProjectors = LocationProjector.createLocationUpdaters(fields); for (FieldPath path : fields) { ResourceId fieldId = path.getLeafId(); if (fieldId.getDomain() == CuidAdapter.PARTNER_FORM_CLASS_DOMAIN) { int databaseId = CuidAdapter.getBlock(fieldId, 0); int fieldIndex = CuidAdapter.getBlock(fieldId, 1); partnerProjectors.add(new PartnerProjectionUpdater(path, databaseId, fieldIndex)); } else if (fieldId.getDomain() == CuidAdapter.INDICATOR_DOMAIN) { int indicatorId = CuidAdapter.getLegacyIdFromCuid(fieldId); indicatorProjectors.add(new IndicatorProjectionUpdater(path, indicatorId)); } else if (fieldId.getDomain() == CuidAdapter.ACTIVITY_DOMAIN) { int fieldIndex = CuidAdapter.getBlock(fieldId, 1); siteProjectors.add(new SiteProjectionUpdater(path, fieldIndex)); } else if (fieldId.getDomain() == CuidAdapter.ATTRIBUTE_GROUP_FIELD_DOMAIN) { attributeProjectors.add(new AttributeProjectionUpdater(path)); } else if (fieldId.getDomain() == CuidAdapter.PROJECT_CLASS_DOMAIN) { int fieldIndex = CuidAdapter.getBlock(fieldId, 1); projectProjectors.add(new ProjectProjectionUpdater<ProjectDTO>(path, fieldIndex)); } } } @Override public List<Projection> apply(ListResult<SiteDTO> input) { List<Projection> projections = Lists.newArrayList(); for (SiteDTO site : input.getData()) { Projection projection = new Projection(site.getInstanceId(), site.getFormClassId()); for (ProjectionUpdater<PartnerDTO> projector : partnerProjectors) { projector.update(projection, site.getPartner()); } for (ProjectionUpdater<LocationDTO> projector : locationProjectors) { projector.update(projection, site.getLocation()); } for (ProjectionUpdater<ProjectDTO> projector : projectProjectors) { projector.update(projection, site.getProject()); } for (String propertyName : site.getPropertyNames()) { if (propertyName.startsWith(IndicatorDTO.PROPERTY_PREFIX)) { Object value = site.get(propertyName); for (IndicatorProjectionUpdater projector : indicatorProjectors) { if (projector.getIndicatorId() == IndicatorDTO.indicatorIdForPropertyName(propertyName)) { if (value instanceof Number) { final double doubleValue = ((Number) value).doubleValue(); projector.update(projection, doubleValue); } else { projector.update(projection, value); } } } } else if (propertyName.startsWith(AttributeDTO.PROPERTY_PREFIX) && site.get(propertyName) == Boolean.TRUE) { final AttributeDTO attributeById = activity.getAttributeById(AttributeDTO.idForPropertyName( propertyName)); AttributeGroupDTO attributeGroup = activity.getAttributeGroupByAttributeId(attributeById.getId()); for (AttributeProjectionUpdater projector : attributeProjectors) { if (CuidAdapter.getLegacyIdFromCuid(projector.getAttributeGroupId()) == attributeGroup.getId()) { projector.update(projection, attributeById); } } } } for (ProjectionUpdater<SiteDTO> projector : siteProjectors) { projector.update(projection, site); } if (criteria.apply(projection)) { projections.add(projection); } } return projections; } }