package org.activityinfo.legacy.shared.impl; /* * #%L * ActivityInfo Server * %% * Copyright (C) 2009 - 2013 UNICEF * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU 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 General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program. If not, see * <http://www.gnu.org/licenses/gpl-3.0.html>. * #L% */ import com.bedatadriven.rebar.sql.client.query.SqlDialect; import com.google.common.collect.Lists; import com.google.common.collect.Sets; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.inject.Inject; import org.activityinfo.legacy.shared.Log; import org.activityinfo.legacy.shared.command.DimensionType; import org.activityinfo.legacy.shared.command.Filter; import org.activityinfo.legacy.shared.command.PivotSites; import org.activityinfo.legacy.shared.command.PivotSites.PivotResult; import org.activityinfo.legacy.shared.command.result.Bucket; import org.activityinfo.legacy.shared.impl.pivot.*; import java.util.List; import java.util.Set; import java.util.logging.Logger; public class PivotSitesHandler implements CommandHandlerAsync<PivotSites, PivotSites.PivotResult> { private final SqlDialect dialect; private static final Logger LOGGER = Logger.getLogger(PivotSitesHandler.class.getName()); private List<BaseTable> baseTables = Lists.newArrayList(); @Inject public PivotSitesHandler(SqlDialect dialect) { this.dialect = dialect; baseTables.add(new SumAvgIndicatorValues()); baseTables.add(new CountIndicatorValues()); baseTables.add(new LinkedSumAvgIndicatorValues()); baseTables.add(new Targets()); baseTables.add(new SiteCounts()); baseTables.add(new LinkedSiteCounts()); baseTables.add(new DimensionValues()); baseTables.add(new LinkedDimensionValues()); } @Override public void execute(PivotSites command, ExecutionContext context, final AsyncCallback<PivotResult> callback) { LOGGER.fine("Pivoting: " + command); if (command.getFilter() == null || filterIsToBroad(command.getFilter())) { Log.error("Filter is to broad: " + command.getFilter()); PivotResult emptyResult = new PivotResult(); emptyResult.setBuckets(Lists.<Bucket>newArrayList()); callback.onSuccess(emptyResult); return; } final PivotQueryContext queryContext = new PivotQueryContext(command, context, dialect); final List<WorkItem> workList = Lists.newArrayList(); for (BaseTable baseTable : baseTables) { if (baseTable.accept(command)) { workList.add(new PivotQuery(queryContext, baseTable)); } } if(command.isPivotedBy(DimensionType.Indicator)) { workList.add(new ErrorLoggingWorkItem(new CalculatedIndicatorsQuery(queryContext))); } if (workList.isEmpty()) { callback.onSuccess(new PivotResult(Lists.<Bucket>newArrayList())); } final Set<WorkItem> remaining = Sets.newHashSet(workList); final List<Throwable> errors = Lists.newArrayList(); for (final WorkItem workItem : workList) { workItem.execute(new AsyncCallback<Void>() { @Override public void onSuccess(Void voidResult) { if (errors.isEmpty()) { remaining.remove(workItem); if (remaining.isEmpty()) { try { callback.onSuccess(new PivotResult(queryContext.getBuckets())); } catch (Throwable e) { callback.onFailure(e); } } } } @Override public void onFailure(Throwable caught) { if (errors.isEmpty()) { callback.onFailure(caught); } errors.add(caught); } }); } } /** * Ensure that there is some filtering so that we don't burden the database * with a query that returns everything! */ private boolean filterIsToBroad(Filter filter) { if (filter.isRestricted(DimensionType.Indicator)) { return false; } if (filter.isRestricted(DimensionType.Activity)) { return false; } if (filter.isRestricted(DimensionType.Database)) { return false; } if (filter.isRestricted(DimensionType.Site)) { return false; } return true; } }