/* * 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.helper; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import java.util.logging.Logger; import org.waterforpeople.mapping.domain.AccessPoint; import org.waterforpeople.mapping.domain.AccessPoint.AccessPointType; import com.gallatinsystems.common.util.StringUtil; import com.gallatinsystems.standards.dao.CompoundStandardDao; import com.gallatinsystems.standards.dao.StandardDao; import com.gallatinsystems.standards.domain.CompoundStandard; import com.gallatinsystems.standards.domain.LevelOfServiceScore; import com.gallatinsystems.standards.domain.LevelOfServiceScore.ScoreObject; import com.gallatinsystems.standards.domain.Standard; import com.gallatinsystems.standards.domain.Standard.StandardComparisons; import com.gallatinsystems.standards.domain.Standard.StandardScope; import com.gallatinsystems.standards.domain.Standard.StandardType; import com.gallatinsystems.standards.domain.Standard.StandardValueType; import com.gallatinsystems.standards.domain.StandardDef; public class ScoringHelper { private static Logger log = Logger.getLogger(ScoringHelper.class.getName()); public LevelOfServiceScore scoreWaterPointByLevelOfService(AccessPoint ap, StandardType scoreType) { LevelOfServiceScore los = new LevelOfServiceScore(); los.setScoreType(scoreType); los.setObjectKey(ap.getKey()); los.setScoreObject(ScoreObject.AccessPoint); if (ap.getImprovedWaterPointFlag()) { ScoreDetailContainer sdc = scoreStandard(ap, scoreType); los.setScore(sdc.getScore()); if (sdc.getDetails() != null) los.setScoreDetails(sdc.getDetails()); sdc = scoreCompound(ap, scoreType); los.setScore(los.getScore() + sdc.getScore()); if (los.getScoreDetails() != null && sdc.getDetails() != null) { ArrayList<String> temp = los.getScoreDetails(); temp.addAll(sdc.getDetails()); los.setScoreDetails(temp); } } else { los.setScore(0); los.addScoreDetail("0 not improved waterpoint"); } return los; } private ScoreDetailContainer scoreCompound(AccessPoint ap, StandardType scoreType) { ScoreDetailContainer sdc = new ScoreDetailContainer(); CompoundStandardDao csdao = new CompoundStandardDao(); List<CompoundStandard> csList = csdao.listByType(scoreType); for (CompoundStandard item : csList) { StandardDef left = item.getStandardLeft(); StandardDef right = item.getStandardRight(); ScoreDetailContainer sdcLeft = processStandard(left, ap); ScoreDetailContainer sdcRight = processStandard(right, ap); if (item.getOperator().equals(CompoundStandard.Operator.AND)) { if (sdcLeft.getScore().equals(1) && sdcRight.getScore().equals(1)) { sdc.setScore(sdc.getScore() + 1); sdc.add("Plus 1 for compound rule" + item.toString()); } else { sdc.setScore(sdc.getScore() + 0); sdc.add("Plus 0 for compound Rule: " + item.toString()); } } else if (item.getOperator().equals(CompoundStandard.Operator.OR)) { if (sdcLeft.getScore().equals(1) || sdcRight.getScore().equals(1)) { sdc.setScore(sdc.getScore() + 1); sdc.add("Plus 1 for compound rule"); } else { sdc.setScore(sdc.getScore() + 0); sdc.add("Plus 0 for compound Rule: " + item); } } } return sdc; } private String formScoreDetailMessage(Integer score, String desc, String type, String attribute, String value, String operator, String compareTo) { return "Plus " + score + " for " + desc + " " + type + " " + attribute + " Value " + value + " " + operator + " " + compareTo; } public void scoreWaterPointSustainability(AccessPoint ap) { } public void scorePILevelOfService(AccessPoint ap) { } public void scorePISustainability(AccessPoint ap) { } private String getAccessPointFieldValue(AccessPoint ap, String accessPointAttribute) { Method m; String value = null; try { m = AccessPoint.class .getMethod( "get" + StringUtil .capitalizeFirstCharacterString(accessPointAttribute), (Class<?>[]) null); if (!m.getReturnType().getName().equals("java.lang.String")) { value = m.invoke(ap, (Object[]) null).toString(); } else { value = (String) m.invoke(ap, (Object[]) null); } } catch (SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NoSuchMethodException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NullPointerException e) { log.info("AccessPoint Attribute: " + accessPointAttribute); e.printStackTrace(); return null; } return value; } private Boolean compareBoolean(String uncastvalue, Boolean compareTo) { Boolean answer = null; Boolean value = Boolean.parseBoolean(uncastvalue); if (value.equals(compareTo)) { answer = true; } else { answer = false; } return answer; } public static void main(String[] args) { } private Boolean compareStrings(String apvalue, ArrayList<String> valueList, StandardComparisons operator) { if (operator.equals(StandardComparisons.equal)) { for (String item : valueList) { if (item.trim().equalsIgnoreCase(apvalue.trim())) { return true; } } return false; } else if (operator.equals(StandardComparisons.notequal)) { for (String item : valueList) { if (item.trim().equalsIgnoreCase(apvalue.trim())) { return false; } } return true; } log.warning("Operator " + operator + " not implemented for a string in a list of strings (returning false)"); return false; } private Boolean compareDouble( Standard.StandardComparisons standardComparisons, String apvalue, Double compareTo) { Boolean answer = false; if (standardComparisons.equals(StandardComparisons.lessthan)) { if (Double.parseDouble(apvalue) < compareTo) { answer = true; } } else if (standardComparisons .equals(StandardComparisons.lessthanorequal)) { if (Double.parseDouble(apvalue) <= compareTo) { answer = true; } } else if (standardComparisons.equals(StandardComparisons.greaterthan)) { if (Double.parseDouble(apvalue) > compareTo) { answer = true; } } else if (standardComparisons .equals(StandardComparisons.greaterthanorequal)) { if (Double.parseDouble(apvalue) >= compareTo) { answer = true; } } else if (standardComparisons.equals(StandardComparisons.equal)) { if (Double.parseDouble(apvalue) == compareTo) { answer = true; } } return answer; } private class ScoreDetailContainer { private Integer score = 0; private ArrayList<String> details = null; public Integer getScore() { return score; } public void setScore(Integer score) { this.score = score; } public ArrayList<String> getDetails() { return details; } public void setDetails(ArrayList<String> details) { this.details = details; } public void add(String message) { if (details == null) { details = new ArrayList<String>(); } details.add(message); } } private ScoreDetailContainer scoreStandard(AccessPoint ap, StandardType scoreType) { ArrayList<String> scoreDetails = new ArrayList<String>(); Integer score = 0; ScoreDetailContainer sdc = new ScoreDetailContainer(); StandardDao standardDao = new StandardDao(); List<Standard> standardList = standardDao .listByAccessPointTypeAndStandardType( AccessPointType.WATER_POINT, scoreType); if (standardList != null) { for (Standard standard : standardList) { sdc = processStandard(standard, ap); score = score + sdc.getScore(); scoreDetails.addAll(sdc.getDetails()); } sdc.setDetails(scoreDetails); sdc.setScore(score); return sdc; } return null; } private ScoreDetailContainer processStandard(StandardDef standard, AccessPoint ap) { ScoreDetailContainer sdc = new ScoreDetailContainer(); if (standard.getStandardScope().equals(StandardScope.Global) || (standard.getStandardScope().equals(StandardScope.Local)) && ((Standard) standard).getCountry().equals(ap.getCountryCode())) { String value = getAccessPointFieldValue(ap, ((Standard) standard).getAccessPointAttribute()); if (value == null) { sdc.add("Could not score attribute " + ((Standard) standard).getAccessPointAttribute()); sdc.setScore(0); } if (((Standard) standard).getAcessPointAttributeType().equals( StandardValueType.Boolean)) { sdc = scoreBoolean((Standard) standard, value); } else if (((Standard) standard).getAcessPointAttributeType().equals( StandardValueType.String)) { sdc = scoreString((Standard) standard, value); } else if (((Standard) standard).getAcessPointAttributeType().equals( StandardValueType.Number)) { sdc = scoreDouble((Standard) standard, value); } } return sdc; } private ScoreDetailContainer scoreBoolean(Standard standard, String value) { ScoreDetailContainer sdc = new ScoreDetailContainer(); if (standard.getAcessPointAttributeType().equals( StandardValueType.Boolean)) { if (compareBoolean(value, Boolean.parseBoolean(standard.getPositiveValues().get(0)))) { sdc.setScore(sdc.getScore() + 1); sdc.add(formScoreDetailMessage(1, standard .getStandardDescription(), " WaterPoint ", standard .getAccessPointAttribute(), value, standard .getStandardComparison().toString(), standard .getPositiveValues().toString())); } else { sdc.setScore(sdc.getScore() + 1); sdc.add(formScoreDetailMessage(0, standard .getStandardDescription(), " WaterPoint ", standard .getAccessPointAttribute(), value, standard .getStandardComparison().toString(), standard .getPositiveValues().toString())); } } return sdc; } private ScoreDetailContainer scoreString(Standard standard, String value) { ScoreDetailContainer sdc = new ScoreDetailContainer(); if (standard.getAcessPointAttributeType().equals( StandardValueType.String) && value != null) { if (this.compareStrings(value, standard.getPositiveValues(), standard.getStandardComparison())) { sdc.setScore(sdc.getScore() + 1); sdc.add(formScoreDetailMessage(1, standard .getStandardDescription(), " WaterPoint ", standard .getAccessPointAttribute(), value, standard .getStandardComparison().toString(), standard .getPositiveValues().toString())); } else { sdc.setScore(sdc.getScore() + 0); sdc.add(formScoreDetailMessage(0, standard .getStandardDescription(), " WaterPoint ", standard .getAccessPointAttribute(), value, standard .getStandardComparison().toString(), standard .getPositiveValues().toString())); } } else { sdc.setScore(sdc.getScore() + 0); sdc.add(formScoreDetailMessage(0, standard .getStandardDescription(), " WaterPoint ", standard .getAccessPointAttribute(), "Null", standard .getStandardComparison().toString(), standard .getPositiveValues().toString())); } return sdc; } private ScoreDetailContainer scoreDouble(Standard standard, String value) { ScoreDetailContainer sdc = new ScoreDetailContainer(); if (this.compareDouble(standard.getStandardComparison(), value, Double.parseDouble(standard.getPositiveValues().get(0)))) { sdc.setScore(sdc.getScore() + 1); sdc.add(formScoreDetailMessage(1, standard.getStandardDescription(), " WaterPoint ", standard .getAccessPointAttribute(), value, standard .getStandardComparison().toString(), standard .getPositiveValues().toString())); } else { sdc.setScore(sdc.getScore() + 0); sdc.add(formScoreDetailMessage(0, standard.getStandardDescription(), " WaterPoint ", standard .getAccessPointAttribute(), value, standard .getStandardComparison().toString(), standard .getPositiveValues().toString())); } return sdc; } }