package org.activityinfo.ui.client.page.entry; /* * #%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.extjs.gxt.ui.client.Style.SortDir; import com.extjs.gxt.ui.client.data.BaseTreeLoader; import com.extjs.gxt.ui.client.data.ModelData; import com.extjs.gxt.ui.client.data.RpcProxy; import com.extjs.gxt.ui.client.data.SortInfo; import com.google.common.collect.Lists; import com.google.gwt.user.client.rpc.AsyncCallback; import org.activityinfo.legacy.client.Dispatcher; import org.activityinfo.legacy.shared.command.*; import org.activityinfo.legacy.shared.command.result.AdminEntityResult; import org.activityinfo.legacy.shared.command.result.SiteResult; import org.activityinfo.legacy.shared.model.*; import org.activityinfo.ui.client.page.entry.grouping.AdminGroupingModel; import java.util.List; /** * Loads sites grouped by a set of AdminLevels */ class SiteAdminTreeLoader extends BaseTreeLoader<ModelData> implements SiteTreeLoader { private TreeProxy treeProxy; public SiteAdminTreeLoader(Dispatcher dispatcher, AdminGroupingModel groupingModel) { super(new TreeProxy(dispatcher)); treeProxy = (TreeProxy) proxy; setAdminLeafLevelId(groupingModel.getAdminLevelId()); } public void setAdminLeafLevelId(int leafLevelId) { treeProxy.setAdminLeafLevelId(leafLevelId); } @Override public void setFilter(Filter filter) { treeProxy.setFilter(filter); } @Override public boolean hasChildren(ModelData parent) { return parent instanceof AdminEntityDTO; } @Override public String getKey(ModelData model) { if (model instanceof AdminEntityDTO) { return "A" + ((AdminEntityDTO) model).getId(); } else if (model instanceof SiteDTO) { return "S" + ((SiteDTO) model).getId(); } else { return "X" + model.hashCode(); } } private static class TreeProxy extends RpcProxy<List<ModelData>> { private final Dispatcher dispatcher; private List<Integer> adminLevelIds = null; private int leafLevelId; private Filter filter; public TreeProxy(Dispatcher dispatcher) { super(); this.dispatcher = dispatcher; } public void setFilter(Filter filter) { this.filter = filter; } public void setAdminLeafLevelId(int leafLevelId) { this.leafLevelId = leafLevelId; this.adminLevelIds = null; } @Override protected void load(Object parentNode, AsyncCallback<List<ModelData>> callback) { if (adminLevelIds == null) { loadAdminLevels(parentNode, callback); } else { loadNodes(parentNode, callback); } } private void loadAdminLevels(final Object parentNode, final AsyncCallback<List<ModelData>> callback) { dispatcher.execute(new GetSchema(), new AsyncCallback<SchemaDTO>() { @Override public void onFailure(Throwable caught) { callback.onFailure(caught); } @Override public void onSuccess(SchemaDTO result) { try { initLevels(result); loadNodes(parentNode, callback); } catch (Exception e) { callback.onFailure(e); } } }); } private void initLevels(SchemaDTO result) { CountryDTO country = result.getCountryByAdminLevelId(leafLevelId); adminLevelIds = Lists.newArrayList(); for (AdminLevelDTO level : country.getAdminLevelAncestors(leafLevelId)) { adminLevelIds.add(level.getId()); } } private void loadNodes(Object parentNode, AsyncCallback<List<ModelData>> callback) { if (parentNode == null) { GetAdminEntities query = new GetAdminEntities(adminLevelIds.get(0)); query.setFilter(filter); loadAdminEntities(query, callback); } else if (parentNode instanceof AdminEntityDTO) { AdminEntityDTO parentEntity = (AdminEntityDTO) parentNode; int depth = adminLevelIds.indexOf(parentEntity.getLevelId()); if (depth + 1 < adminLevelIds.size()) { loadChildAdminLevels(parentEntity, adminLevelIds.get(depth + 1), callback); } else { loadSites(parentEntity, callback); } } } private void loadChildAdminLevels(AdminEntityDTO parentEntity, int adminLevelId, AsyncCallback<List<ModelData>> callback) { GetAdminEntities query = new GetAdminEntities(); query.setLevelId(adminLevelId); query.setParentId(parentEntity.getId()); query.setFilter(filter); loadAdminEntities(query, callback); } private void loadAdminEntities(GetAdminEntities query, final AsyncCallback<List<ModelData>> callback) { dispatcher.execute(query, new AsyncCallback<AdminEntityResult>() { @Override public void onFailure(Throwable caught) { callback.onFailure(caught); } @Override public void onSuccess(AdminEntityResult result) { callback.onSuccess((List) result.getData()); } }); } private void loadSites(AdminEntityDTO parentEntity, final AsyncCallback<List<ModelData>> callback) { Filter childFilter = new Filter(filter); childFilter.addRestriction(DimensionType.AdminLevel, parentEntity.getId()); GetSites siteQuery = new GetSites(); siteQuery.setFilter(childFilter); siteQuery.setSortInfo(new SortInfo("locationName", SortDir.ASC)); dispatcher.execute(siteQuery, new AsyncCallback<SiteResult>() { @Override public void onFailure(Throwable caught) { callback.onFailure(caught); } @Override public void onSuccess(SiteResult result) { callback.onSuccess((List) result.getData()); } }); } } }