Author: chatellier Date: 2010-10-27 15:38:56 +0000 (Wed, 27 Oct 2010) New Revision: 109 Log: Fin du merge d'especes Modified: trunk/coser-business/src/main/java/fr/ifremer/coser/command/MergeSpeciesCommand.java trunk/coser-business/src/test/java/fr/ifremer/coser/services/CommandServiceTest.java trunk/coser-business/src/test/java/fr/ifremer/coser/services/ProjectServiceTest.java trunk/coser-business/src/test/resources/csv/correct/testlength.csv Modified: trunk/coser-business/src/main/java/fr/ifremer/coser/command/MergeSpeciesCommand.java =================================================================== --- trunk/coser-business/src/main/java/fr/ifremer/coser/command/MergeSpeciesCommand.java 2010-10-27 14:23:04 UTC (rev 108) +++ trunk/coser-business/src/main/java/fr/ifremer/coser/command/MergeSpeciesCommand.java 2010-10-27 15:38:56 UTC (rev 109) @@ -27,15 +27,18 @@ import java.util.Iterator; +import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.NotImplementedException; +import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import fr.ifremer.coser.CoserBusinessException; +import fr.ifremer.coser.CoserConstants; import fr.ifremer.coser.bean.AbstractDataContainer; -import fr.ifremer.coser.bean.Control; import fr.ifremer.coser.bean.Project; import fr.ifremer.coser.data.Catch; +import fr.ifremer.coser.data.Length; /** * Merge species command. @@ -101,12 +104,142 @@ */ protected Project mergeLength(Project project, AbstractDataContainer container, String newSpecyName, String... speciesNames) { + + // Campagne;Annee;Trait;Espece;Sexe;Maturite;Longueur;Nombre;Poids;Age + + // regroupement par Campagne;Annee;Trait;Espece;Sexe;Maturite;Longueur;Age + String[] commonTuple = null; + String[] mergeTuple = null; + int mergeTupleIndex = -1; + + // parcours des elements + Iterator<String[]> itTuple = container.getLength().iterator(); + itTuple.next(); // skip header + int index = 1; // skip header + + while (itTuple.hasNext()) { + String[] tuple = itTuple.next(); + + // search for diff in commonTuple and current tuple + // 1 = skip line index (0) + boolean diffFound = false; + if (commonTuple != null) { + for (int tupleIndex = 0 ; tupleIndex < commonTuple.length && !diffFound; ++tupleIndex) { + if (tupleIndex != Length.INDEX_LINE && tupleIndex != Length.INDEX_NUMBER + && tupleIndex != Length.INDEX_WEIGHT && tupleIndex != Length.INDEX_SPECIES) { + if (!commonTuple[tupleIndex].equals(tuple[tupleIndex])) { + diffFound = true; + } + } + } + } + else { + diffFound = true; + } + + if (diffFound) { + mergeTuple = null; + // clone parce que si c'est un tuple de merge... + commonTuple = (String[])ArrayUtils.clone(tuple); + } + + // test si l'espece en cours fait partie de celle a merger + String species = tuple[Length.INDEX_SPECIES]; + boolean specyFound = false; + for (String specy : speciesNames) { + if (specy.equals(species)) { + specyFound = true; + } + } + + // si l'espece est a merger, on se souvient du tuple + // principale a merge, ou on merge avec le tuple + // principal si on a deja un tuple principal + if (specyFound) { + if (mergeTuple == null) { + mergeTuple = tuple; + mergeTuple[Length.INDEX_SPECIES] = newSpecyName; + mergeTupleIndex = index; + } + else { + mergeTuple = mergeLengths(mergeTuple, tuple); + // et on supprime le tuple + // qui a ete merge + itTuple.remove(); + // bidouille le remove decalle les index suivants + index--; + } + + container.getLength().set(mergeTupleIndex, mergeTuple); + } + + index++; + } return project; } /** + * Merge deux lines des catch. + * + * Le resultat est mergé dans {@code tuple1} et retourné. + * + * Somme les "Nombre" et "Poids" + * + * @param mergeTuple + * @param tuple + * @return + */ + protected String[] mergeLengths(String[] tuple1, String[] tuple2) { + + try { + // number + if (isNotAvailableData(tuple1[Length.INDEX_NUMBER]) || isNotAvailableData(tuple2[Length.INDEX_NUMBER])) { + tuple1[Length.INDEX_NUMBER] = CoserConstants.VALIDATION_NA; + } + else { + double nombre1 = Double.parseDouble(tuple1[Length.INDEX_NUMBER]); + double nombre2 = Double.parseDouble(tuple2[Length.INDEX_NUMBER]); + tuple1[Length.INDEX_NUMBER] = String.valueOf(nombre1 + nombre2); + } + + // weight + if (isNotAvailableData(tuple1[Length.INDEX_WEIGHT]) || isNotAvailableData(tuple2[Length.INDEX_WEIGHT])) { + tuple1[Length.INDEX_WEIGHT] = CoserConstants.VALIDATION_NA; + } + else { + double poids1 = Double.parseDouble(tuple1[Length.INDEX_WEIGHT]); + double poids2 = Double.parseDouble(tuple2[Length.INDEX_WEIGHT]); + tuple1[Length.INDEX_WEIGHT] = String.valueOf(poids1 + poids2); + } + } + catch (NumberFormatException ex) { + if (log.isWarnEnabled()) { + log.warn("Can't convert data as double for merge", ex); + } + } + return tuple1; + } + + /** + * Return true if a value + * + * @param data + * @return + */ + protected boolean isNotAvailableData(String data) { + boolean result = false; + if (StringUtils.isEmpty(data) || data.equals(CoserConstants.VALIDATION_NA)) { + result = true; + } + return result; + } + + /** * Fusion d'especes dans les données de taille. * + * Peut etre a revoir, car ca fonctionne, mais le traitement + * est dépendant de l'ordre. + * * @param project project * @param container data container * @param newSpecyName new specy name (after merge) @@ -119,11 +252,9 @@ // "Campagne","Annee","Trait","Espece","Nombre","Poids" // regroupement par campagne/annee/trait - String lastCampagne = null; - String lastAnnee = null; - String lastTraits = null; - String[] tupleFound = null; - int tupleIndex = -1; + String[] commonTuple = null; + String[] mergeTuple = null; + int mergeTupleIndex = -1; // parcours des elements Iterator<String[]> itTuple = container.getCatch().iterator(); @@ -134,19 +265,27 @@ // si les valeurs servant au bornes de regroupement // on changer, on reset les données du merge - String currentCampagne = tuple[Catch.INDEX_SURVEY]; - String currentAnnee = tuple[Catch.INDEX_YEAR]; - String currentTraits = tuple[Catch.INDEX_HAUL]; - if (!currentCampagne.equals(lastCampagne) || - !currentAnnee.equals(lastAnnee) || - !currentTraits.equals(lastTraits)) { - - tupleFound = null; - lastCampagne = currentCampagne; - lastAnnee = currentAnnee; - lastTraits = currentTraits; + boolean diffFound = false; + if (commonTuple != null) { + for (int tupleIndex = 0 ; tupleIndex < commonTuple.length && !diffFound; ++tupleIndex) { + if (tupleIndex != Catch.INDEX_LINE && tupleIndex != Catch.INDEX_NUMBER + && tupleIndex != Catch.INDEX_WEIGHT && tupleIndex != Catch.INDEX_SPECIES) { + if (!commonTuple[tupleIndex].equals(tuple[tupleIndex])) { + diffFound = true; + } + } + } } + else { + diffFound = true; + } + if (diffFound) { + mergeTuple = null; + // clone parce que si c'est un tuple de merge... + commonTuple = (String[])ArrayUtils.clone(tuple); + } + // test si l'espece en cours fait partie de celle a merger String species = tuple[Catch.INDEX_SPECIES]; boolean specyFound = false; @@ -160,13 +299,13 @@ // principale a merge, ou on merge avec le tuple // principal si on a deja un tuple principal if (specyFound) { - if (tupleFound == null) { - tupleFound = tuple; - tupleFound[3] = newSpecyName; - tupleIndex = index; + if (mergeTuple == null) { + mergeTuple = tuple; + mergeTuple[Catch.INDEX_SPECIES] = newSpecyName; + mergeTupleIndex = index; } else { - tupleFound = mergeCatches(tupleFound, tuple); + mergeTuple = mergeCatches(mergeTuple, tuple); // et on supprime le tuple // qui a ete merge itTuple.remove(); @@ -174,7 +313,7 @@ index--; } - container.getCatch().set(tupleIndex, tupleFound); + container.getCatch().set(mergeTupleIndex, mergeTuple); } index++; Modified: trunk/coser-business/src/test/java/fr/ifremer/coser/services/CommandServiceTest.java =================================================================== --- trunk/coser-business/src/test/java/fr/ifremer/coser/services/CommandServiceTest.java 2010-10-27 14:23:04 UTC (rev 108) +++ trunk/coser-business/src/test/java/fr/ifremer/coser/services/CommandServiceTest.java 2010-10-27 15:38:56 UTC (rev 109) @@ -64,14 +64,14 @@ @Test public void testDeleteLine() throws CoserBusinessException { Project project = createTestProject(projectService); - Assert.assertEquals(29, project.getControl().getLength().size()); + Assert.assertEquals(30, project.getControl().getLength().size()); DeleteLineCommand command = new DeleteLineCommand(); command.setLineIndex("2"); command.setCategory(Category.LENGTH); commandService.doAction(command, project, project.getControl()); - Assert.assertEquals(28, project.getControl().getLength().size()); + Assert.assertEquals(29, project.getControl().getLength().size()); } /** Modified: trunk/coser-business/src/test/java/fr/ifremer/coser/services/ProjectServiceTest.java =================================================================== --- trunk/coser-business/src/test/java/fr/ifremer/coser/services/ProjectServiceTest.java 2010-10-27 14:23:04 UTC (rev 108) +++ trunk/coser-business/src/test/java/fr/ifremer/coser/services/ProjectServiceTest.java 2010-10-27 15:38:56 UTC (rev 109) @@ -236,12 +236,18 @@ public void testMergeSpecies() throws CoserBusinessException { Project project = createTestProject(service); Selection selection = service.initProjectSelection(project); + selection.setName("test"); Assert.assertTrue(service.isSpecyNameExist(project, "COSER_SPECIES_MERGE")); Assert.assertEquals(25, selection.getCatch().size()); + Assert.assertEquals(30, selection.getLength().size()); project = service.mergeSpecies(project, selection, "COSER_SPECIES_MERGE", "COSER_SPECIES1", "COSER_SPECIES2"); Assert.assertEquals(19, selection.getCatch().size()); + Assert.assertEquals(29, selection.getLength().size()); + + service.createProjectSelection(project, selection); + System.out.println(selection.getName()); } } Modified: trunk/coser-business/src/test/resources/csv/correct/testlength.csv =================================================================== --- trunk/coser-business/src/test/resources/csv/correct/testlength.csv 2010-10-27 14:23:04 UTC (rev 108) +++ trunk/coser-business/src/test/resources/csv/correct/testlength.csv 2010-10-27 15:38:56 UTC (rev 109) @@ -1,29 +1,30 @@ Survey;Year;Haul;Species;Sex;Maturity;Length;Number;Weight;Age -COSER_TEST;2010;TRAIT1;COSER_SPECIES1;i;NA;29.19;1.00;NA -COSER_TEST;2010;TRAIT1;COSER_SPECIES2;i;NA;19.60;2.00;NA -COSER_TEST;2010;TRAIT1;COSER_SPECIES3;i;NA;32.93;5.00;NA -COSER_TEST;2010;TRAIT1;COSER_SPECIES3;i;NA;26.27;3.00;NA -COSER_TEST;2010;TRAIT1;COSER_SPECIES3;i;NA;35.25;4.00;NA -COSER_TEST;2010;TRAIT1;COSER_SPECIES4;i;NA;37.82;4.00;NA -COSER_TEST;2010;TRAIT2;COSER_SPECIES1;i;NA;20.07;2.00;NA -COSER_TEST;2010;TRAIT2;COSER_SPECIES1;i;NA;27.18;2.00;NA -COSER_TEST;2010;TRAIT2;COSER_SPECIES2;i;NA;21.14;1.00;NA -COSER_TEST;2010;TRAIT2;COSER_SPECIES3;i;NA;1.82;4.00;NA -COSER_TEST;2010;TRAIT2;COSER_SPECIES4;i;NA;36.55;4.00;NA -COSER_TEST;2010;TRAIT3;COSER_SPECIES1;i;NA;20.39;3.00;NA -COSER_TEST;2010;TRAIT3;COSER_SPECIES2;i;NA;19.88;3.00;NA -COSER_TEST;2010;TRAIT3;COSER_SPECIES3;i;NA;18.16;1.00;NA -COSER_TEST;2010;TRAIT3;COSER_SPECIES4;i;NA;10.22;2.00;NA -COSER_TEST;2010;TRAIT3;COSER_SPECIES4;i;NA;33.03;5.00;NA -COSER_TEST;2011;TRAIT1;COSER_SPECIES1;i;NA;1.00;4.00;NA +COSER_TEST;2010;TRAIT1;COSER_SPECIES1;i;NA;29.19;1.00;0.45;NA +COSER_TEST;2010;TRAIT1;COSER_SPECIES2;i;NA;19.60;2.00;0.34;NA +COSER_TEST;2010;TRAIT1;COSER_SPECIES2;i;NA;19.60;3.00;0.78;NA +COSER_TEST;2010;TRAIT1;COSER_SPECIES3;i;NA;32.93;5.00;0.87;NA +COSER_TEST;2010;TRAIT1;COSER_SPECIES3;f;NA;26.27;3.00;0.03;NA +COSER_TEST;2010;TRAIT1;COSER_SPECIES3;m;NA;35.25;4.00;;NA +COSER_TEST;2010;TRAIT1;COSER_SPECIES4;i;NA;37.82;4.00;0.61;NA +COSER_TEST;2010;TRAIT2;COSER_SPECIES1;i;NA;20.07;2.00;0.12;NA +COSER_TEST;2010;TRAIT2;COSER_SPECIES1;i;NA;27.18;2.00;0.92;NA +COSER_TEST;2010;TRAIT2;COSER_SPECIES2;i;NA;21.14;1.00;0.34;NA +COSER_TEST;2010;TRAIT2;COSER_SPECIES3;i;NA;1.82;4.00;0.1;NA +COSER_TEST;2010;TRAIT2;COSER_SPECIES4;i;NA;36.55;4.00;0.39;NA +COSER_TEST;2010;TRAIT3;COSER_SPECIES1;i;NA;20.39;3.00;0.28;NA +COSER_TEST;2010;TRAIT3;COSER_SPECIES2;i;NA;19.88;3.00;0.31;NA +COSER_TEST;2010;TRAIT3;COSER_SPECIES3;i;NA;18.16;1.00;0.34;NA +COSER_TEST;2010;TRAIT3;COSER_SPECIES4;i;NA;10.22;2.00;0.31;NA +COSER_TEST;2010;TRAIT3;COSER_SPECIES4;f;NA;33.03;5.00;0.26;NA +COSER_TEST;2011;TRAIT1;COSER_SPECIES1;i;NA;1.00;4.00;0.81;NA COSER_TEST;2011;TRAIT1;COSER_SPECIES2;i;NA;27.61;3.00;NA -COSER_TEST;2011;TRAIT1;COSER_SPECIES3;i;NA;20.44;3.00;NA -COSER_TEST;2011;TRAIT1;COSER_SPECIES4;i;NA;6.86;1.00;NA -COSER_TEST;2011;TRAIT2;COSER_SPECIES1;i;NA;15.04;4.00;NA -COSER_TEST;2011;TRAIT2;COSER_SPECIES2;i;NA;35.03;1.00;NA -COSER_TEST;2011;TRAIT2;COSER_SPECIES3;i;NA;19.41;1.00;NA +COSER_TEST;2011;TRAIT1;COSER_SPECIES3;i;NA;20.44;3.00;0.43;NA +COSER_TEST;2011;TRAIT1;COSER_SPECIES4;i;NA;6.86;1.00;0.23;NA +COSER_TEST;2011;TRAIT2;COSER_SPECIES1;i;NA;15.04;4.00;0.95;NA +COSER_TEST;2011;TRAIT2;COSER_SPECIES2;i;NA;35.03;1.00;0.26;NA +COSER_TEST;2011;TRAIT2;COSER_SPECIES3;i;NA;19.41;1.00;0.51;NA COSER_TEST;2011;TRAIT2;COSER_SPECIES4;i;NA;24.58;2.00;NA -COSER_TEST;2011;TRAIT3;COSER_SPECIES1;i;NA;2.46;4.00;NA -COSER_TEST;2011;TRAIT3;COSER_SPECIES2;i;NA;18.93;5.00;NA -COSER_TEST;2011;TRAIT3;COSER_SPECIES3;i;NA;23.77;5.00;NA -COSER_TEST;2011;TRAIT3;COSER_SPECIES4;i;NA;0.94;3.00;NA +COSER_TEST;2011;TRAIT3;COSER_SPECIES1;i;NA;2.46;3.00;0.32;NA +COSER_TEST;2011;TRAIT3;COSER_SPECIES2;i;NA;18.93;5.00;0.22;NA +COSER_TEST;2011;TRAIT3;COSER_SPECIES3;i;NA;23.77;5.00;0.12;NA +COSER_TEST;2011;TRAIT3;COSER_SPECIES4;i;NA;0.94;3.00;0.77;NA