Author: tchemit Date: 2014-01-20 21:41:49 +0100 (Mon, 20 Jan 2014) New Revision: 1516 Url: http://forge.codelutin.com/projects/tutti/repository/revisions/1516 Log: refs #3876: Import de donn?\195?\169es depuis un ictyom?\195?\168tre (par lot) Added: trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/psionimport/ trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/psionimport/PsionImportBatchModel.java trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/psionimport/PsionImportModel.java trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/psionimport/PsionImportResult.java trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/psionimport/PsionImportService.java trunk/tutti-service/src/test/java/fr/ifremer/tutti/service/psionimport/ trunk/tutti-service/src/test/java/fr/ifremer/tutti/service/psionimport/PsionImportServiceTest.java trunk/tutti-service/src/test/resources/psion/ trunk/tutti-service/src/test/resources/psion/CC053.IWA trunk/tutti-service/src/test/resources/psion/CFchephren 110612.IWA trunk/tutti-service/src/test/resources/psion/FM001.IWA Added: trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/psionimport/PsionImportBatchModel.java =================================================================== --- trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/psionimport/PsionImportBatchModel.java (rev 0) +++ trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/psionimport/PsionImportBatchModel.java 2014-01-20 20:41:49 UTC (rev 1516) @@ -0,0 +1,119 @@ +package fr.ifremer.tutti.service.psionimport; + +/* + * #%L + * Tutti :: Service + * $Id$ + * $HeadURL:$ + * %% + * Copyright (C) 2012 - 2014 Ifremer + * %% + * 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.google.common.collect.Maps; +import fr.ifremer.tutti.persistence.entities.referential.Species; +import org.apache.commons.lang3.mutable.MutableInt; + +import java.io.Serializable; +import java.util.Map; + +/** + * Created on 1/20/14. + * + * @author Tony Chemit <chemit@codelutin.com> + * @since 3.0.1 + */ +public class PsionImportBatchModel { + + protected final Species species; + + protected final Integer lengthStepCaracteristicId; + + protected Float weight; + + protected Float sampleWeight; + + protected Integer categoryId; + + protected Serializable categoryValue; + + protected final Map<Float, MutableInt> frequencies; + + public PsionImportBatchModel(Species species, Integer lengthStepCaracteristicId) { + this.species = species; + this.lengthStepCaracteristicId = lengthStepCaracteristicId; + frequencies = Maps.newTreeMap(); + } + + public void setWeight(Float weight) { + this.weight = weight; + } + + public void setSampleWeight(Float sampleWeight) { + this.sampleWeight = sampleWeight; + } + + public void setCategory(Integer categoryId, Serializable categoryValue) { + this.categoryId = categoryId; + this.categoryValue = categoryValue; + } + + public void addFrequency(Float size) { + MutableInt mutableFloat = frequencies.get(size); + if (mutableFloat == null) { + mutableFloat = new MutableInt(0); + frequencies.put(size, mutableFloat); + } + mutableFloat.increment(); + } + + public Species getSpecies() { + return species; + } + + public Integer getLengthStepCaracteristicId() { + return lengthStepCaracteristicId; + } + + public Float getWeight() { + return weight; + } + + public Float getSampleWeight() { + return sampleWeight; + } + + public Integer getCategoryId() { + return categoryId; + } + + public Serializable getCategoryValue() { + return categoryValue; + } + + public boolean withFrequencies() { + return !frequencies.isEmpty(); + } + + public Map<Float, MutableInt> getFrequencies() { + return frequencies; + } + + public int getNbFrequencies() { + return frequencies.size(); + } +} Property changes on: trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/psionimport/PsionImportBatchModel.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/psionimport/PsionImportModel.java =================================================================== --- trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/psionimport/PsionImportModel.java (rev 0) +++ trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/psionimport/PsionImportModel.java 2014-01-20 20:41:49 UTC (rev 1516) @@ -0,0 +1,84 @@ +package fr.ifremer.tutti.service.psionimport; + +/* + * #%L + * Tutti :: Service + * $Id$ + * $HeadURL:$ + * %% + * Copyright (C) 2012 - 2014 Ifremer + * %% + * 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.google.common.collect.Lists; +import com.google.common.collect.Sets; +import fr.ifremer.tutti.persistence.entities.referential.Species; + +import java.util.List; +import java.util.Set; + +/** + * Created on 1/20/14. + * + * @author Tony Chemit <chemit@codelutin.com> + * @since 3.0.1 + */ +public class PsionImportModel { + + protected final List<PsionImportBatchModel> batchs; + + protected final Set<String> ignoredSpecies; + + public PsionImportModel() { + batchs = Lists.newArrayList(); + ignoredSpecies = Sets.newHashSet(); + } + + public void addBatch(PsionImportBatchModel batchModel) { + batchs.add(batchModel); + } + + public void addIgnoredSpecies(String species) { + ignoredSpecies.add(species); + } + + public boolean withBatchs() { + return !batchs.isEmpty(); + } + + public Set<String> getIgnoredSpecies() { + return ignoredSpecies; + } + + public Set<Species> getSpecies() { + Set<Species> result = Sets.newLinkedHashSet(); + for (PsionImportBatchModel batch : batchs) { + result.add(batch.getSpecies()); + } + return result; + } + + public List<PsionImportBatchModel> getBatchs(Species species) { + List<PsionImportBatchModel> result = Lists.newArrayList(); + for (PsionImportBatchModel batch : batchs) { + if (species.equals(batch.getSpecies())) { + result.add(batch); + } + } + return result; + } +} Property changes on: trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/psionimport/PsionImportModel.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/psionimport/PsionImportResult.java =================================================================== --- trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/psionimport/PsionImportResult.java (rev 0) +++ trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/psionimport/PsionImportResult.java 2014-01-20 20:41:49 UTC (rev 1516) @@ -0,0 +1,66 @@ +package fr.ifremer.tutti.service.psionimport; + +/* + * #%L + * Tutti :: Service + * $Id$ + * $HeadURL:$ + * %% + * Copyright (C) 2012 - 2014 Ifremer + * %% + * 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 java.io.File; + +/** + * Created on 1/20/14. + * + * @author Tony Chemit <chemit@codelutin.com> + * @since 3.0.1 + */ +public class PsionImportResult { + + protected final File importFile; + + protected int nbImported; + + protected int nbNotImported; + + public PsionImportResult(File importFile) { + this.importFile = importFile; + } + + public File getImportFile() { + return importFile; + } + + public int getNbImported() { + return nbImported; + } + + public int getNbNotImported() { + return nbNotImported; + } + + void incrementNbImported() { + this.nbImported++; + } + + void incrementNbNotImported() { + this.nbNotImported++; + } +} Property changes on: trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/psionimport/PsionImportResult.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/psionimport/PsionImportService.java =================================================================== --- trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/psionimport/PsionImportService.java (rev 0) +++ trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/psionimport/PsionImportService.java 2014-01-20 20:41:49 UTC (rev 1516) @@ -0,0 +1,599 @@ +package fr.ifremer.tutti.service.psionimport; + +/* + * #%L + * Tutti :: Service + * $Id$ + * $HeadURL:$ + * %% + * Copyright (C) 2012 - 2014 Ifremer + * %% + * 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.google.common.base.Charsets; +import com.google.common.base.Preconditions; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import com.google.common.io.Files; +import fr.ifremer.shared.application.ApplicationBusinessException; +import fr.ifremer.tutti.persistence.entities.TuttiEntities; +import fr.ifremer.tutti.persistence.entities.data.AttachementObjectTypeEnum; +import fr.ifremer.tutti.persistence.entities.data.Attachment; +import fr.ifremer.tutti.persistence.entities.data.Attachments; +import fr.ifremer.tutti.persistence.entities.data.BatchContainer; +import fr.ifremer.tutti.persistence.entities.data.CatchBatch; +import fr.ifremer.tutti.persistence.entities.data.FishingOperation; +import fr.ifremer.tutti.persistence.entities.data.SpeciesBatch; +import fr.ifremer.tutti.persistence.entities.data.SpeciesBatchFrequency; +import fr.ifremer.tutti.persistence.entities.data.SpeciesBatchFrequencys; +import fr.ifremer.tutti.persistence.entities.data.SpeciesBatchs; +import fr.ifremer.tutti.persistence.entities.protocol.SpeciesProtocol; +import fr.ifremer.tutti.persistence.entities.protocol.TuttiProtocol; +import fr.ifremer.tutti.persistence.entities.referential.Caracteristic; +import fr.ifremer.tutti.persistence.entities.referential.CaracteristicQualitativeValue; +import fr.ifremer.tutti.persistence.entities.referential.Species; +import fr.ifremer.tutti.persistence.service.TuttiEnumerationFile; +import fr.ifremer.tutti.service.AbstractTuttiService; +import fr.ifremer.tutti.service.PersistenceService; +import fr.ifremer.tutti.service.TuttiDataContext; +import fr.ifremer.tutti.service.TuttiServiceContext; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.mutable.MutableInt; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.Serializable; +import java.text.DateFormat; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static org.nuiton.i18n.I18n._; + +/** + * To import some psion files. + * <p/> + * Created on 1/20/14. + * + * @author Tony Chemit <chemit@codelutin.com> + * @since 3.0.1 + */ +public class PsionImportService extends AbstractTuttiService { + + private static final Log log = LogFactory.getLog(PsionImportService.class); + + protected static final Set<String> SEX_VALUES = Sets.newHashSet( + "N", "n", "I", "i", "F", "f", "M", "m" + ); + + protected static final Set<String> MATURITY_VALUES = Sets.newHashSet( + "1", "2", "3", "4", "5" + ); + + protected PersistenceService persistenceService; + + protected char csvSeparator; + + protected TuttiDataContext dataContext; + + protected CaracteristicQualitativeValue sortedCaracteristic; + + protected CaracteristicQualitativeValue unsortedCaracteristic; + + protected Map<String, Species> speciesBySurveyCode; + + protected Map<String, SpeciesProtocol> speciesProtocolBySurveyCode; + + protected Map<String, CaracteristicQualitativeValue> sexCaracteristicValues; + + protected Map<String, CaracteristicQualitativeValue> maturityCaracteristicValues; + + @Override + public void setServiceContext(TuttiServiceContext context) { + super.setServiceContext(context); + persistenceService = getService(PersistenceService.class); + + csvSeparator = ';'; + dataContext = context.getDataContext(); + + + TuttiEnumerationFile enumerationFile = persistenceService.getEnumerationFile(); + + { // sorted/unsorted caracteristic + Caracteristic caracteristic = + persistenceService.getSortedUnsortedCaracteristic(); + + sortedCaracteristic = TuttiEntities.getQualitativeValue(caracteristic, enumerationFile.QUALITATIVE_VRAC_ID); + unsortedCaracteristic = TuttiEntities.getQualitativeValue(caracteristic, enumerationFile.QUALITATIVE_HORS_VRAC_ID); + } + + { // sex caracteristic + + sexCaracteristicValues = Maps.newTreeMap(); + + Caracteristic caracteristic = persistenceService.getSexCaracteristic(); + + List<CaracteristicQualitativeValue> qualitativeValues = caracteristic.getQualitativeValue(); + + Map<Integer, CaracteristicQualitativeValue> sexById = TuttiEntities.splitByIdAsInt(qualitativeValues); + CaracteristicQualitativeValue femaleCaracteristic = sexById.get(enumerationFile.QUALITATIVE_SEX_FEMALE_ID); + sexCaracteristicValues.put("F", femaleCaracteristic); + sexCaracteristicValues.put("f", femaleCaracteristic); + CaracteristicQualitativeValue maleCaracteristic = sexById.get(enumerationFile.QUALITATIVE_SEX_MALE_ID); + sexCaracteristicValues.put("M", maleCaracteristic); + sexCaracteristicValues.put("m", maleCaracteristic); + CaracteristicQualitativeValue unkownCaracteristic = sexById.get(enumerationFile.QUALITATIVE_SEX_UNDEFINED_ID); + sexCaracteristicValues.put("I", unkownCaracteristic); + sexCaracteristicValues.put("i", unkownCaracteristic); + } + + { // maturity caracteristic + + maturityCaracteristicValues = Maps.newTreeMap(); + + Caracteristic caracteristic = persistenceService.getMaturityCaracteristic(); + + List<CaracteristicQualitativeValue> qualitativeValues = caracteristic.getQualitativeValue(); + + Map<Integer, CaracteristicQualitativeValue> byIds = TuttiEntities.splitByIdAsInt(qualitativeValues); + maturityCaracteristicValues.put("1", byIds.get(enumerationFile.QUALITATIVE_MATURITY_1_ID)); + maturityCaracteristicValues.put("2", byIds.get(enumerationFile.QUALITATIVE_MATURITY_2_ID)); + maturityCaracteristicValues.put("3", byIds.get(enumerationFile.QUALITATIVE_MATURITY_3_ID)); + maturityCaracteristicValues.put("4", byIds.get(enumerationFile.QUALITATIVE_MATURITY_4_ID)); + maturityCaracteristicValues.put("5", byIds.get(enumerationFile.QUALITATIVE_MATURITY_5_ID)); + } + + List<Species> allReferentSpecies = persistenceService.getReferentSpeciesWithSurveyCode( + persistenceService.getAllReferentSpecies()); + + speciesBySurveyCode = Maps.newTreeMap(); + for (Species species : allReferentSpecies) { + if (species.getSurveyCode() != null) { + speciesBySurveyCode.put(species.getSurveyCode(), species); + } + } + + speciesProtocolBySurveyCode = Maps.newTreeMap(); + + TuttiProtocol protocol = dataContext.getProtocol(); + + if (protocol == null) { + // not possible + //FIXME Deal with error + throw new IllegalStateException("Can't open psionImportService without a protocol"); + } + + List<SpeciesProtocol> speciesProtocols = protocol.getSpecies(); + for (SpeciesProtocol speciesProtocol : speciesProtocols) { + if (speciesProtocol.getSpeciesSurveyCode() == null) { + continue; + } + + speciesProtocolBySurveyCode.put(speciesProtocol.getSpeciesSurveyCode(), speciesProtocol); + } + } + + public PsionImportResult importFile(File psionFile, FishingOperation operation, CatchBatch catchBatch) { + + Preconditions.checkNotNull(psionFile); + Preconditions.checkArgument(psionFile.exists(), "Psion file " + psionFile + " does not exist."); + + // load model + PsionImportModel importModel; + try { + importModel = readImportFile(psionFile); + } catch (IOException e) { + throw new ApplicationBusinessException(e.getMessage(), e.getCause()); + } + + // import in database + PsionImportResult result = persist(psionFile, importModel, operation, catchBatch); + + return result; + } + + protected PsionImportModel readImportFile(File arpFile) throws IOException { + + TuttiEnumerationFile enumerationFile = persistenceService.getEnumerationFile(); + + PsionImportModel importModel = new PsionImportModel(); + + BufferedReader reader = Files.newReader(arpFile, Charsets.UTF_8); + + try { + PsionImportBatchModel batch = null; + + // first line, don't care + String line; + + line = reader.readLine(); // initiales saisisseurs + line = reader.readLine(); // Id du trait + line = reader.readLine(); // Date du trait + line = reader.readLine(); // Heure de création du fichier + line = reader.readLine(); // Ligne blanche + + int lineNumber = 6; + + String badSpecies = null; + while ((line = reader.readLine()) != null) { + lineNumber++; + if (!line.contains(":")) { + throw new IOException( + "Format de la ligne (" + + lineNumber + ") incorrecte : " + line); + } + int endIndex = line.indexOf(':'); + String commandStr = StringUtils.trim(line.substring(0, endIndex)); + + + PsionImportKeyword command; + + try { + command = PsionImportKeyword.valueOf(commandStr); + } catch (IllegalArgumentException e) { + throw new IOException( + "La commande " + commandStr + " n'est pas connue ligne (" + + lineNumber + ") "); + } + + if (command.isIgnored()) { + if (log.isWarnEnabled()) { + log.warn("Ignoring command: " + command); + } + continue; + } + + String value = StringUtils.trim(line.substring(endIndex + 1)); + + if (PsionImportKeyword.ESPE.equals(command)) { + + // start a new species + + // register previous batch + if (batch != null) { + addBatchToModel(importModel, batch); + } + + Species species = speciesBySurveyCode.get(value); + + if (species == null) { + + // could not load this species + if (log.isWarnEnabled()) { + log.warn("Ligne " + lineNumber + " espèce " + value + " inconnue."); + } + badSpecies = value; + importModel.addIgnoredSpecies(badSpecies); + continue; + } + + badSpecies = null; + + SpeciesProtocol speciesProtocol = speciesProtocolBySurveyCode.get(value); + + String lengthStepCaracteristicId = speciesProtocol.getLengthStepPmfmId(); + + if (StringUtils.isBlank(lengthStepCaracteristicId)) { + if (log.isWarnEnabled()) { + log.warn("Ligne " + lineNumber + " espèce " + value + " ignorée car pas de caractéristique de classe de taille renseignée dans le protocole."); + } + badSpecies = value; + importModel.addIgnoredSpecies(badSpecies); + continue; + } + batch = new PsionImportBatchModel(species, Integer.valueOf(lengthStepCaracteristicId)); + } else { + + if (badSpecies != null) { + // ignore this line due to bad species + if (log.isDebugEnabled()) { + log.debug("Ligne " + lineNumber + + " ignorée car l'espèce " + badSpecies + " n'était pas reconnue"); + } + continue; + } + + // check batch exists + if (batch == null) { + throw new IOException( + "La ligne " + line + " (" + lineNumber + + ") n'est pas valide, elle doit être précédée par une ligne ESPE"); + } + + switch (command) { + + case POID: + // add weight + Float weight = toFloat(value, lineNumber); + batch.setWeight(weight); + break; + + case TAIL: + // add sample weight + Float sampleWeight = toFloat(value, lineNumber); + batch.setSampleWeight(sampleWeight); + break; + + case CATE: + // add category + + Integer caracteristicId; + CaracteristicQualitativeValue caracteristicQualitativeValue; + + if (SEX_VALUES.contains(value)) { + + // sex caracteristic + caracteristicId = enumerationFile.PMFM_ID_SEX; + + caracteristicQualitativeValue = sexCaracteristicValues.get(value); + + if (caracteristicQualitativeValue == null) { + + //means non sexé + caracteristicId = null; + } + + } else if (MATURITY_VALUES.contains(value)) { + + // maturity caracteristic + caracteristicId = enumerationFile.PMFM_ID_MATURITY; + caracteristicQualitativeValue = maturityCaracteristicValues.get(value); + + } else { + + if (log.isWarnEnabled()) { + log.warn("Ligne " + lineNumber + ", catégorisation '" + value + "' inconnue, espèce " + batch.getSpecies().getSurveyCode() + " ignorée"); + } + + badSpecies = batch.getSpecies().getSurveyCode(); + importModel.addIgnoredSpecies(badSpecies); + batch = null; + continue; +// throw new IOException( +// "Ligne " + lineNumber + ", catégorisation '" + value + "' inconnue"); + } + + batch.setCategory(caracteristicId, caracteristicQualitativeValue); + break; + + case LONG: + // add frequency + Float size = toFloat(value, lineNumber); + batch.addFrequency(size); + break; + + case OUTI: + // ignore it + break; + } + } + } + + if (batch != null) { + + // save it + addBatchToModel(importModel, batch); + } + + reader.close(); + return importModel; + } finally { + IOUtils.closeQuietly(reader); + } + } + + protected PsionImportResult persist(File arpFile, + PsionImportModel importModel, + FishingOperation operation, + CatchBatch catchBatch) { + PsionImportResult result = new PsionImportResult(arpFile); + + if (catchBatch != null) { + addFileAsAttachment(arpFile, catchBatch); + } + + // delete all species batches + BatchContainer<SpeciesBatch> rootSpeciesBatch = persistenceService.getRootSpeciesBatch(operation.getId(), null); + for (SpeciesBatch batch : rootSpeciesBatch.getChildren()) { + persistenceService.deleteSpeciesBatch(batch.getId()); + } + + // insert all imported species batches + + TuttiEnumerationFile enumerationFile = persistenceService.getEnumerationFile(); + + Set<Species> species = importModel.getSpecies(); + + for (Species specy : species) { + + //FIXME Make sure this does work well with a none sex batch... + List<PsionImportBatchModel> batchs = importModel.getBatchs(specy); + + if (batchs.size() == 1 && batchs.get(0).getCategoryId() == null) { + + PsionImportBatchModel batchModel = batchs.get(0); + + // simple batch with no category + SpeciesBatch batch = createSpeciesBatch(operation, + batchModel.getSpecies(), + batchModel.getWeight(), + enumerationFile.PMFM_ID_SORTED_UNSORTED, + sortedCaracteristic); + //FIXME Check this is ok. + batch.setWeight(batchModel.getSampleWeight()); + + batch = persistenceService.createSpeciesBatch(batch, null); + + persistFrequencies(batch, batchModel); + + } else { + + // batch with categories + + SpeciesBatch batch = createSpeciesBatch(operation, + specy, + null, + enumerationFile.PMFM_ID_SORTED_UNSORTED, + sortedCaracteristic); + + batch = persistenceService.createSpeciesBatch(batch, null); + + for (PsionImportBatchModel batchModel : batchs) { + + SpeciesBatch childBatch = createSpeciesBatch(operation, + batchModel.getSpecies(), + batchModel.getWeight(), + batchModel.getCategoryId(), + batchModel.getCategoryValue()); + //FIXME Check this is ok. + childBatch.setWeight(batchModel.getSampleWeight()); + + childBatch = persistenceService.createSpeciesBatch(childBatch, batch.getId()); + + persistFrequencies(childBatch, batchModel); + } + } + result.incrementNbImported(); + } + + for (String ignoredSpecies : importModel.getIgnoredSpecies()) { + result.incrementNbNotImported(); + } + persistenceService.saveCatchBatch(catchBatch); + + return result; + } + + protected void persistFrequencies(SpeciesBatch batch, PsionImportBatchModel batchModel) { + + Integer lengthStepCaracteristicId = batchModel.getLengthStepCaracteristicId(); + Map<Float, MutableInt> frequencies = batchModel.getFrequencies(); + List<SpeciesBatchFrequency> toSave = Lists.newArrayList(); + + Caracteristic lengthStepCaracteristic = persistenceService.getCaracteristic(lengthStepCaracteristicId); + + for (Map.Entry<Float, MutableInt> entry : frequencies.entrySet()) { + Float size = entry.getKey(); + MutableInt number = entry.getValue(); + + SpeciesBatchFrequency batchFrequency = SpeciesBatchFrequencys.newSpeciesBatchFrequency(); + batchFrequency.setBatch(batch); + batchFrequency.setLengthStepCaracteristic(lengthStepCaracteristic); + batchFrequency.setLengthStep(size); + batchFrequency.setNumber(number.getValue()); + toSave.add(batchFrequency); + } + + persistenceService.saveSpeciesBatchFrequency(batch.getId(), toSave); + } + + protected void addBatchToModel(PsionImportModel importModel, + PsionImportBatchModel batch) throws IOException { + + if (log.isInfoEnabled()) { + log.info("Adding for species " + batch.getSpecies().getSurveyCode() + ", " + + batch.getNbFrequencies() + " batchs."); + } + importModel.addBatch(batch); + } + + protected SpeciesBatch createSpeciesBatch(FishingOperation operation, + Species species, + Float catchWeight, + Integer categoryId, + Serializable cqv) { + SpeciesBatch batch = SpeciesBatchs.newSpeciesBatch(); + batch.setFishingOperation(operation); + batch.setSampleCategoryId(categoryId); + batch.setSampleCategoryValue(cqv); + batch.setSpecies(species); + batch.setSampleCategoryWeight( + catchWeight == null ? null : TuttiEntities.roundKiloGram(catchWeight)); + return batch; + } + + protected void addFileAsAttachment(File f, CatchBatch catchBatch) { + Attachment attachment = Attachments.newAttachment(); + attachment.setObjectType(AttachementObjectTypeEnum.CATCH_BATCH); + attachment.setObjectId(Integer.valueOf(catchBatch.getId())); + attachment.setName(f.getName()); + String date = DateFormat.getDateTimeInstance().format(context.currentDate()); + String comment = _("tutti.service.arp.import.attachment.comment", date); + attachment.setComment(comment); + persistenceService.createAttachment(attachment, f); + } + + protected Float toFloat(String cell, int lineNumber) throws IOException { + Float result = null; + if (!cell.isEmpty()) { + try { + result = Float.valueOf(cell); + } catch (NumberFormatException e) { + throw new IOException("Format de la valeur [" + lineNumber + "] : " + cell + + " incorrect, devrait être un entier décimal"); + } + } + if (result == null) { + throw new IOException("La valeur [" + lineNumber + "] est obligatoire mais n'est pas renseignée"); + } + return result; + } + + /** + * All usables keywords in a psion import. + * <p/> + * Created on 1/20/14. + * + * @author Tony Chemit <chemit@codelutin.com> + * @since 3.0.1 + */ + public static enum PsionImportKeyword { + + ESPE(false), + POID(false), + TAIL(false), + CATE(false), + LONG(false), + + // ignored + HEUR(true), + AGEN(true), + CAIS(true), + TAXO(true), + OUTI(true), + PORT(true), + DATE(true), + HERE(true), + NAVI(true), + ENGI(true); + + private final boolean ignored; + + PsionImportKeyword(boolean ignored) { + this.ignored = ignored; + } + + public boolean isIgnored() { + return ignored; + } + } +} Property changes on: trunk/tutti-service/src/main/java/fr/ifremer/tutti/service/psionimport/PsionImportService.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/tutti-service/src/test/java/fr/ifremer/tutti/service/psionimport/PsionImportServiceTest.java =================================================================== --- trunk/tutti-service/src/test/java/fr/ifremer/tutti/service/psionimport/PsionImportServiceTest.java (rev 0) +++ trunk/tutti-service/src/test/java/fr/ifremer/tutti/service/psionimport/PsionImportServiceTest.java 2014-01-20 20:41:49 UTC (rev 1516) @@ -0,0 +1,188 @@ +package fr.ifremer.tutti.service.psionimport; + +/* + * #%L + * Tutti :: Service + * $Id$ + * $HeadURL:$ + * %% + * Copyright (C) 2012 - 2014 Ifremer + * %% + * 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 fr.ifremer.tutti.TuttiConfigurationOption; +import fr.ifremer.tutti.persistence.ProgressionModel; +import fr.ifremer.tutti.persistence.entities.data.BatchContainer; +import fr.ifremer.tutti.persistence.entities.data.CatchBatch; +import fr.ifremer.tutti.persistence.entities.data.FishingOperation; +import fr.ifremer.tutti.persistence.entities.data.SpeciesBatch; +import fr.ifremer.tutti.service.PersistenceService; +import fr.ifremer.tutti.service.ServiceDbResource; +import fr.ifremer.tutti.service.TuttiServiceContext; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.junit.Assert; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Test; + +import java.io.File; +import java.io.IOException; + +/** + * Created on 1/19/14. + * + * @author Tony Chemit <chemit@codelutin.com> + * @since 3.1 + */ +public class PsionImportServiceTest { + + @ClassRule + public static final ServiceDbResource dbResource = + ServiceDbResource.writeDb("dbExport"); + + /** Logger. */ + private static final Log log = LogFactory.getLog(PsionImportServiceTest.class); + + public static final String PROGRAM_ID = "CAM-TEST_ELEVATION"; + + public static final String CRUISE_ID = "100003"; + + public static final String OPERATION_1_ID = "100112"; + + public static final String OPERATION_2_ID = "100113"; + + public static final String OPERATION_3_ID = "100115"; + + protected PsionImportService service; + + protected PersistenceService persistenceService; + + protected ServiceDbResource.DataContext dataContext; + + protected ProgressionModel progressionModel; + + protected File dataDirectory; + + @Before + public void setUp() throws Exception { + + dataDirectory = dbResource.getConfig().getDataDirectory(); + + TuttiServiceContext serviceContext = dbResource.getServiceContext(); + + File protocol = dbResource.copyClassPathResource("pupitri/ano-3898.tuttiProtocol", "ano-3898.tuttiProtocol"); + dbResource.getConfig().getApplicationConfig().setOption(TuttiConfigurationOption.DB_PROTOCOL_DIRECTORY.getKey(), protocol.getParentFile().getAbsolutePath()); + serviceContext.getDataContext().setProtocolId("ano-3898"); + + dbResource.openDataContext(); + + persistenceService = serviceContext.getService(PersistenceService.class); + service = serviceContext.getService(PsionImportService.class); + + progressionModel = new ProgressionModel(); + progressionModel.setTotal(9); + + dataContext = dbResource.loadContext(PROGRAM_ID, CRUISE_ID, 3, OPERATION_2_ID, OPERATION_1_ID, OPERATION_3_ID); + } + + @Test + public void importCC053() throws IOException { + + File trunk = dbResource.copyClassPathResource("psion/CC053.IWA", "CC053.IWA"); + + FishingOperation operation = dataContext.operations.get(1); + CatchBatch catchBatch = persistenceService.getCatchBatchFromFishingOperation(operation.getId()); + catchBatch.setFishingOperation(operation); + + BatchContainer<SpeciesBatch> rootSpeciesBatch = persistenceService.getRootSpeciesBatch(operation.getId(), null); +// Assert.assertEquals(3, rootSpeciesBatch.sizeChildren()); + PsionImportResult arpImportResult = service.importFile(trunk, operation, catchBatch); + + PsionImportResult importResult = service.importFile(trunk, operation, catchBatch); + + int nbAdded = importResult.getNbImported(); + int nbNotAdded = importResult.getNbNotImported(); + + if (log.isInfoEnabled()) { + log.info("Imported: " + nbAdded); + log.info("Ignored: " + nbNotAdded); + } + + Assert.assertEquals(9, nbAdded); + Assert.assertEquals(9, nbNotAdded); + + BatchContainer<SpeciesBatch> rootSpeciesBatchAfter = persistenceService.getRootSpeciesBatch(operation.getId(), null); + Assert.assertEquals(9, rootSpeciesBatchAfter.sizeChildren()); + } + + @Test + public void importFM001() throws IOException { + + File trunk = dbResource.copyClassPathResource("psion/FM001.IWA", "FM001.IWA"); + + FishingOperation operation = dataContext.operations.get(1); + CatchBatch catchBatch = persistenceService.getCatchBatchFromFishingOperation(operation.getId()); + catchBatch.setFishingOperation(operation); + + BatchContainer<SpeciesBatch> rootSpeciesBatch = persistenceService.getRootSpeciesBatch(operation.getId(), null); +// Assert.assertEquals(3, rootSpeciesBatch.sizeChildren()); + PsionImportResult importResult = service.importFile(trunk, operation, catchBatch); + + int nbAdded = importResult.getNbImported(); + int nbNotAdded = importResult.getNbNotImported(); + + if (log.isInfoEnabled()) { + log.info("Imported: " + nbAdded); + log.info("Ignored: " + nbNotAdded); + } + + Assert.assertEquals(2, nbAdded); + Assert.assertEquals(8, nbNotAdded); + + BatchContainer<SpeciesBatch> rootSpeciesBatchAfter = persistenceService.getRootSpeciesBatch(operation.getId(), null); + Assert.assertEquals(2, rootSpeciesBatchAfter.sizeChildren()); + } + + @Test + public void importCFchephren() throws IOException { + + File trunk = dbResource.copyClassPathResource("psion/CFchephren 110612.IWA", "CFchephren 110612.IWA"); + + FishingOperation operation = dataContext.operations.get(1); + CatchBatch catchBatch = persistenceService.getCatchBatchFromFishingOperation(operation.getId()); + catchBatch.setFishingOperation(operation); + + BatchContainer<SpeciesBatch> rootSpeciesBatch = persistenceService.getRootSpeciesBatch(operation.getId(), null); +// Assert.assertEquals(3, rootSpeciesBatch.sizeChildren()); + PsionImportResult importResult = service.importFile(trunk, operation, catchBatch); + + int nbAdded = importResult.getNbImported(); + int nbNotAdded = importResult.getNbNotImported(); + + if (log.isInfoEnabled()) { + log.info("Imported: " + nbAdded); + log.info("Ignored: " + nbNotAdded); + } + + Assert.assertEquals(0, nbAdded); + Assert.assertEquals(1, nbNotAdded); + + BatchContainer<SpeciesBatch> rootSpeciesBatchAfter = persistenceService.getRootSpeciesBatch(operation.getId(), null); + Assert.assertEquals(0, rootSpeciesBatchAfter.sizeChildren()); + } +} Property changes on: trunk/tutti-service/src/test/java/fr/ifremer/tutti/service/psionimport/PsionImportServiceTest.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/tutti-service/src/test/resources/psion/CC053.IWA =================================================================== --- trunk/tutti-service/src/test/resources/psion/CC053.IWA (rev 0) +++ trunk/tutti-service/src/test/resources/psion/CC053.IWA 2014-01-20 20:41:49 UTC (rev 1516) @@ -0,0 +1,590 @@ +cc +053 +06-13-2013 +07:19:11 + +ESPE : MERLMER +POID : 50 +TAIL : 50 +CATE : I +LONG : 12.5 +LONG : 15 +ESPE : SPICMAE +POID : 20 +TAIL : 20 +CATE : N +LONG : 12 +ESPE : TRIPLAS +POID : 40 +TAIL : 40 +CATE : N +LONG : 15 +ESPE : PAGEERY +POID : 760 +TAIL : 760 +CATE : N +LONG : 16.5 +LONG : 20 +LONG : 20 +LONG : 18.5 +LONG : 17.5 +LONG : 18.5 +LONG : 17.5 +LONG : 19 +LONG : 18.5 +ESPE : ELEDMOS +POID : 230 +TAIL : 230 +CATE : N +LONG : 5 +LONG : 6 +LONG : 5 +ESPE : SOLEVUL +POID : 1350 +TAIL : 1350 +CATE : N +LONG : 34.5 +LONG : 27.5 +LONG : 31 +LONG : 23 +LONG : 21.5 +LONG : 34.5 +ESPE : ELEDCIR +POID : 4650 +TAIL : 1820 +CATE : N +LONG : 6.5 +LONG : 5.5 +LONG : 5.5 +LONG : 5 +LONG : 5 +LONG : 5 +LONG : 5 +LONG : 5 +LONG : 5.5 +LONG : 5 +LONG : 5 +LONG : 5.5 +LONG : 5.5 +LONG : 5.5 +LONG : 5 +LONG : 5 +LONG : 5 +LONG : 4 +LONG : 4 +LONG : 4 +LONG : 4.5 +LONG : 4.5 +LONG : 4.5 +LONG : 4.5 +LONG : 4.5 +LONG : 4.5 +LONG : 4.5 +LONG : 4.5 +LONG : 4.5 +LONG : 4.5 +LONG : 4.5 +LONG : 4.5 +ESPE : SPICMAE +POID : 864 +TAIL : 300 +CATE : N +LONG : 11.5 +LONG : 13.5 +LONG : 14 +LONG : 14.5 +LONG : 17 +LONG : 15.5 +LONG : 12.5 +LONG : 14 +LONG : 14 +LONG : 13.5 +ESPE : EUTRGUR +POID : 3788 +TAIL : 1315 +CATE : N +LONG : 20 +LONG : 16 +LONG : 15 +LONG : 17.5 +LONG : 15.5 +LONG : 18.5 +LONG : 15 +LONG : 16 +LONG : 14.5 +LONG : 13.5 +LONG : 17.5 +LONG : 16 +LONG : 16.5 +LONG : 19 +LONG : 15.5 +LONG : 16 +LONG : 16 +LONG : 16 +LONG : 17 +LONG : 17 +LONG : 19 +LONG : 13.5 +LONG : 19 +LONG : 18 +LONG : 23.5 +LONG : 16.5 +LONG : 16.5 +LONG : 16.5 +LONG : 15 +LONG : 15.5 +LONG : 14.5 +LONG : 16.5 +LONG : 19 +LONG : 18 +LONG : 13.5 +ESPE : TRISCAP +POID : 7777 +TAIL : 1545 +CATE : N +LONG : 16 +LONG : 20 +LONG : 17 +LONG : 20 +LONG : 18.5 +LONG : 18.5 +LONG : 19.5 +LONG : 18 +LONG : 16.5 +LONG : 18.5 +LONG : 17.5 +LONG : 20.5 +LONG : 16.5 +LONG : 16.5 +LONG : 17 +LONG : 18.5 +LONG : 16 +LONG : 17.5 +LONG : 17 +LONG : 18.5 +LONG : 15.5 +LONG : 16 +LONG : 16.5 +LONG : 16.5 +LONG : 16.5 +ESPE : TRACMED +POID : 10700 +TAIL : 3715 +CATE : N +LONG : 21 +LONG : 18.5 +LONG : 22 +LONG : 21.5 +LONG : 24.5 +LONG : 18.5 +LONG : 18 +LONG : 13 +LONG : 21 +LONG : 21 +LONG : 20 +LONG : 13.5 +LONG : 21.5 +LONG : 16 +LONG : 23 +LONG : 22 +LONG : 22 +LONG : 17 +LONG : 19.5 +LONG : 20 +LONG : 23.5 +LONG : 19.5 +LONG : 12.5 +LONG : 19.5 +LONG : 14 +LONG : 19 +LONG : 20 +LONG : 18 +LONG : 23 +LONG : 18.5 +LONG : 10.5 +LONG : 10 +LONG : 15.5 +LONG : 19 +LONG : 16 +LONG : 16 +LONG : 19.5 +LONG : 20.5 +LONG : 26 +LONG : 12 +LONG : 20.5 +LONG : 22.5 +LONG : 19.5 +LONG : 21 +LONG : 24 +LONG : 25.5 +LONG : 17.5 +LONG : 19 +LONG : 17 +LONG : 20 +LONG : 17.5 +LONG : 16 +LONG : 20 +LONG : 15.5 +LONG : 14 +LONG : 12 +LONG : 17 +LONG : 13 +LONG : 9 +LONG : 10.5 +LONG : 9 +LONG : 9.5 +LONG : 14 +LONG : 12 +ESPE : PAGEACA +POID : 6600 +TAIL : 3220 +CATE : N +LONG : 17.5 +LONG : 17.5 +LONG : 17.5 +LONG : 16.5 +LONG : 17.5 +LONG : 16 +LONG : 17.5 +LONG : 16.5 +LONG : 18 +LONG : 18 +LONG : 21.5 +LONG : 17 +LONG : 18 +LONG : 17.5 +LONG : 17.5 +LONG : 18 +LONG : 17 +LONG : 18 +LONG : 18 +LONG : 17.5 +LONG : 17 +LONG : 17 +LONG : 17 +LONG : 19 +LONG : 17.5 +LONG : 22 +LONG : 17 +LONG : 17 +LONG : 18.5 +LONG : 17.5 +LONG : 18 +LONG : 16.5 +LONG : 17.5 +LONG : 17 +LONG : 17.5 +LONG : 17.5 +LONG : 17.5 +LONG : 16 +LONG : 16 +LONG : 17.5 +LONG : 16 +LONG : 17.5 +LONG : 17.5 +ESPE : BOOPBOO +POID : 45943 +TAIL : 2230 +CATE : N +LONG : 21 +LONG : 17 +LONG : 17 +LONG : 16 +LONG : 16.5 +LONG : 17 +LONG : 20 +LONG : 17.5 +LONG : 17 +LONG : 16 +LONG : 16.5 +LONG : 16.5 +LONG : 18.5 +LONG : 15.5 +LONG : 16.5 +LONG : 16.5 +LONG : 17 +LONG : 16.5 +LONG : 16.5 +LONG : 16.5 +LONG : 17.5 +LONG : 18 +LONG : 20 +LONG : 16.5 +LONG : 17 +LONG : 16.5 +LONG : 16.5 +LONG : 17 +LONG : 16 +LONG : 21.5 +LONG : 19 +LONG : 17 +LONG : 16 +LONG : 18 +LONG : 15 +LONG : 16.5 +LONG : 17 +LONG : 13.5 +LONG : 15 +ESPE : MERLMER +POID : 395 +TAIL : 395 +CATE : F +LONG : 34.5 +ESPE : LOPHPIS +POID : 1175 +TAIL : 1175 +CATE : F +LONG : 32 +LONG : 28.5 +LONG : 27.5 +ESPE : MERLMER +POID : 317 +TAIL : 110 +CATE : I +LONG : 15.5 +LONG : 15 +LONG : 15 +LONG : 14 +LONG : 11.5 +ESPE : SQUIMAN +POID : 37 +TAIL : 37 +CATE : N +LONG : 27 +ESPE : OCTOVUL +POID : 11600 +TAIL : 11600 +CATE : N +LONG : 11 +LONG : 14 +LONG : 13 +LONG : 13 +LONG : 6.5 +LONG : 10 +LONG : 7.5 +LONG : 6.5 +ESPE : DIPLVUL +POID : 2250 +TAIL : 2250 +CATE : N +LONG : 20.5 +LONG : 20.5 +LONG : 18.5 +LONG : 15.5 +LONG : 19.5 +LONG : 20.5 +LONG : 21 +LONG : 22 +LONG : 18 +LONG : 18 +LONG : 18.5 +LONG : 19.5 +LONG : 24 +LONG : 20 +LONG : 20 +LONG : 19.5 +LONG : 18 +LONG : 19.5 +ESPE : TRISCAP +POID : 3341 +TAIL : 210 +CATE : N +LONG : 9.5 +LONG : 10.5 +LONG : 8.5 +LONG : 8 +LONG : 9 +LONG : 8 +LONG : 8 +LONG : 8 +LONG : 8 +LONG : 8 +LONG : 11 +LONG : 10.5 +LONG : 10 +LONG : 10 +LONG : 8.5 +LONG : 8.5 +LONG : 8.5 +LONG : 9 +LONG : 9 +LONG : 8 +LONG : 9.5 +LONG : 9 +LONG : 7.5 +LONG : 8 +LONG : 8 +LONG : 8.5 +LONG : 8.5 +LONG : 8.5 +LONG : 8.5 +LONG : 8.5 +ESPE : TRACTRA +POID : 1267 +TAIL : 440 +CATE : N +LONG : 20 +LONG : 8 +LONG : 8 +LONG : 8.5 +LONG : 7.5 +LONG : 6.5 +LONG : 9 +LONG : 9 +LONG : 8.5 +LONG : 16 +LONG : 9 +LONG : 14 +LONG : 17.5 +LONG : 18 +LONG : 15.5 +LONG : 9 +LONG : 10.5 +LONG : 8 +LONG : 11 +LONG : 8 +LONG : 8 +LONG : 8.5 +LONG : 8.5 +LONG : 9 +LONG : 9 +LONG : 8 +LONG : 7 +LONG : 8 +LONG : 8.5 +LONG : 8 +LONG : 8.5 +LONG : 7.5 +LONG : 7.5 +LONG : 8 +LONG : 7.5 +ESPE : MULLBAR +POID : 3629 +TAIL : 1260 +CATE : M +LONG : 12 +LONG : 11.5 +LONG : 11 +LONG : 11.5 +LONG : 11.5 +LONG : 10.5 +LONG : 10.5 +LONG : 11.5 +LONG : 11.5 +LONG : 11 +LONG : 9 +LONG : 11.5 +LONG : 10.5 +LONG : 12.5 +LONG : 11.5 +LONG : 11 +LONG : 11 +LONG : 11.5 +LONG : 10.5 +LONG : 10.5 +LONG : 12 +LONG : 11.5 +LONG : 13 +LONG : 11 +LONG : 12 +LONG : 11 +LONG : 11.5 +LONG : 12 +LONG : 10.5 +LONG : 11.5 +LONG : 11 +LONG : 10.5 +LONG : 9.5 +LONG : 10.5 +LONG : 11 +LONG : 10.5 +LONG : 11 +LONG : 11 +LONG : 12 +LONG : 16 +LONG : 13.5 +LONG : 13 +LONG : 12 +LONG : 13 +LONG : 16.5 +LONG : 12 +LONG : 11.5 +LONG : 12 +LONG : 11 +LONG : 11 +LONG : 11.5 +LONG : 13 +LONG : 12 +LONG : 11 +LONG : 14 +LONG : 12.5 +LONG : 11.5 +LONG : 12 +LONG : 12.5 +LONG : 12 +LONG : 12.5 +LONG : 16 +LONG : 16 +LONG : 11.5 +LONG : 11.5 +LONG : 10.5 +LONG : 11.5 +LONG : 11.5 +ESPE : MULLBAR +POID : 4853 +TAIL : 1685 +CATE : F +LONG : 9.5 +LONG : 10.5 +LONG : 11.5 +LONG : 11.5 +LONG : 13 +LONG : 12 +LONG : 10.5 +LONG : 12 +LONG : 12 +LONG : 13.5 +LONG : 16.5 +LONG : 12.5 +LONG : 15.5 +LONG : 12.5 +LONG : 12 +LONG : 14 +LONG : 14.5 +LONG : 14.5 +LONG : 14.5 +LONG : 14.5 +LONG : 12.5 +LONG : 13 +LONG : 13.5 +LONG : 12 +LONG : 12 +LONG : 11.5 +LONG : 12 +LONG : 13 +LONG : 15.5 +LONG : 14.5 +LONG : 13.5 +LONG : 13 +LONG : 13 +LONG : 13 +LONG : 14 +LONG : 15.5 +LONG : 14.5 +LONG : 14 +LONG : 12.5 +LONG : 17 +LONG : 15 +LONG : 15 +LONG : 15 +LONG : 16 +LONG : 15 +LONG : 14.5 +LONG : 14.5 +LONG : 14.5 +LONG : 15.5 +LONG : 14 +LONG : 13.5 +LONG : 16 +LONG : 13.5 +LONG : 15 Added: trunk/tutti-service/src/test/resources/psion/CFchephren 110612.IWA =================================================================== --- trunk/tutti-service/src/test/resources/psion/CFchephren 110612.IWA (rev 0) +++ trunk/tutti-service/src/test/resources/psion/CFchephren 110612.IWA 2014-01-20 20:41:49 UTC (rev 1516) @@ -0,0 +1,330 @@ + +INIT : CF +PORT : LOC +DATE : 06-11-2012 +HEUR : 04:37:33 +OUTI : Pied � coulisse +NAVI : CHEPHREN +ENGI : B +ESPE : 4401 +TAXO : 1 +LONG : 10.77 +LONG : 10.25 +LONG : 11.59 +LONG : 10.55 +LONG : 12.88 +LONG : 11.06 +LONG : 9.64 +LONG : 10.16 +LONG : 12.70 +LONG : 14.29 +LONG : 14.24 +LONG : 10.48 +LONG : 11.52 +LONG : 10.60 +LONG : 10.47 +LONG : 10.77 +LONG : 8.61 +LONG : 12.94 +LONG : 12.10 +LONG : 13.31 +LONG : 10.86 +LONG : 10.71 +LONG : 13.07 +LONG : 12.02 +LONG : 11.08 +LONG : 12.31 +LONG : 11.78 +LONG : 11.94 +LONG : 10.35 +LONG : 12.07 +LONG : 9.86 +LONG : 12.28 +LONG : 10.35 +LONG : 11.28 +LONG : 12.50 +LONG : 12.09 +LONG : 11.07 +LONG : 9.63 +LONG : 10.31 +LONG : 8.85 +LONG : 10.14 +LONG : 12.15 +LONG : 10.69 +LONG : 11.50 +LONG : 10.45 +LONG : 10.10 +LONG : 10.70 +TAXO : 2 +LONG : 12.33 +LONG : 11.89 +LONG : 10.21 +LONG : 10.55 +LONG : 9.95 +LONG : 10.83 +LONG : 9.92 +LONG : 12.32 +LONG : 11.90 +LONG : 10.43 +LONG : 10.46 +LONG : 10.33 +LONG : 10.82 +LONG : 9.87 +LONG : 9.89 +LONG : 10.91 +LONG : 10.28 +LONG : 10.29 +LONG : 11.18 +LONG : 9.86 +LONG : 11.00 +LONG : 11.52 +LONG : 11.22 +LONG : 12.02 +LONG : 11.11 +LONG : 9.59 +LONG : 11.26 +LONG : 10.02 +LONG : 10.61 +LONG : 9.31 +LONG : 10.85 +LONG : 11.24 +LONG : 10.25 +LONG : 11.20 +LONG : 11.11 +LONG : 11.77 +LONG : 9.89 +LONG : 10.53 +LONG : 10.46 +LONG : 11.77 +LONG : 12.44 +LONG : 9.96 +LONG : 10.32 +LONG : 10.23 +LONG : 10.96 +LONG : 10.65 +LONG : 10.06 +LONG : 8.15 +LONG : 10.53 +LONG : 12.65 +LONG : 10.49 +LONG : 12.22 +LONG : 11.49 +LONG : 11.01 +LONG : 10.46 +LONG : 10.02 +LONG : 11.39 +LONG : 9.98 +LONG : 10.72 +LONG : 10.64 +LONG : 11.28 +LONG : 11.59 +LONG : 11.89 +LONG : 11.47 +LONG : 11.18 +LONG : 10.62 +LONG : 12.19 +LONG : 10.16 +LONG : 10.40 +LONG : 11.98 +LONG : 11.87 +LONG : 11.92 +LONG : 10.86 +LONG : 10.07 +LONG : 11.23 +LONG : 9.93 +LONG : 10.24 +LONG : 10.95 +LONG : 9.69 +LONG : 9.82 +LONG : 11.61 +LONG : 9.57 +LONG : 11.40 +LONG : 10.22 +LONG : 9.27 +LONG : 10.80 +LONG : 11.40 +LONG : 9.68 +LONG : 10.68 +LONG : 7.09 +LONG : 10.61 +LONG : 10.33 +LONG : 10.73 +TAXO : 1 +LONG : 11.79 +LONG : 11.35 +LONG : 10.58 +LONG : 11.32 +LONG : 15.86 +TAXO : 2 +LONG : 10.49 +LONG : 10.60 +LONG : 10.73 +LONG : 10.31 +LONG : 9.52 +TAXO : 1 +LONG : 1.16 +CAIS : 05:13:38 +AGEN : CF +PORT : LOC +DATE : 06-11-2012 +HEUR : 05:14:3 +OUTI : Ichtyometre +OUTI : Pied a coulisse +NAVI : CHEPHREN +ENGI : B +ESPE : 4401 +CATE : N +TAXO : 2 +LONG : 46 +TAXO : 1 +LONG : 56 +LONG : 53 +LONG : 54 +LONG : 57 +LONG : 50 +LONG : 53 +LONG : 54 +LONG : 56 +LONG : 55 +LONG : 55 +LONG : 51 +LONG : 48 +LONG : 51 +LONG : 58 +LONG : 49 +LONG : 51 +LONG : 50 +LONG : 49 +LONG : 54 +LONG : 47 +LONG : 49 +LONG : 51 +LONG : 49 +LONG : 51 +LONG : 49 +LONG : 56 +LONG : 52 +LONG : 56 +LONG : 56 +LONG : 51 +LONG : 50 +LONG : 53 +LONG : 52 +LONG : 51 +LONG : 51 +LONG : 48 +LONG : 51 +LONG : 48 +LONG : 55 +LONG : 49 +LONG : 51 +LONG : 57 +LONG : 53 +LONG : 53 +LONG : 57 +LONG : 54 +LONG : 48 +LONG : 51 +LONG : 52 +LONG : 58 +LONG : 52 +LONG : 54 +LONG : 54 +LONG : 51 +LONG : 54 +LONG : 53 +LONG : 53 +LONG : 58 +LONG : 53 +LONG : 48 +LONG : 50 +LONG : 50 +LONG : 54 +LONG : 56 +LONG : 58 +LONG : 53 +LONG : 50 +LONG : 50 +LONG : 54 +LONG : 56 +LONG : 49 +LONG : 54 +LONG : 55 +LONG : 54 +LONG : 50 +LONG : 50 +LONG : 53 +LONG : 59 +LONG : 51 +LONG : 49 +LONG : 52 +LONG : 45 +LONG : 49 +LONG : 56 +LONG : 55 +LONG : 55 +LONG : 54 +LONG : 53 +LONG : 53 +LONG : 52 +LONG : 61 +LONG : 55 +LONG : 51 +LONG : 53 +LONG : 53 +LONG : 55 +LONG : 55 +LONG : 55 +LONG : 52 +LONG : 53 +LONG : 54 +LONG : 50 +LONG : 54 +LONG : 47 +LONG : 54 +LONG : 57 +LONG : 51 +LONG : 51 +LONG : 51 +LONG : 56 +LONG : 50 +LONG : 53 +LONG : 47 +LONG : 56 +LONG : 57 +LONG : 54 +LONG : 56 +LONG : 55 +LONG : 48 +LONG : 58 +LONG : 55 +LONG : 59 +LONG : 51 +LONG : 49 +LONG : 51 +LONG : 52 +LONG : 54 +LONG : 41 +LONG : 53 +LONG : 54 +LONG : 51 +LONG : 56 +LONG : 54 +LONG : 47 +LONG : 49 +LONG : 48 +LONG : 54 +LONG : 49 +LONG : 49 +LONG : 54 +LONG : 53 +LONG : 51 +LONG : 55 +LONG : 51 +LONG : 52 +LONG : 53 +LONG : 50 +LONG : 53 +LONG : 52 +LONG : 49 +CAIS : 05:35:7 Added: trunk/tutti-service/src/test/resources/psion/FM001.IWA =================================================================== --- trunk/tutti-service/src/test/resources/psion/FM001.IWA (rev 0) +++ trunk/tutti-service/src/test/resources/psion/FM001.IWA 2014-01-20 20:41:49 UTC (rev 1516) @@ -0,0 +1,210 @@ +fm +001 +05-24-2013 +18:28:13 + +ESPE : HELIDAC +POID : 1040 +TAIL : 1040 +CATE : N +LONG : 21.5 +LONG : 26 +LONG : 22 +LONG : 24 +LONG : 25.5 +ESPE : TODASAG +POID : 265 +TAIL : 265 +CATE : N +LONG : 21 +ESPE : RAJAOXY +POID : 115 +TAIL : 115 +CATE : F1 +LONG : 35 +ESPE : PHYIBLE +POID : 235 +TAIL : 235 +CATE : N +LONG : 6.5 +LONG : 6.5 +LONG : 7.5 +LONG : 7.5 +LONG : 6 +LONG : 6.5 +LONG : 7.5 +LONG : 7.5 +LONG : 8 +LONG : 8 +LONG : 6.5 +LONG : 8.5 +LONG : 7.5 +LONG : 7 +LONG : 5.5 +LONG : 7.5 +LONG : 7 +LONG : 6.5 +LONG : 7.5 +LONG : 7.5 +LONG : 6 +LONG : 6 +LONG : 6 +LONG : 6.5 +LONG : 5.5 +LONG : 6.5 +LONG : 7 +LONG : 7.5 +LONG : 6.5 +LONG : 18 +LONG : 16 +LONG : 22.5 +LONG : 15.5 +LONG : 16 +LONG : 7.5 +LONG : 7.5 +ESPE : GALUMEL +POID : 1460 +TAIL : 1460 +CATE : M +LONG : 35 +LONG : 32.5 +LONG : 34 +LONG : 33.5 +LONG : 40 +LONG : 40 +LONG : 40 +LONG : 42 +LONG : 45 +ESPE : LEPMBOS +POID : 275 +TAIL : 275 +CATE : N +LONG : 21 +LONG : 15.5 +LONG : 16.5 +LONG : 20 +LONG : 20 +LONG : 14 +ESPE : GALUMEL +POID : 4890 +TAIL : 4890 +CATE : F +LONG : 42 +LONG : 43.5 +LONG : 34 +LONG : 40 +LONG : 44 +LONG : 36.5 +LONG : 30.5 +LONG : 37.5 +LONG : 40 +LONG : 38 +LONG : 37 +LONG : 38 +LONG : 37 +LONG : 40 +LONG : 43 +LONG : 38 +LONG : 35 +LONG : 46 +LONG : 49 +LONG : 48.5 +LONG : 48.5 +LONG : 46.5 +LONG : 48.5 +ESPE : NEPRNOR +POID : 110 +TAIL : 110 +CATE : F +LONG : 28 +LONG : 31 +LONG : 29 +LONG : 36 +LONG : 25 +LONG : 32 +LONG : 32 +LONG : 34 +ESPE : NEPRNOR +POID : 365 +TAIL : 365 +CATE : M +LONG : 54 +LONG : 44 +LONG : 47 +LONG : 39 +LONG : 27 +LONG : 37 +LONG : 30 +LONG : 32 +LONG : 34 +LONG : 32 +ESPE : ARISFOL +POID : 775 +TAIL : 775 +CATE : F +LONG : 46 +LONG : 47 +LONG : 43 +LONG : 43 +LONG : 45 +LONG : 43 +LONG : 45 +LONG : 47 +LONG : 46 +LONG : 33 +LONG : 43 +LONG : 33 +LONG : 29 +LONG : 43 +LONG : 46 +LONG : 45 +LONG : 46 +LONG : 45 +LONG : 46 +LONG : 43 +LONG : 42 +LONG : 42 +LONG : 43 +LONG : 45 +LONG : 46 +LONG : 45 +LONG : 47 +LONG : 45 +LONG : 40 +ESPE : ARISFOL +POID : 75 +TAIL : 75 +CATE : M +LONG : 34 +LONG : 32 +LONG : 38 +LONG : 32 +LONG : 33 +ESPE : PAPELON +POID : 40 +TAIL : 40 +CATE : M +LONG : 30 +LONG : 32 +LONG : 33 +ESPE : PAPELON +POID : 40 +TAIL : 40 +CATE : F +LONG : 36 +LONG : 36 +ESPE : ETMOSPI +POID : 90 +TAIL : 90 +CATE : F +LONG : 20 +LONG : 19.5 +LONG : 12.5 +ESPE : ETMOSPI +POID : 295 +TAIL : 295 +CATE : M +LONG : 18.5 +LONG : 13 +LONG : 30.5 +LONG : 30.5