Author: blavenier Date: 2013-01-18 17:49:08 +0100 (Fri, 18 Jan 2013) New Revision: 225 Url: http://forge.codelutin.com/projects/tutti/repository/revisions/225 Log: ref refs #1920: [Persistence] Adagio Donnees thematiques - Continue implementation of FishingOperation.create() : lat/long, trawl distance, etc. Modified: trunk/tutti-persistence-adagio/src/main/java/fr/ifremer/tutti/persistence/TuttiEnumerationFile.java trunk/tutti-persistence-adagio/src/main/java/fr/ifremer/tutti/persistence/service/CruisePersistenceServiceImpl.java trunk/tutti-persistence-adagio/src/main/java/fr/ifremer/tutti/persistence/service/FishingOperationPersistenceServiceImpl.java trunk/tutti-persistence-adagio/src/main/resources/queries-override.hbm.xml trunk/tutti-persistence-adagio/src/main/resources/tutti-db-enumerations.properties trunk/tutti-persistence-adagio/src/test/java/fr/ifremer/tutti/persistence/service/FishingOperationPersistenceServiceTest.java Modified: trunk/tutti-persistence-adagio/src/main/java/fr/ifremer/tutti/persistence/TuttiEnumerationFile.java =================================================================== --- trunk/tutti-persistence-adagio/src/main/java/fr/ifremer/tutti/persistence/TuttiEnumerationFile.java 2013-01-18 15:05:20 UTC (rev 224) +++ trunk/tutti-persistence-adagio/src/main/java/fr/ifremer/tutti/persistence/TuttiEnumerationFile.java 2013-01-18 16:49:08 UTC (rev 225) @@ -131,6 +131,31 @@ @Value("${QualityFlagCode.NOTQUALIFIED}") public final String QUALITY_FLAG_CODE_NOT_QUALIFIED = null; + @Value("${PmfmId.STATION_NUMBER}") + public final Integer PMFM_ID_STATION_NUMBER = null; + + @Value("${PmfmId.TRAWL_DISTANCE}") + public final Integer PMFM_ID_TRAWL_DISTANCE = null; + + @Value("${PmfmId.RECTILINEAR_OPERATION}") + public final Integer PMFM_ID_RECTILINEAR_OPERATION = null; + + @Value("${QualitativeValueId.RECTILINEAR_OPERATION_YES}") + public final Integer QUALITATIVE_RECTILINEAR_OPERATION_YES = null; + + @Value("${QualitativeValueId.RECTILINEAR_OPERATION_NO}") + public final Integer QUALITATIVE_RECTILINEAR_OPERATION_NO = null; + + @Value("${PmfmId.HAUL_VALID}") + public final Integer PMFM_ID_HAUL_VALID = null; + + @Value("${QualitativeValueId.HAUL_VALID_YES}") + public final Integer QUALITATIVE_HAUL_VALID_YES = null; + + @Value("${QualitativeValueId.HAUL_VALID_NO}") + public final Integer QUALITATIVE_HAUL_VALID_NO = null; + + public void init() { Preconditions.checkNotNull(GEAR_CLASSIFICIATION_ID_SCIENTIFIC, "GEAR_CLASSIFICIATION_ID_SCIENTIFIC constant not found"); Preconditions.checkNotNull(GEAR_CLASSIFICIATION_ID_FISHING, "GEAR_CLASSIFICIATION_ID_FISHING constant not found"); @@ -153,6 +178,10 @@ Preconditions.checkNotNull(PMFM_ID_MATURITY, "PMFM_ID_MATURITY constant not found"); Preconditions.checkNotNull(PMFM_ID_MACRO_WASTE_CATEGORY, "PMFM_ID_MACRO_WASTE_CATEGORY constant not found"); Preconditions.checkNotNull(PMFM_ID_MACRO_WASTE_SIZE_CATEGORY, "PMFM_ID_MACRO_WASTE_SIZE_CATEGORY constant not found"); + Preconditions.checkNotNull(PMFM_ID_STATION_NUMBER, "PMFM_ID_STATION_NUMBER constant not found"); + Preconditions.checkNotNull(PMFM_ID_TRAWL_DISTANCE, "PMFM_ID_TRAWL_DISTANCE constant not found"); + Preconditions.checkNotNull(PMFM_ID_RECTILINEAR_OPERATION, "PMFM_ID_RECTILINEAR_OPERATION constant not found"); + Preconditions.checkNotNull(PMFM_ID_HAUL_VALID, "PMFM_ID_HAUL_VALID constant not found"); Preconditions.checkNotNull(QUALITY_FLAG_CODE_NOT_QUALIFIED, "QUALITY_FLAG_CODE_NOT_QUALIFIED constant not found"); Preconditions.checkNotNull(UNIT_ID_NONE, "UNIT_ID_NONE constant not found"); Preconditions.checkNotNull(USER_PROFIL_ID_OBSERVER, "USER_PROFIL_ID_OBSERVER constant not found"); @@ -164,5 +193,10 @@ Preconditions.checkNotNull(STATUS_VALID_CODE, "StatusCode.ENABLE constant not found"); Preconditions.checkNotNull(STATUS_TEMPORARY_CODE, "StatusCode.TEMPORARY constant not found"); Preconditions.checkNotNull(QUALITATIVE_VRAC_ID, "QualitativeValueId.VRAC constant not found"); + Preconditions.checkNotNull(QUALITATIVE_RECTILINEAR_OPERATION_YES, "QualitativeValueId.RECTILINEAR_OPERATION_YES constant not found"); + Preconditions.checkNotNull(QUALITATIVE_RECTILINEAR_OPERATION_NO, "QualitativeValueId.RECTILINEAR_OPERATION_NO constant not found"); + Preconditions.checkNotNull(QUALITATIVE_HAUL_VALID_YES, "QualitativeValueId.HAUL_VALID_YES constant not found"); + Preconditions.checkNotNull(QUALITATIVE_HAUL_VALID_NO, "QualitativeValueId.HAUL_VALID_NO constant not found"); + } } Modified: trunk/tutti-persistence-adagio/src/main/java/fr/ifremer/tutti/persistence/service/CruisePersistenceServiceImpl.java =================================================================== --- trunk/tutti-persistence-adagio/src/main/java/fr/ifremer/tutti/persistence/service/CruisePersistenceServiceImpl.java 2013-01-18 15:05:20 UTC (rev 224) +++ trunk/tutti-persistence-adagio/src/main/java/fr/ifremer/tutti/persistence/service/CruisePersistenceServiceImpl.java 2013-01-18 16:49:08 UTC (rev 225) @@ -33,6 +33,7 @@ import fr.ifremer.adagio.core.dao.referential.QualityFlagDao; import fr.ifremer.adagio.core.dao.referential.location.Location; import fr.ifremer.adagio.core.dao.referential.location.LocationDao; +import fr.ifremer.adagio.core.dao.referential.pmfm.PmfmDao; import fr.ifremer.adagio.core.dao.referential.vessel.VesselDao; import fr.ifremer.adagio.core.dao.technical.synchronization.SynchronizationStatus; import fr.ifremer.tutti.persistence.entities.data.Cruise; Modified: trunk/tutti-persistence-adagio/src/main/java/fr/ifremer/tutti/persistence/service/FishingOperationPersistenceServiceImpl.java =================================================================== --- trunk/tutti-persistence-adagio/src/main/java/fr/ifremer/tutti/persistence/service/FishingOperationPersistenceServiceImpl.java 2013-01-18 15:05:20 UTC (rev 224) +++ trunk/tutti-persistence-adagio/src/main/java/fr/ifremer/tutti/persistence/service/FishingOperationPersistenceServiceImpl.java 2013-01-18 16:49:08 UTC (rev 225) @@ -24,43 +24,42 @@ * #L% */ +import java.sql.Timestamp; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.Iterator; +import java.util.List; + +import javax.annotation.Resource; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.hibernate.type.IntegerType; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DataRetrievalFailureException; +import org.springframework.stereotype.Service; + +import com.google.common.collect.Lists; + +import fr.ifremer.adagio.core.dao.data.measure.VesselUseMeasurement; import fr.ifremer.adagio.core.dao.data.operation.FishingOperationDao; import fr.ifremer.adagio.core.dao.data.survey.fishingTrip.FishingTrip; import fr.ifremer.adagio.core.dao.data.survey.scientificCruise.ScientificCruise; import fr.ifremer.adagio.core.dao.data.survey.scientificCruise.ScientificCruiseDao; import fr.ifremer.adagio.core.dao.data.vessel.feature.use.GearUseFeatures; +import fr.ifremer.adagio.core.dao.data.vessel.feature.use.VesselUseFeatures; +import fr.ifremer.adagio.core.dao.data.vessel.feature.use.isActive; import fr.ifremer.adagio.core.dao.data.vessel.position.VesselPosition; import fr.ifremer.adagio.core.dao.referential.QualityFlagDao; import fr.ifremer.adagio.core.dao.referential.gear.Gear; import fr.ifremer.adagio.core.dao.referential.gear.GearDao; -import fr.ifremer.adagio.core.dao.referential.location.Location; import fr.ifremer.adagio.core.dao.referential.location.LocationDao; -import fr.ifremer.adagio.core.dao.technical.synchronization.SynchronizationStatus; -import fr.ifremer.tutti.persistence.entities.data.Cruise; +import fr.ifremer.adagio.core.dao.referential.pmfm.PmfmDao; +import fr.ifremer.adagio.core.dao.referential.pmfm.PmfmId; +import fr.ifremer.adagio.core.dao.referential.pmfm.QualitativeValueDao; import fr.ifremer.tutti.persistence.entities.data.FishingOperation; -import fr.ifremer.tutti.persistence.entities.data.Program; -import fr.ifremer.tutti.persistence.entities.referential.Country; -import fr.ifremer.tutti.persistence.entities.referential.Person; -import fr.ifremer.tutti.persistence.entities.referential.Vessel; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.hibernate.type.IntegerType; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.dao.DataRetrievalFailureException; -import org.springframework.stereotype.Service; - -import com.google.common.collect.Lists; - -import java.sql.Timestamp; -import java.util.Calendar; -import java.util.Date; -import java.util.GregorianCalendar; -import java.util.Iterator; -import java.util.List; - -import javax.annotation.Resource; - /** * @author tchemit <chemit@codelutin.com> * @since 0.3 @@ -89,7 +88,19 @@ @Resource(name = "qualityFlagDao") protected QualityFlagDao qualityFlagDao; + + @Resource(name = "pmfmDao") + protected PmfmDao pmfmDao; + @Resource(name = "qualitativeValueDao") + protected QualitativeValueDao qualitativeValueDao; + + protected static Float DEFAULT_EMPTY_LATITUDE = 0.0001f; + + protected static Float DEFAULT_EMPTY_LONGITUDE = 0.0001f; + + protected static String FISHING_OPERATION_NAME_SEPARATOR = " - "; + protected Calendar calendar = new GregorianCalendar(); @Override @@ -101,7 +112,11 @@ public FishingOperation getFishingOperation(String id) { Object[] source = queryUnique( "fishingOperation", - "fishingOperationId", IntegerType.INSTANCE, Integer.valueOf(id)); + "fishingOperationId", IntegerType.INSTANCE, Integer.valueOf(id), + "pmfmIdTrawlDistance", IntegerType.INSTANCE, enumeration.PMFM_ID_TRAWL_DISTANCE, + "pmfmIdRectilinearOperation", IntegerType.INSTANCE, enumeration.PMFM_ID_RECTILINEAR_OPERATION, + "pmfmIdHaulValid", IntegerType.INSTANCE, enumeration.PMFM_ID_HAUL_VALID + ); if (source == null) { throw new DataRetrievalFailureException("Could not retrieve fishingOperation with id=" + id); @@ -114,19 +129,36 @@ int colIndex=0; - // Start date - calendar.setTimeInMillis(((Timestamp) source[colIndex++]).getTime()); - int millisecond = calendar.get(Calendar.MILLISECOND); - if (millisecond > 0) { - // Recognize a fake date : see method beanToEntity() - result.setGearShootingStartDate(null); + // Name = StationNumber - FishingOperationNumber - TrawlNetNumber + String name = (String)source[colIndex++]; + if (name != null) { + String[] nameInfos = name.split(FISHING_OPERATION_NAME_SEPARATOR); + if (nameInfos.length == 3) { + // Station number + result.setStationNumber(nameInfos[0]); + + // Fishing operation number + if (nameInfos[1].length() == 0) { + result.setFishingOperationNumber(null); + } + else { + result.setFishingOperationNumber(Integer.valueOf(nameInfos[1])); + } + // Trawl net number + if (nameInfos[2].length() == 0) { + result.setTrawlNetNumber(null); + } + else { + result.setTrawlNetNumber(Integer.valueOf(nameInfos[2])); + } + } } - else { - result.setGearShootingStartDate(calendar.getTime()); - } + // Start date + result.setGearShootingStartDate(convertDatabase2UI((Timestamp) source[colIndex++])); + // End date - result.setGearShootingEndDate((Date) source[colIndex++]); + result.setGearShootingEndDate(convertDatabase2UI((Timestamp) source[colIndex++])); // Comment : result.setComment((String) source[colIndex++]); @@ -139,6 +171,40 @@ result.setGear(gear); } + // Start position + VesselPosition startVesselPosition = (VesselPosition)source[colIndex++]; + if (startVesselPosition == null) { + result.setGearShootingStartLatitude(null); + result.setGearShootingStartLongitude(null); + } + else { + result.setGearShootingStartLatitude(convertLatitude2UI(startVesselPosition.getLatitude())); + result.setGearShootingStartLongitude(convertLongitude2UI(startVesselPosition.getLongitude())); + } + + // End position + VesselPosition endVesselPosition = (VesselPosition)source[colIndex++]; + if (endVesselPosition == null) { + result.setGearShootingEndLatitude(null); + result.setGearShootingEndLongitude(null); + } + else { + result.setGearShootingEndLatitude(DEFAULT_EMPTY_LATITUDE.equals(endVesselPosition.getLatitude())?null:endVesselPosition.getLatitude()); + result.setGearShootingEndLongitude(DEFAULT_EMPTY_LONGITUDE.equals(endVesselPosition.getLongitude())?null:endVesselPosition.getLongitude()); + } + + // Trawl distance + result.setTrawlDistance((Float)source[colIndex++]); + + // Rectilinear operation ? + result.setFishingOperationRectiligne(enumeration.QUALITATIVE_RECTILINEAR_OPERATION_YES.equals((Integer)source[colIndex++])); + + // Haul valid ? + Integer haulValidQualitativeId = (Integer)source[colIndex++]; + if (haulValidQualitativeId != null) { + result.setFishingOperationValid((enumeration.QUALITATIVE_HAUL_VALID_YES.equals(haulValidQualitativeId))); + } + return result; } @@ -159,7 +225,8 @@ } protected void beanToEntity(FishingOperation source, fr.ifremer.adagio.core.dao.data.operation.FishingOperation target, boolean copyIfNull) { - //StringBuffer miscDataBuffer = new StringBuffer(); + + // Retrieve entities : FishingTrip and ScientificCruise ScientificCruise scientificCruise = null; FishingTrip fishingtrip = target.getFishingTrip(); if (fishingtrip == null) { @@ -174,7 +241,7 @@ // Link to parent fishing trip target.setFishingTrip(fishingtrip); - // Store previous start/stop position + // Retrieve entities : VesselPosition (start and end) VesselPosition startPosition = null; VesselPosition endPosition = null; if (target.getVesselPositions() != null) { @@ -188,23 +255,74 @@ } } } + + // Retrieve entities : Gear Use Features + GearUseFeatures gearUseFeature = null; + if (target.getGearUseFeatures() == null || target.getGearUseFeatures().size() == 0) { + gearUseFeature = GearUseFeatures.Factory.newInstance(); + if (target.getGearUseFeatures() == null) { + target.setGearUseFeatures(Lists.newArrayList(gearUseFeature)); + gearUseFeature.setOperation(target); + } else { + target.getGearUseFeatures().add(gearUseFeature); + gearUseFeature.setOperation(target); + } + } else { + gearUseFeature = target.getGearUseFeatures().iterator().next(); + } + // Retrieve entities : Vessel Use Features + VesselUseFeatures vesselUseFeature = null; + if (target.getVesselUseFeatures() == null || target.getVesselUseFeatures().size() == 0) { + vesselUseFeature = VesselUseFeatures.Factory.newInstance(); + if (target.getVesselUseFeatures() == null) { + target.setVesselUseFeatures(Lists.newArrayList(vesselUseFeature)); + vesselUseFeature.setOperation(target); + } else { + target.getVesselUseFeatures().add(vesselUseFeature); + vesselUseFeature.setOperation(target); + } + } else { + vesselUseFeature = target.getVesselUseFeatures().iterator().next(); + } + + StringBuffer nameBuffer = new StringBuffer(); + // StationNumber if (copyIfNull && source.getStationNumber() == null) { - // TODO BL : where to store station number + setVesselUseMeasurement(scientificCruise, vesselUseFeature, enumeration.PMFM_ID_STATION_NUMBER, null, "", null); } else if (source.getStationNumber() != null) { - //source.getStationNumber(); - // TODO BL : where to store station number + setVesselUseMeasurement(scientificCruise, vesselUseFeature, enumeration.PMFM_ID_STATION_NUMBER, null, source.getStationNumber(), null); + nameBuffer.append(source.getStationNumber()); } // OP N° if (copyIfNull && source.getFishingOperationNumber() == null) { - // TODO BL : where to store OP N° + // Leave empty in the name buffer + if (nameBuffer.length() > 0) { + nameBuffer.append(FISHING_OPERATION_NAME_SEPARATOR); + } } else if (source.getFishingOperationNumber() != null) { - //source.getStationNumber(); + if (nameBuffer.length() > 0) { + nameBuffer.append(FISHING_OPERATION_NAME_SEPARATOR); + } + // TODO BL : store OP N° ? or compute it ? + nameBuffer.append(source.getFishingOperationNumber()); + } + + // Trawl net number + if (copyIfNull && source.getTrawlNetNumber() == null) { // TODO BL : where to store OP N° + } else if (source.getTrawlNetNumber() != null) { + if (nameBuffer.length() > 0) { + nameBuffer.append(FISHING_OPERATION_NAME_SEPARATOR); + } + // TODO BL : store in Gear Use Measurement ? + nameBuffer.append(source.getTrawlNetNumber()); } + target.setName(nameBuffer.toString()); + // Start date : if (copyIfNull && source.getGearShootingStartDate() == null) { target.setStartDateTime(null); @@ -228,7 +346,24 @@ target.setEndDateTime(calendar.getTime()); target.setFishingEndDateTime(calendar.getTime()); } + + // Trawl distance + if (copyIfNull && source.getTrawlDistance() == null) { + removeVesselUseMeasurement(vesselUseFeature, enumeration.PMFM_ID_TRAWL_DISTANCE); + } else if (source.getTrawlDistance() != null) { + setVesselUseMeasurement(scientificCruise, vesselUseFeature, enumeration.PMFM_ID_TRAWL_DISTANCE, source.getTrawlDistance(), null, null); + } + + // Rectilinear operation + setVesselUseMeasurement(scientificCruise, vesselUseFeature, enumeration.PMFM_ID_RECTILINEAR_OPERATION, null, null, source.isFishingOperationRectiligne()?enumeration.QUALITATIVE_RECTILINEAR_OPERATION_YES:enumeration.QUALITATIVE_RECTILINEAR_OPERATION_NO); + // Operation is valid ? + if (copyIfNull && source.getFishingOperationValid() == null) { + removeVesselUseMeasurement(vesselUseFeature, enumeration.PMFM_ID_HAUL_VALID); + } else if (source.getFishingOperationValid() != null) { + setVesselUseMeasurement(scientificCruise, vesselUseFeature, enumeration.PMFM_ID_HAUL_VALID, null, null, source.getFishingOperationValid().booleanValue()?enumeration.QUALITATIVE_HAUL_VALID_YES:enumeration.QUALITATIVE_HAUL_VALID_NO); + } + // Comment if (copyIfNull && source.getComment() == null) { target.setComments(null); @@ -252,24 +387,30 @@ calendar.set(Calendar.MILLISECOND, 1); target.setStartDateTime(calendar.getTime()); target.setFishingStartDateTime(calendar.getTime()); - } + } - // Gear Use Features - GearUseFeatures gearUseFeature = null; - if (target.getGearUseFeatures() == null || target.getGearUseFeatures().size() == 0) { - gearUseFeature = GearUseFeatures.Factory.newInstance(); - if (target.getGearUseFeatures() == null) { - target.setGearUseFeatures(Lists.newArrayList(gearUseFeature)); - gearUseFeature.setOperation(target); - } else { - target.getGearUseFeatures().add(gearUseFeature); - gearUseFeature.setOperation(target); - } - } else { - gearUseFeature = target.getGearUseFeatures().iterator().next(); + // VesselUseFeatures : + vesselUseFeature.setStartDate(target.getStartDateTime()); + if (vesselUseFeature.getStartDate() == null) { + vesselUseFeature.setStartDate(scientificCruise.getDepartureDateTime()); } + vesselUseFeature.setEndDate(target.getEndDateTime()); + vesselUseFeature.setVessel(target.getVessel()); + vesselUseFeature.setProgram(scientificCruise.getProgram()); + vesselUseFeature.setIsActive(isActive.ACTIVE.getValue()); + if (vesselUseFeature.getCreationDate() == null) { + calendar.setTime(new Date()); + calendar.set(Calendar.HOUR_OF_DAY, 0); + calendar.set(Calendar.MINUTE, 0); + calendar.set(Calendar.SECOND, 0); + calendar.set(Calendar.MILLISECOND, 0); + vesselUseFeature.setCreationDate(calendar.getTime()); + } + if (vesselUseFeature.getQualityFlag() == null) { + vesselUseFeature.setQualityFlag(qualityFlagDao.load(enumeration.QUALITY_FLAG_CODE_NOT_QUALIFIED)); + } - // Fill fishing trip with scientificCruise info: + // GearUseFeatures : gearUseFeature.setStartDate(target.getStartDateTime()); if (gearUseFeature.getStartDate() == null) { gearUseFeature.setStartDate(scientificCruise.getDepartureDateTime()); @@ -289,7 +430,7 @@ gearUseFeature.setQualityFlag(qualityFlagDao.load(enumeration.QUALITY_FLAG_CODE_NOT_QUALIFIED)); } - // Gear + // GearUseFeatures.Gear if (copyIfNull && source.getGear() == null) { gearUseFeature.setGear(null); } else if (source.getGear() != null && source.getGear().getId() != null) { @@ -298,45 +439,212 @@ } // Start position : - if (startPosition == null) { - startPosition = VesselPosition.Factory.newInstance(); - startPosition.setOperation(target); - if (target.getVesselPositions() == null) { - target.setVesselPositions(Lists.newArrayList(startPosition)); + // If need to be store + if (source.getGearShootingEndLatitude() != null + || source.getGearShootingEndDate() != null + || source.getGearShootingEndLongitude() != null) { + + if (startPosition == null) { + startPosition = VesselPosition.Factory.newInstance(); + startPosition.setOperation(target); + if (target.getVesselPositions() == null) { + target.setVesselPositions(Lists.newArrayList(startPosition)); + } + target.getVesselPositions().add(startPosition); } + startPosition.setDateTime(target.getStartDateTime()); + startPosition.setLatitude(source.getGearShootingStartLatitude()!=null?source.getGearShootingStartLatitude():DEFAULT_EMPTY_LATITUDE); + startPosition.setLongitude(source.getGearShootingStartLongitude()!=null?source.getGearShootingStartLongitude():DEFAULT_EMPTY_LONGITUDE); + startPosition.setVessel(target.getVessel()); + startPosition.setProgram(scientificCruise.getProgram()); + startPosition.setRecorderDepartment(scientificCruise.getRecorderDepartment()); + startPosition.setQualityFlag(target.getQualityFlag()); } - startPosition.setDateTime(target.getStartDateTime()); - startPosition.setLatitude(source.getGearShootingStartLatitude()); - startPosition.setLongitude(source.getGearShootingStartLongitude()); - startPosition.setVessel(target.getVessel()); - startPosition.setProgram(scientificCruise.getProgram()); - startPosition.setRecorderDepartment(scientificCruise.getRecorderDepartment()); - startPosition.setQualityFlag(target.getQualityFlag()); + + // If not need to be store, delete start position from list + else if (startPosition != null && target.getVesselPositions() != null) { + target.getVesselPositions().remove(startPosition); + } - if (endPosition == null) { - endPosition = VesselPosition.Factory.newInstance(); - endPosition.setOperation(target); - target.getVesselPositions().add(endPosition); + // End position : + // If need to be store + if (source.getGearShootingEndLatitude() != null + || source.getGearShootingEndDate() != null + || source.getGearShootingEndLongitude() != null) { + + if (endPosition == null) { + endPosition = VesselPosition.Factory.newInstance(); + endPosition.setOperation(target); + target.getVesselPositions().add(endPosition); + } + Date endDateTime = convertUI2DatabaseMandatoryDate(target.getEndDateTime(), startPosition.getDateTime(), true); + endPosition.setDateTime(endDateTime); + if (endDateTime.equals(target.getEndDateTime()) == false) { + // To link position with the operation end, Allegro need to have exactly the same dates + target.setEndDateTime(endDateTime); + target.setFishingEndDateTime(endDateTime); + } + endPosition.setLatitude(convertUI2DatabaseMandatoryLatitude(source.getGearShootingEndLatitude())); + endPosition.setLongitude(convertUI2DatabaseMandatoryLatitude(source.getGearShootingEndLongitude())); + endPosition.setVessel(target.getVessel()); + endPosition.setProgram(scientificCruise.getProgram()); + endPosition.setRecorderDepartment(scientificCruise.getRecorderDepartment()); + endPosition.setQualityFlag(target.getQualityFlag()); } - endPosition.setDateTime(target.getEndDateTime()); - if (endPosition.getDateTime() == null) { - calendar.setTime(startPosition.getDateTime()); - calendar.set(Calendar.MILLISECOND, 1); - endPosition.setDateTime(calendar.getTime()); + + // If not need to be store, delete end position from list + else if (endPosition != null && target.getVesselPositions() != null) { + target.getVesselPositions().remove(endPosition); } - endPosition.setLatitude(source.getGearShootingEndLatitude()); - endPosition.setLongitude(source.getGearShootingEndLongitude()); - endPosition.setVessel(target.getVessel()); - endPosition.setProgram(scientificCruise.getProgram()); - endPosition.setRecorderDepartment(scientificCruise.getRecorderDepartment()); - endPosition.setQualityFlag(target.getQualityFlag()); - // Save miscDataBuffer into comments - //gearUseFeature.setComments(miscDataBuffer.toString()); } @Override public FishingOperation saveFishingOperation(FishingOperation bean) { return null; } + + /** + * Test if the date has millisecond set. This yes, return null, then return the date itself. + * @param databaseValue the date stored in the database (could be fake date, not null only because of database constraints) + * @return null if the date is a fake date + */ + protected Date convertDatabase2UI(Timestamp databaseValue) { + if (databaseValue == null) { + return null; + } + calendar.setTimeInMillis(databaseValue.getTime()); + if (calendar.get(Calendar.MILLISECOND) != 0) { + return null; + } + return calendar.getTime(); + } + + /** + * Convert a UI date, when the database value is mandatory. + * If the given value is null, use the default date, then set millisecond to '1', to be able to retrieve the null value later. + * @param uiValue the date used in the UI + * @return null if the date is a fake date + */ + protected Date convertUI2DatabaseMandatoryDate(Date uiValue, Date defaultNotEmptyDate, boolean addOneSecondToDefaultDate) { + // if ui date is not empty, then use it (but reset millisecond) + if (uiValue != null) { + calendar.setTime(uiValue); + calendar.set(Calendar.MILLISECOND, 0); + return calendar.getTime(); + } + if (defaultNotEmptyDate == null) { + throw new IllegalArgumentException("'defaultNotEmptyDate' could not be null."); + } + + calendar.setTime(defaultNotEmptyDate); + if (addOneSecondToDefaultDate) { + calendar.add(Calendar.SECOND, 1); + } + calendar.set(Calendar.MILLISECOND, 1); + return calendar.getTime(); + } + + /** + * Test if the latitude is null, and return a default value if yes + * @param databaseValue the latitude used in UI (could be null) + * @return null the latitude to store in database (could not be null) + */ + protected Float convertUI2DatabaseMandatoryLatitude(Float databaseValue) { + return (databaseValue != null)?databaseValue:DEFAULT_EMPTY_LATITUDE; + } + + /** + * Test if the latitude is a fake value. This yes, return null, then return the given value. + * @param databaseValue the latitude stored in the database (could be fake date, not null only because of database constraints) + * @return null if the latitude is fake + */ + protected Float convertLatitude2UI(Float databaseValue) { + return DEFAULT_EMPTY_LATITUDE.equals(databaseValue)?null:databaseValue; + } + + /** + * Test if the latitude is null, and return a default value if yes + * @param databaseValue the latitude used in UI (could be null) + * @return null the latitude to store in database (could not be null) + */ + protected Float convertUI2DatabaseMandatoryLongitude(Float databaseValue) { + return (databaseValue != null)?databaseValue:DEFAULT_EMPTY_LONGITUDE; + } + + /** + * Test if the longitude is a fake value. This yes, return null, then return the given value. + * @param databaseValue the longitude stored in the database (could be fake date, not null only because of database constraints) + * @return null if the longitude is fake + */ + protected Float convertLongitude2UI(Float databaseValue) { + return DEFAULT_EMPTY_LONGITUDE.equals(databaseValue)?null:databaseValue; + } + + protected Integer getPmfmId() { + // TODO BLA + return null; + } + + protected VesselUseMeasurement getVesselUseMeasurement(ScientificCruise scientificCruise, VesselUseFeatures vesselUseFeatures, + Integer pmfmId, boolean createIfNotExists) { + VesselUseMeasurement vesselUseMeasurement = null; + if (vesselUseFeatures.getVesselUseMeasurements() != null) { + for (Iterator iterator = vesselUseFeatures.getVesselUseMeasurements().iterator(); iterator.hasNext();) { + VesselUseMeasurement vum = (VesselUseMeasurement) iterator.next(); + if (pmfmId.equals(vum.getPmfm().getId())) { + vesselUseMeasurement = vum; + break; + } + } + } + if (vesselUseMeasurement == null) { + if (!createIfNotExists) { + return null; + } + vesselUseMeasurement = VesselUseMeasurement.Factory.newInstance(); + vesselUseMeasurement.setVesselUseFeatures(vesselUseFeatures); + if (vesselUseFeatures.getVesselUseMeasurements() == null) { + vesselUseFeatures.setVesselUseMeasurements(Lists.newArrayList(vesselUseMeasurement)); + } + else { + vesselUseFeatures.getVesselUseMeasurements().add(vesselUseMeasurement); + } + vesselUseMeasurement.setQualityFlag(qualityFlagDao.load(enumeration.QUALITY_FLAG_CODE_NOT_QUALIFIED)); + vesselUseMeasurement.setDepartment(scientificCruise.getRecorderDepartment()); + vesselUseMeasurement.setPmfm(pmfmDao.load(pmfmId)); + } + + return vesselUseMeasurement; + } + + protected void removeVesselUseMeasurement(VesselUseFeatures vesselUseFeatures, + Integer pmfmId) { + VesselUseMeasurement vesselUseMeasurement = getVesselUseMeasurement(null, vesselUseFeatures, pmfmId, false); + if (vesselUseMeasurement == null) { + return; + } + vesselUseFeatures.getVesselUseMeasurements().remove(vesselUseMeasurement); + // TOBO BLa : vérifier qu'il ne faut pas dao.delete() en plus + } + + protected VesselUseMeasurement setVesselUseMeasurement(ScientificCruise scientificCruise, VesselUseFeatures vesselUseFeatures, + Integer pmfmId, + Float numericalValue, + String alphanumericalValue, + Integer qualitativevalueId) { + VesselUseMeasurement vesselUseMeasurement = getVesselUseMeasurement(scientificCruise, vesselUseFeatures, pmfmId, true); + + if (alphanumericalValue != null) { + vesselUseMeasurement.setAlphanumericalValue(alphanumericalValue); + } + else if (numericalValue != null) { + vesselUseMeasurement.setNumericalValue(numericalValue); + } + else if (qualitativevalueId != null) { + vesselUseMeasurement.setQualitativeValue(qualitativeValueDao.load(qualitativevalueId)); + } + + return vesselUseMeasurement; + } } Modified: trunk/tutti-persistence-adagio/src/main/resources/queries-override.hbm.xml =================================================================== --- trunk/tutti-persistence-adagio/src/main/resources/queries-override.hbm.xml 2013-01-18 15:05:20 UTC (rev 224) +++ trunk/tutti-persistence-adagio/src/main/resources/queries-override.hbm.xml 2013-01-18 16:49:08 UTC (rev 225) @@ -165,17 +165,27 @@ <query cacheable="true" name="fishingOperation"> <![CDATA[ SELECT + o.name as name, o.startDateTime as startDateTime, o.endDateTime as endDateTime, o.comments as comments, - guf.gear.id as gearId + guf.gear.id as gearId, + (select vp_start from VesselPositionImpl vp_start where vp_start.operation.id = o.id and vp_start.dateTime = o.startDateTime) as startVesselPosition, + (select vp_end from VesselPositionImpl vp_end where vp_end.operation.id = o.id and vp_end.dateTime = o.endDateTime) as endVesselPosition, + (select vum.numericalValue from VesselUseMeasurementImpl vum where vum.vesselUseFeatures.id=vuf.id and vum.pmfm.id=:pmfmIdTrawlDistance) as trawlDistance, + (select vum2.qualitativeValue.id from VesselUseMeasurementImpl vum2 where vum2.vesselUseFeatures.id=vuf.id and vum2.pmfm.id=:pmfmIdRectilinearOperation) as rectilinearQualitativeId, + (select vum3.qualitativeValue.id from VesselUseMeasurementImpl vum3 where vum3.vesselUseFeatures.id=vuf.id and vum3.pmfm.id=:pmfmIdHaulValid) as haulValidQualitativeId FROM FishingOperationImpl o INNER JOIN o.gearUseFeatures guf + INNER JOIN o.vesselUseFeatures vuf WHERE o.id=:fishingOperationId ]]> <query-param name="fishingOperationId" type="java.lang.Integer"/> + <query-param name="pmfmIdTrawlDistance" type="java.lang.Integer"/> + <query-param name="pmfmIdRectilinearOperation" type="java.lang.Integer"/> + <query-param name="pmfmIdHaulValid" type="java.lang.Integer"/> </query> Modified: trunk/tutti-persistence-adagio/src/main/resources/tutti-db-enumerations.properties =================================================================== --- trunk/tutti-persistence-adagio/src/main/resources/tutti-db-enumerations.properties 2013-01-18 15:05:20 UTC (rev 224) +++ trunk/tutti-persistence-adagio/src/main/resources/tutti-db-enumerations.properties 2013-01-18 16:49:08 UTC (rev 225) @@ -326,9 +326,20 @@ PmfmId.MACRO_WASTE_CATEGORY=1181 #TODO A créér PmfmId.MACRO_WASTE_SIZE_CATEGORY=1181 +# TODO A creer (dans les enumerations Allegro) +PmfmId.STATION_NUMBER=1243 +# TODO A creer (dans les enumerations Allegro) +PmfmId.TRAWL_DISTANCE=113 +# TODO A creer (dans les enumerations Allegro) +PmfmId.HAUL_VALID=1163 +QualitativeValueId.HAUL_VALID_YES=1575 +QualitativeValueId.HAUL_VALID_NO=1576 +# TODO A creer (dans les enumerations Allegro) +PmfmId.RECTILINEAR_OPERATION=192 +QualitativeValueId.RECTILINEAR_OPERATION_YES=277 +# TODO A creer (dans les enumerations Allegro) +QualitativeValueId.RECTILINEAR_OPERATION_NO=278 -#TODO A creer (20=observateur volant, 95=Administrateur SIH) -# L'avantage du 20 est qu'il est inactif (=20), donc plus facilement detectable +#TODO A creer (dans les enumerations Allegro) +# (20=observateur volant, 95=Administrateur SIH) -> L'avantage du 20 est qu'il est inactif (=20), donc plus facilement detectable PersonId.UNKNOWN_RECORDER_PERSON=20 - - Modified: trunk/tutti-persistence-adagio/src/test/java/fr/ifremer/tutti/persistence/service/FishingOperationPersistenceServiceTest.java =================================================================== --- trunk/tutti-persistence-adagio/src/test/java/fr/ifremer/tutti/persistence/service/FishingOperationPersistenceServiceTest.java 2013-01-18 15:05:20 UTC (rev 224) +++ trunk/tutti-persistence-adagio/src/test/java/fr/ifremer/tutti/persistence/service/FishingOperationPersistenceServiceTest.java 2013-01-18 16:49:08 UTC (rev 225) @@ -85,7 +85,9 @@ @Test public void createFishingOperation(/*FishingOperation bean*/) { Calendar calendar = new GregorianCalendar(); - + FishingOperation reloadedFishingOperation = null; + FishingOperation createdFishingOperation = null; + // Duplicate an existing cruise, to attach new fishing operations cruise = cruiseService.getCruise(dbResource.getFixtures().cruiseId()); cruise.setId(null); @@ -98,41 +100,60 @@ // Create new fishing operation : FishingOperation fishingOperation = new FishingOperation(); + // ----------------------------------------------------------------------------- + // 1. Test with only mandatory properties + // ----------------------------------------------------------------------------- + // Set properties (with optional value to null) fishingOperation.setCruise(cruise); - fishingOperation.setStationNumber("1"); + fishingOperation.setStationNumber("STA1"); fishingOperation.setFishingOperationNumber(new Integer(1)); + fishingOperation.setTrawlNetNumber(new Integer(1)); fishingOperation.setGearShootingStartDate(null); fishingOperation.setGearShootingEndDate(null); fishingOperation.setGear(null); + fishingOperation.setGearShootingStartLatitude(33.2541f); + fishingOperation.setComment(null); // Store fishing operation into database : - FishingOperation createdFishingOperation = service.createFishingOperation(fishingOperation); + /*createdFishingOperation = service.createFishingOperation(fishingOperation); assertNotNull("Fishing operation ID must not be null after creation in database", createdFishingOperation); assertNotNull(createdFishingOperation.getId()); - // TODO BLA : add asserts on other properties // Trying to relaod this fishing operation - FishingOperation reloadedFishingOperation = service.getFishingOperation(createdFishingOperation.getId()); + reloadedFishingOperation = service.getFishingOperation(createdFishingOperation.getId()); assertNotNull(reloadedFishingOperation); assertNull(reloadedFishingOperation.getGearShootingStartDate()); - + */ + + // ----------------------------------------------------------------------------- + // 2. Test with all properties set + // ----------------------------------------------------------------------------- // Set properties fishingOperation.setId(null); - fishingOperation.setStationNumber("2"); + fishingOperation.setStationNumber("STA2"); fishingOperation.setFishingOperationNumber(new Integer(2)); + fishingOperation.setTrawlNetNumber(new Integer(2)); calendar.setTime(new Date()); calendar.set(Calendar.HOUR_OF_DAY, 1); + calendar.set(Calendar.MILLISECOND, 99); fishingOperation.setGearShootingStartDate(calendar.getTime()); calendar.setTime(new Date()); calendar.set(Calendar.HOUR_OF_DAY, 10); + calendar.set(Calendar.MILLISECOND, 99); fishingOperation.setGearShootingEndDate(calendar.getTime()); - + fishingOperation.setGearShootingStartLatitude(33.2541f); fishingOperation.setGearShootingStartLongitude(-5.514f); fishingOperation.setGearShootingEndLatitude(33.7441f); fishingOperation.setGearShootingEndLongitude(-5.597f); + + fishingOperation.setTrawlDistance(100.12345f); + fishingOperation.setFishingOperationRectiligne(true); + fishingOperation.setFishingOperationValid(Boolean.TRUE); + fishingOperation.setComment("Unit test createFishingOperation() - Part n°2 : All properties set"); + List<Gear> gears = referentialService.getAllFishingGear(); assertNotNull(gears); assertTrue(gears.size() > 0); @@ -142,12 +163,68 @@ createdFishingOperation = service.createFishingOperation(fishingOperation); assertNotNull("Fishing operation ID must not be null after creation in database", createdFishingOperation); assertNotNull(createdFishingOperation.getId()); - assertNotNull(createdFishingOperation.getGear()); - //assertEquals(fishingOperation.getGearShootingStartLatitude(), createdFishingOperation.getGearShootingStartLatitude()); - //assertEquals(fishingOperation.getGearShootingStartLongitude(), createdFishingOperation.getGearShootingStartLongitude()); - //assertEquals(fishingOperation.getGearShootingEndLatitude(), createdFishingOperation.getGearShootingEndLatitude()); - //assertEquals(fishingOperation.getGearShootingEndLongitude(), createdFishingOperation.getGearShootingEndLongitude()); + reloadedFishingOperation = service.getFishingOperation(createdFishingOperation.getId()); + assertNotNull(reloadedFishingOperation.getGear()); + assertEquals(fishingOperation.getStationNumber(), reloadedFishingOperation.getStationNumber()); + assertEquals(fishingOperation.getFishingOperationNumber(), reloadedFishingOperation.getFishingOperationNumber()); + assertEquals(fishingOperation.getTrawlNetNumber(), reloadedFishingOperation.getTrawlNetNumber()); + assertNotNull(reloadedFishingOperation.getGearShootingStartDate()); + calendar.setTime(fishingOperation.getGearShootingStartDate()); + calendar.set(Calendar.MILLISECOND, 0); + assertEquals(calendar.getTime(), reloadedFishingOperation.getGearShootingStartDate()); + assertEquals(fishingOperation.getGearShootingStartLatitude(), reloadedFishingOperation.getGearShootingStartLatitude()); + assertEquals(fishingOperation.getGearShootingStartLongitude(), reloadedFishingOperation.getGearShootingStartLongitude()); + assertNotNull(reloadedFishingOperation.getGearShootingEndDate()); + calendar.setTime(fishingOperation.getGearShootingEndDate()); + calendar.set(Calendar.MILLISECOND, 0); + assertEquals(calendar.getTime(), reloadedFishingOperation.getGearShootingEndDate()); + assertEquals(fishingOperation.getGearShootingEndLatitude(), reloadedFishingOperation.getGearShootingEndLatitude()); + assertEquals(fishingOperation.getGearShootingEndLongitude(), reloadedFishingOperation.getGearShootingEndLongitude()); + assertEquals(fishingOperation.getTrawlDistance(), reloadedFishingOperation.getTrawlDistance()); + assertEquals(fishingOperation.isFishingOperationRectiligne(), reloadedFishingOperation.isFishingOperationRectiligne()); + assertEquals(fishingOperation.getFishingOperationValid(), reloadedFishingOperation.getFishingOperationValid()); + assertEquals(fishingOperation.getComment(), reloadedFishingOperation.getComment()); + + // ----------------------------------------------------------------------------- + // 3. Test : + // - startDate and startLat filled, but empty endLong + // - endLat and endLong filled but empty endDate + // - isFishingOperationRectiligne = false + // - trawlDistance empty + // - fishingOperationValid = false + // ----------------------------------------------------------------------------- + fishingOperation.setId(null); + fishingOperation.setStationNumber("STA3"); + fishingOperation.setFishingOperationNumber(new Integer(3)); + fishingOperation.setTrawlNetNumber(new Integer(3)); + fishingOperation.setGearShootingStartLongitude(null); + fishingOperation.setGearShootingEndDate(null); + fishingOperation.setTrawlDistance(null); + fishingOperation.setFishingOperationRectiligne(false); + fishingOperation.setFishingOperationValid(false); + fishingOperation.setComment("Unit test createFishingOperation() - Part n°3 :\n-startDate and startLat filled, but empty endLong\n- endLat and endLong filled but empty endDate"); + createdFishingOperation = service.createFishingOperation(fishingOperation); + reloadedFishingOperation = service.getFishingOperation(createdFishingOperation.getId()); + assertEquals(fishingOperation.getGearShootingStartLatitude(), reloadedFishingOperation.getGearShootingStartLatitude()); + assertEquals(fishingOperation.getGearShootingStartLongitude(), reloadedFishingOperation.getGearShootingStartLongitude()); + assertNull(reloadedFishingOperation.getGearShootingEndDate()); + assertEquals(fishingOperation.getGearShootingEndLatitude(), reloadedFishingOperation.getGearShootingEndLatitude()); + assertEquals(fishingOperation.getGearShootingEndLongitude(), reloadedFishingOperation.getGearShootingEndLongitude()); + assertEquals(fishingOperation.getTrawlDistance(), reloadedFishingOperation.getTrawlDistance()); + assertEquals(fishingOperation.isFishingOperationRectiligne(), reloadedFishingOperation.isFishingOperationRectiligne()); + assertEquals(fishingOperation.getFishingOperationValid(), reloadedFishingOperation.getFishingOperationValid()); + + // ----------------------------------------------------------------------------- + // 4. Test : + // - + // ----------------------------------------------------------------------------- + fishingOperation.setId(null); + //createdFishingOperation = service.createFishingOperation(fishingOperation); + //reloadedFishingOperation = service.getFishingOperation(createdFishingOperation.getId()); + //assertEquals(fishingOperation.getGearShootingStartLatitude(), reloadedFishingOperation.getGearShootingStartLatitude()); + //assertEquals(fishingOperation.getGearShootingStartLongitude(), reloadedFishingOperation.getGearShootingStartLongitude()); + } @Test