/* * Copyright (C) 2010-2012 Stichting Akvo (Akvo Foundation) * * This file is part of Akvo FLOW. * * Akvo FLOW is free software: you can redistribute it and modify it under the terms of * the GNU Affero General Public License (AGPL) as published by the Free Software Foundation, * either version 3 of the License or any later version. * * Akvo FLOW 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 Affero General Public License included below for more details. * * The full license text can also be seen at <http://www.gnu.org/licenses/agpl.html>. */ package org.waterforpeople.mapping.analytics.dao; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.jdo.PersistenceManager; import org.waterforpeople.mapping.analytics.domain.AccessPointStatusSummary; import org.waterforpeople.mapping.domain.AccessPoint; import com.gallatinsystems.framework.dao.BaseDAO; import com.gallatinsystems.framework.servlet.PersistenceFilter; import com.gallatinsystems.gis.geography.domain.Country; import com.google.appengine.api.datastore.DatastoreTimeoutException; /** * updates access point status summary objects * * @author Christopher Fagiani */ public class AccessPointStatusSummaryDao extends BaseDAO<AccessPointStatusSummary> { public AccessPointStatusSummaryDao() { super(AccessPointStatusSummary.class); } /** * synchronized static method so that only 1 thread can be updating a summary at a time. This is * inefficient but is the only way we can be sure we're keeping the count consistent since there * is no "select for update" or sql dml-like construct * * @param answer */ @SuppressWarnings("rawtypes") public static synchronized void incrementCount(AccessPoint ap, Country c, int unit) { PersistenceManager pm = PersistenceFilter.getManager(); javax.jdo.Query query = pm.newQuery(AccessPointStatusSummary.class); query .setFilter("year == yearParam && status == statusParam && community == communityParam && type == typeParam"); query .declareParameters("String yearParam, String statusParam, String communityParam, String typeParam"); String yearString = null; if (ap.getCollectionDate() != null) { GregorianCalendar cal = new GregorianCalendar(); cal.setTime(ap.getCollectionDate()); yearString = cal.get(Calendar.YEAR) + ""; } List results = (List) query.executeWithArray(yearString, ap .getPointStatus(), ap.getCommunityCode(), ap.getPointType()); AccessPointStatusSummary summary = null; if ((results == null || results.size() == 0) && unit > 0) { summary = new AccessPointStatusSummary(); summary.setCount(1L); summary.setYear(yearString); summary.setStatus(ap.getPointStatus()); if (ap.getCountryCode() != null) { summary.setCountry(ap.getCountryCode()); } else { summary.setCountry(c.getIsoAlpha2Code()); } summary.setCommunity(ap.getCommunityCode()); summary.setType(ap.getPointType() != null ? ap.getPointType() .toString() : "UNKNOWN"); } else if (unit > 0) { summary = (AccessPointStatusSummary) results.get(0); summary.setCount(summary.getCount() + unit); } if (summary != null) { AccessPointStatusSummaryDao thisDao = new AccessPointStatusSummaryDao(); if (summary.getCount() == 0 && summary.getKey() != null) { thisDao.delete(summary); } else if (summary.getCount() > 0) { try { thisDao.save(summary); } catch (DatastoreTimeoutException te) { sleep(); thisDao.save(summary); } } } } /** * lists access point summary objects that match the criteria passed in, any of which are * nullable. * * @param country * @param community * @param year * @param type * @return */ @SuppressWarnings("unchecked") public List<AccessPointStatusSummary> listByLocationAndYear(String country, String community, String type, String year, String status) { PersistenceManager pm = PersistenceFilter.getManager(); javax.jdo.Query query = pm.newQuery(AccessPointStatusSummary.class); StringBuilder filterString = new StringBuilder(); StringBuilder paramString = new StringBuilder(); Map<String, Object> paramMap = new HashMap<String, Object>(); appendNonNullParam("country", filterString, paramString, "String", country, paramMap); appendNonNullParam("community", filterString, paramString, "String", community, paramMap); appendNonNullParam("year", filterString, paramString, "String", year, paramMap); appendNonNullParam("type", filterString, paramString, "String", type, paramMap); appendNonNullParam("status", filterString, paramString, "String", status, paramMap); query.setFilter(filterString.toString()); query.declareParameters(paramString.toString()); return (List<AccessPointStatusSummary>) query.executeWithMap(paramMap); } /** * lists the summary objects for a country with a creation date on or after the data passed in * * @param country * @param creationDate * @param cursorString * @return */ @SuppressWarnings("unchecked") public List<AccessPointStatusSummary> listByCountryAndCreationDate( String country, Date creationDate, String cursorString) { PersistenceManager pm = PersistenceFilter.getManager(); javax.jdo.Query query = pm.newQuery(AccessPointStatusSummary.class); query .setFilter("country == countryParam && createdDateTime > dateParam"); query.declareParameters("String countryParam, Date dateParam"); query.declareImports("import java.util.Date"); prepareCursor(cursorString, query); return (List<AccessPointStatusSummary>) query.execute(country, creationDate); } }