[Suiviobsmer-commits] r822 - trunk/wao-business/src/main/java/fr/ifremer/wao/service
Author: bleny Date: 2010-12-07 14:33:10 +0000 (Tue, 07 Dec 2010) New Revision: 822 Log: refactor boarding computing in synthesis ; make it testable ; bug fixed Modified: trunk/wao-business/src/main/java/fr/ifremer/wao/service/ServiceSynthesisImpl.java Modified: trunk/wao-business/src/main/java/fr/ifremer/wao/service/ServiceSynthesisImpl.java =================================================================== --- trunk/wao-business/src/main/java/fr/ifremer/wao/service/ServiceSynthesisImpl.java 2010-12-05 20:55:28 UTC (rev 821) +++ trunk/wao-business/src/main/java/fr/ifremer/wao/service/ServiceSynthesisImpl.java 2010-12-07 14:33:10 UTC (rev 822) @@ -78,8 +78,8 @@ import java.util.Collection; import java.util.Date; import java.util.HashMap; -import java.util.Iterator; import java.util.LinkedHashMap; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.SortedMap; @@ -199,19 +199,13 @@ } /** - * We need to select the boats and for each one, the number of boardings - * done. The number of boardings is calculated with the number of contacts - * finished linked with each boat. The {@code fromDate} is used to filter - * results since this date. For observer view, only results for his - * company is needed. * - * @return a BoardingResult which contains the number of boats for boardings - * and for invalid boardings from 1 to {@code MAX_BOARDINGS}, the boat with - * the max boarding and its value. - * @throws WaoException + * @param data for each boat, a set of ordered contact (a sample row code + * and the tides begin dates) + * @return a boarding result */ - @Override - protected BoardingResult executeGetBoardingBoats(TopiaContext transaction, SamplingFilter filter) throws Exception { + protected BoardingResult computeBoardingReasult(Map<Boat, LinkedHashMap<String, List<Date>>> data) { + Map<String, Integer> mapBoarding = new LinkedHashMap<String, Integer>(); BoardingResult result = new BoardingResultImpl(); result.setBoardings(mapBoarding); @@ -227,6 +221,102 @@ } mapBoarding.put(maxBoardingsKey, 0); + int maxBoardingCount = -1; + Boat maxBoardingBoat = null; + + int invalidBoardingTotal = 0; + int boardingTotal = 0; + + for (Map.Entry<Boat, LinkedHashMap<String, List<Date>>> entry : data.entrySet()) { + Boat boat = entry.getKey(); + LinkedHashMap<String, List<Date>> codesAndTides = entry.getValue(); + + if (log.isDebugEnabled()) { + StringBuilder logMessage = new StringBuilder(); + logMessage.append("in data, for boat " + boat.getName() + " tides are :"); + for (Map.Entry<String, List<Date>> codeAndTides : codesAndTides.entrySet()) { + logMessage.append(codeAndTides.getKey() + " -> " + codeAndTides.getValue()); + } + log.debug(logMessage.toString()); + } + + int boardingCount = 0; + int invalidBoardingCount = 0; + + for (Map.Entry<String, List<Date>> codeAndTides : codesAndTides.entrySet()) { + List<Date> tides = codeAndTides.getValue(); + + boardingCount += tides.size(); + + Date lastTideBeginDate = null; + for (Date tideBeginDate : tides) { + + if (lastTideBeginDate != null && // prevent NPE for first iteration + DateUtil.getDifferenceInMonths(lastTideBeginDate, tideBeginDate) <= 3) { + + invalidBoardingCount += 1; + } + + lastTideBeginDate = tideBeginDate; + } + } + + invalidBoardingTotal += invalidBoardingCount; + boardingTotal += boardingCount; + + // update max + if (boardingCount > maxBoardingCount) { + maxBoardingCount = boardingCount; + maxBoardingBoat = boat; + } + + // update mapBoarding + String key; + if (boardingCount >= MAX_BOARDINGS) { + key = maxBoardingsKey; + } else { + key = String.valueOf(boardingCount); + } + + Integer oldValue = mapBoarding.get(key); + // add one more boat for "key" number of boardings + mapBoarding.put(key, oldValue + 1); + + if (log.isDebugEnabled()) { + log.debug(boat + " made " + boardingCount + " boardings"); + } + + if (log.isDebugEnabled()) { + log.debug("boat " + boat.getName() + " did " + invalidBoardingCount + + " invalid boardings on " + boardingCount); + } + } + + result.setMaxBoardingValue(maxBoardingCount); + result.setMaxBoardingBoat(maxBoardingBoat); + result.setBoardingsCount(boardingTotal); + result.setInvalidBoardingsCount(invalidBoardingTotal); + result.setValidBoardingsCount(boardingTotal - invalidBoardingTotal); + + return result; + + } + + /** + * We need to select the boats and for each one, the number of boardings + * done. The number of boardings is calculated with the number of contacts + * finished linked with each boat. The {@code fromDate} is used to filter + * results since this date. For observer view, only results for his + * company is needed. + * + * @return a BoardingResult which contains the number of boats for boardings + * and for invalid boardings from 1 to {@code MAX_BOARDINGS}, the boat with + * the max boarding and its value. + * @throws WaoException + */ + @Override + protected BoardingResult executeGetBoardingBoats(TopiaContext transaction, SamplingFilter filter) throws Exception { + // The number of boardings is the number of finished contacts // Use fromDate to filter contacts finished from this date // No need to use boat filter for this method @@ -263,13 +353,11 @@ log.trace("Exec query : " + query); } - List<Object[]> nbBoardingsByBoat = transaction.findByQuery(query); + List<Object[]> boardingsByBoat = transaction.findByQuery(query); - - if (log.isDebugEnabled()) { - for (Object[] row : nbBoardingsByBoat) { - log.debug("results for nbBoardingBoats " + Arrays.toString(row)); + for (Object[] row : boardingsByBoat) { + log.debug("result in boardingsByBoat " + Arrays.toString(row)); } } @@ -285,101 +373,28 @@ // [ARC EN CIEL, 2009_0200, 2010-01-17 00:00:00.0] // [ARC EN CIEL, 2009_0200, 2010-02-13 00:00:00.0] - String lastBoatName = null; - String lastSampleRowCode = null; - Date lastTideBeginDate = null; + Map<Boat, LinkedHashMap<String, List<Date>>> data = new HashMap<Boat, LinkedHashMap<String, List<Date>>>(); - int currentBoardingCount = 1; - - int maxBoardingCount = -1; - Boat maxBoardingBoat = null; - - int invalidBoardingCount = 0; - - // We will browse result line after line, at each line, we know what was - // in the last line. By Comparing we know if it's the same boat. - // If yes, check sample-row and date to count a possible invalid - // boarding. If no, we changed boat and then we can add it to the totals - // and consider it as a maximum - //for (Object[] row : nbBoardingsByBoat) { - Iterator<Object[]> it = nbBoardingsByBoat.iterator(); - while (it.hasNext()) { - Object[] row = it.next(); - + for (Object[] row : boardingsByBoat) { Boat boat = (Boat) row[0]; - String boatName = boat.getName(); String sampleRowCode = (String) row[1]; Date tideBeginDate = (Date) row[2]; - if (log.isDebugEnabled()) { - log.debug("results for nbBoardingBoats " + Arrays.toString(row)); + LinkedHashMap<String, List<Date>> value = data.get(boat); + if (value == null) { + value = new LinkedHashMap<String, List<Date>>(); + data.put(boat, value); } - if (boatName.equals(lastBoatName)) { - - currentBoardingCount += 1; - - if (sampleRowCode.equals(lastSampleRowCode) && - DateUtil.getDifferenceInMonths(lastTideBeginDate, tideBeginDate) <= 3) { - - invalidBoardingCount += 1; - } - + List<Date> dates = value.get(sampleRowCode); + if (dates == null) { + dates = new LinkedList<Date>(); + value.put(sampleRowCode, dates); } - - boolean computeValue = // there is two case when we know we can consider we - // computed a new set of data for a same boat - - // first case, current row has not the same boat - // as last row. Common case : we can conclude - // things from last rows - ! boatName.equals(lastBoatName) - // just one exception for the first row - // don't conclude things for boat "null" - && lastBoatName != null - - // second case, this is the last boat and - // the last row, we must compute now or we will - // miss data for the last boat - || ! it.hasNext(); - - if (computeValue) { - - // update max - if (currentBoardingCount > maxBoardingCount) { - maxBoardingCount = currentBoardingCount; - maxBoardingBoat = boat; - } - - // update mapBoarding - String key; - if (currentBoardingCount >= MAX_BOARDINGS) { - key = maxBoardingsKey; - } else { - key = String.valueOf(currentBoardingCount); - } - - Integer oldValue = mapBoarding.get(key); - mapBoarding.put(key, oldValue + 1); - - if (log.isDebugEnabled()) { - log.debug(lastBoatName + " made " + currentBoardingCount + " boardings"); - } - - // re-initialize values for the new boat in the lines - currentBoardingCount = 1; - } - - lastBoatName = boatName; - lastSampleRowCode = sampleRowCode; - lastTideBeginDate = tideBeginDate; + dates.add(tideBeginDate); } - result.setMaxBoardingValue(maxBoardingCount); - result.setMaxBoardingBoat(maxBoardingBoat); - result.setBoardingsCount(nbBoardingsByBoat.size()); - result.setInvalidBoardingsCount(invalidBoardingCount); - result.setValidBoardingsCount(nbBoardingsByBoat.size() - invalidBoardingCount); + BoardingResult result = computeBoardingReasult(data); return result; }
participants (1)
-
bleny@users.labs.libre-entreprise.org