This is an automated email from the git hooks/post-receive script. New commit to branch develop in repository observe. See http://git.codelutin.com/observe.git commit 7c2189f74e2fbae5a24bc62acfcc681ca8a1a68f Author: Sylvain Bavencoff <bavencoff@codelutin.com> Date: Fri Oct 9 08:46:55 2015 +0200 mise en place de la validation de DTO (refs #7591) --- observe-application-swing/pom.xml | 2 +- .../business/ObserveApplicationContext.java | 8 +- .../fr/ird/observe/business/gps/GpsPoints.java | 22 + .../fr/ird/observe/db/ObserveSwingDataSource.java | 13 + .../fr/ird/observe/ui/admin/AdminTabUIHandler.java | 2 +- .../java/fr/ird/observe/ui/admin/AdminUIModel.java | 4 +- .../ui/admin/validate/ValidateConfigUI.jaxx | 2 +- .../observe/ui/admin/validate/ValidateModel.java | 6 +- .../ui/admin/validate/ValidateUIHandler.java | 8 +- .../validation/ObserveSwingValidator.java | 2 +- .../validation/ValidationContext.java | 167 +------- .../validation/ValidationMessageDetector.java | 2 +- .../validation/ValidationModelMode.java | 2 +- .../validation/ValidationService.java | 7 +- .../{business => }/validation/ValidatorsMap.java | 2 +- .../dto/AbstractEspeceFieldDtoValidator.java | 295 ++++++++++++++ .../dto/ActivityDebutDePecheSaneDtoValidator.java | 205 ++++++++++ .../dto/ActivityFinDePecheSaneDtoValidator.java | 242 +++++++++++ .../dto/ActivityFinDeVeilleExistsDtoValidator.java | 185 +++++++++ .../dto/ActivitySimpleSpeedDtoValidator.java | 183 +++++++++ .../validator/dto/ActivitySpeedDtoValidator.java | 222 ++++++++++ .../dto/RouteActivitysFieldDtoValidator.java | 132 ++++++ .../dto/SetLonglineUniqueHomeIdDtoValidator.java | 103 +++++ .../dto/SetLonglineUniqueNumberDtoValidator.java | 99 +++++ .../dto/SpeciesLengthFieldDtoValidator.java | 34 +- .../dto/SpeciesWeightFieldDtoValidator.java | 34 +- .../dto/VesselActivityFieldDtoValidator.java | 451 +++++++++++++++++++++ .../seine/RouteDto-n1-create-error-validation.xml | 65 +++ .../RouteDto-n1-create-warning-validation.xml | 59 +++ .../seine/RouteDto-n1-update-error-validation.xml | 111 +++++ .../RouteDto-n1-update-warning-validation.xml | 116 ++++++ .../src/main/resources/validators.xml | 38 +- .../src/main/resources/validators.xml | 27 +- .../CollectionFieldExpressionValidator2.java | 2 +- .../validator}/CollectionUniqueKeyValidator2.java | 2 +- .../ObserveCollectionUniqueKeyValidator.java | 2 +- .../entities/AbstractEspeceFieldValidator.java | 295 ++++++++++++++ .../ActivityDebutDePecheSaneValidator.java | 199 +++++++++ .../entities/ActivityFinDePecheSaneValidator.java | 237 +++++++++++ .../ActivityFinDeVeilleExistsValidator.java | 185 +++++++++ .../entities/ActivitySimpleSpeedValidator.java | 183 +++++++++ .../validator/entities/ActivitySpeedValidator.java | 222 ++++++++++ .../entities/RouteActivitysFieldValidator.java | 135 ++++++ .../entities/SetLonglineUniqueHomeIdValidator.java | 102 +++++ .../entities/SetLonglineUniqueNumberValidator.java | 102 +++++ .../entities/SpeciesLengthFieldValidator.java} | 34 +- .../entities/SpeciesWeightFieldValidator.java} | 34 +- .../entities/VesselActivityFieldValidator.java | 446 ++++++++++++++++++++ .../entities/ActivitySeineSpeedValidatorTest.java | 121 ++++++ 49 files changed, 4879 insertions(+), 272 deletions(-) diff --git a/observe-application-swing/pom.xml b/observe-application-swing/pom.xml index 2577602..2cce4bd 100644 --- a/observe-application-swing/pom.xml +++ b/observe-application-swing/pom.xml @@ -46,7 +46,7 @@ <jaxx.autoImportCss>true</jaxx.autoImportCss> <jaxx.autoRecurseInCss>false</jaxx.autoRecurseInCss> <jaxx.validatorFactoryFQN> - fr.ird.observe.business.validation.ObserveSwingValidator + fr.ird.observe.validation.ObserveSwingValidator </jaxx.validatorFactoryFQN> <jaxx.commonCss> ${project.basedir}/src/main/java/fr/ird/observe/ui/ObserveCommon.css diff --git a/observe-application-swing/src/main/java/fr/ird/observe/business/ObserveApplicationContext.java b/observe-application-swing/src/main/java/fr/ird/observe/business/ObserveApplicationContext.java index 96e6a86..aa94cdd 100644 --- a/observe-application-swing/src/main/java/fr/ird/observe/business/ObserveApplicationContext.java +++ b/observe-application-swing/src/main/java/fr/ird/observe/business/ObserveApplicationContext.java @@ -21,12 +21,12 @@ */ package fr.ird.observe.business; -import fr.ird.observe.business.validation.ObserveSwingValidator; +import fr.ird.observe.validation.ObserveSwingValidator; import fr.ird.observe.configuration.ObserveSwingApplicationConfig; import fr.ird.observe.business.db.DataContext; import fr.ird.observe.business.gps.GPSService; -import fr.ird.observe.business.validation.ValidationContext; +import fr.ird.observe.validation.ValidationContext; import fr.ird.observe.db.ObserveSwingDataSource; import fr.ird.observe.services.dto.constants.ReferentialLocale; import fr.ird.observe.ui.DecoratorService; @@ -215,8 +215,8 @@ public class ObserveApplicationContext extends DefaultApplicationContext { if (getDataSource() != null) { setDataSource(null); } - - getValidationContext().closeDataSource(); + // FIXME +// getValidationContext().closeDataSource(); // fermeture des services de persistances ouverts //FIXME diff --git a/observe-application-swing/src/main/java/fr/ird/observe/business/gps/GpsPoints.java b/observe-application-swing/src/main/java/fr/ird/observe/business/gps/GpsPoints.java index 6434ccd..1aaa45a 100644 --- a/observe-application-swing/src/main/java/fr/ird/observe/business/gps/GpsPoints.java +++ b/observe-application-swing/src/main/java/fr/ird/observe/business/gps/GpsPoints.java @@ -23,6 +23,7 @@ package fr.ird.observe.business.gps; */ import fr.ird.observe.services.dto.seine.ActivitySeineDto; +import fr.ird.observe.services.dto.seine.ActivitySeineStubDto; import fr.ird.observe.services.dto.seine.RouteDto; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -70,6 +71,27 @@ public class GpsPoints { } + /** + * Construit un point à partir de l'entité donnée. + * + * @param route la route qui contient le jour + * @param activity l'activite qui contient l'heure et la position géographique + * @return le nouveau point instancié + * @since 3.8 + */ + public static GPSPoint newPoint(RouteDto route, ActivitySeineStubDto activity) { + + Date currentTime = DateUtil.getDateAndTime(route.getDate(), activity.getTime(), false, false); + + GPSPoint gpsPoint = new GPSPointImpl(); + gpsPoint.setTime(currentTime); + gpsPoint.setLatitude(activity.getLatitude()); + gpsPoint.setLongitude(activity.getLongitude()); + + return gpsPoint; + + } + /** * Calcule la distance entre deux points (en kilometres). diff --git a/observe-application-swing/src/main/java/fr/ird/observe/db/ObserveSwingDataSource.java b/observe-application-swing/src/main/java/fr/ird/observe/db/ObserveSwingDataSource.java index 79b781c..0654765 100644 --- a/observe-application-swing/src/main/java/fr/ird/observe/db/ObserveSwingDataSource.java +++ b/observe-application-swing/src/main/java/fr/ird/observe/db/ObserveSwingDataSource.java @@ -17,6 +17,7 @@ import fr.ird.observe.services.configuration.ObserveDataSourceConnection; import fr.ird.observe.services.configuration.ObserveDataSourceInformation; import fr.ird.observe.services.dto.DataSourceCreateConfigurationDto; import fr.ird.observe.services.dto.DataSourceCreateWithNoReferentialImportException; +import fr.ird.observe.services.dto.IdDto; import fr.ird.observe.services.dto.IncompatibleDataSourceCreateConfigurationException; import fr.ird.observe.services.dto.ObserveDbUserDto; import fr.ird.observe.services.dto.constants.ReferentialLocale; @@ -192,6 +193,18 @@ public class ObserveSwingDataSource extends AbstractSerializableBean { dataSourceService.applySecurity(users); } + + + public <D extends IdDto> D getObserveDto(Class<D> dtoType, String id) { + Preconditions.checkState(isOpen(), "Connection is not open"); + + DataSourceService dataSourceService = newService(DataSourceService.class); + + D result = dataSourceService.getObserveDto(dtoType, id); + + return result; + } + public void migrateData(ObserveDataSourceInformation dataSourceInformation, Version targetVersion) throws DatabaseConnexionNotAuthorizedException, DatabaseNotFoundException { Preconditions.checkState(!isOpen(), "Connection is open"); diff --git a/observe-application-swing/src/main/java/fr/ird/observe/ui/admin/AdminTabUIHandler.java b/observe-application-swing/src/main/java/fr/ird/observe/ui/admin/AdminTabUIHandler.java index 586f716..994bfe4 100644 --- a/observe-application-swing/src/main/java/fr/ird/observe/ui/admin/AdminTabUIHandler.java +++ b/observe-application-swing/src/main/java/fr/ird/observe/ui/admin/AdminTabUIHandler.java @@ -28,7 +28,7 @@ import fr.ird.observe.business.SendMessageAble; import fr.ird.observe.business.gps.GPSService; -import fr.ird.observe.business.validation.ValidationService; +import fr.ird.observe.validation.ValidationService; import fr.ird.observe.db.ObserveSwingDataSource; import fr.ird.observe.services.service.BabModelVersionException; import fr.ird.observe.services.service.DatabaseConnexionNotAuthorizedException; diff --git a/observe-application-swing/src/main/java/fr/ird/observe/ui/admin/AdminUIModel.java b/observe-application-swing/src/main/java/fr/ird/observe/ui/admin/AdminUIModel.java index d935954..1316db6 100644 --- a/observe-application-swing/src/main/java/fr/ird/observe/ui/admin/AdminUIModel.java +++ b/observe-application-swing/src/main/java/fr/ird/observe/ui/admin/AdminUIModel.java @@ -22,8 +22,8 @@ package fr.ird.observe.ui.admin; import fr.ird.observe.business.report.model.Report; -import fr.ird.observe.business.validation.ValidationModelMode; -import fr.ird.observe.business.validation.ValidatorsMap; +import fr.ird.observe.validation.ValidationModelMode; +import fr.ird.observe.validation.ValidatorsMap; import fr.ird.observe.configuration.ObserveSwingApplicationConfig; import fr.ird.observe.db.ObserveSwingDataSource; import fr.ird.observe.db.constantes.DbMode; diff --git a/observe-application-swing/src/main/java/fr/ird/observe/ui/admin/validate/ValidateConfigUI.jaxx b/observe-application-swing/src/main/java/fr/ird/observe/ui/admin/validate/ValidateConfigUI.jaxx index b71b533..02f0e06 100644 --- a/observe-application-swing/src/main/java/fr/ird/observe/ui/admin/validate/ValidateConfigUI.jaxx +++ b/observe-application-swing/src/main/java/fr/ird/observe/ui/admin/validate/ValidateConfigUI.jaxx @@ -28,7 +28,7 @@ <import> fr.ird.observe.configuration.ObserveSwingApplicationConfig fr.ird.observe.ui.admin.AdminUIModel - fr.ird.observe.business.validation.ValidationModelMode + fr.ird.observe.validation.ValidationModelMode org.nuiton.validator.NuitonValidatorScope diff --git a/observe-application-swing/src/main/java/fr/ird/observe/ui/admin/validate/ValidateModel.java b/observe-application-swing/src/main/java/fr/ird/observe/ui/admin/validate/ValidateModel.java index bbef147..787b1cf 100644 --- a/observe-application-swing/src/main/java/fr/ird/observe/ui/admin/validate/ValidateModel.java +++ b/observe-application-swing/src/main/java/fr/ird/observe/ui/admin/validate/ValidateModel.java @@ -22,9 +22,9 @@ package fr.ird.observe.ui.admin.validate; import fr.ird.observe.configuration.ObserveSwingApplicationConfig; -import fr.ird.observe.business.validation.ValidationModelMode; -import fr.ird.observe.business.validation.ValidationService; -import fr.ird.observe.business.validation.ValidatorsMap; +import fr.ird.observe.validation.ValidationModelMode; +import fr.ird.observe.validation.ValidationService; +import fr.ird.observe.validation.ValidatorsMap; import fr.ird.observe.ui.admin.AdminActionModel; import fr.ird.observe.ui.admin.AdminStep; import org.apache.commons.logging.Log; diff --git a/observe-application-swing/src/main/java/fr/ird/observe/ui/admin/validate/ValidateUIHandler.java b/observe-application-swing/src/main/java/fr/ird/observe/ui/admin/validate/ValidateUIHandler.java index e5cbec6..1b9657b 100644 --- a/observe-application-swing/src/main/java/fr/ird/observe/ui/admin/validate/ValidateUIHandler.java +++ b/observe-application-swing/src/main/java/fr/ird/observe/ui/admin/validate/ValidateUIHandler.java @@ -24,10 +24,10 @@ package fr.ird.observe.ui.admin.validate; import com.google.common.base.Charsets; import fr.ird.observe.ObserveServiceHelper; import fr.ird.observe.ui.DecoratorService; -import fr.ird.observe.business.validation.ValidationContext; -import fr.ird.observe.business.validation.ValidationMessageDetector; -import fr.ird.observe.business.validation.ValidationModelMode; -import fr.ird.observe.business.validation.ValidatorsMap; +import fr.ird.observe.validation.ValidationContext; +import fr.ird.observe.validation.ValidationMessageDetector; +import fr.ird.observe.validation.ValidationModelMode; +import fr.ird.observe.validation.ValidatorsMap; import fr.ird.observe.db.ObserveSwingDataSource; import fr.ird.observe.services.dto.referential.ProgramDto; import fr.ird.observe.services.dto.seine.TripSeineDto; diff --git a/observe-application-swing/src/main/java/fr/ird/observe/business/validation/ObserveSwingValidator.java b/observe-application-swing/src/main/java/fr/ird/observe/validation/ObserveSwingValidator.java similarity index 99% rename from observe-application-swing/src/main/java/fr/ird/observe/business/validation/ObserveSwingValidator.java rename to observe-application-swing/src/main/java/fr/ird/observe/validation/ObserveSwingValidator.java index ae36b4c..c1fee69 100644 --- a/observe-application-swing/src/main/java/fr/ird/observe/business/validation/ObserveSwingValidator.java +++ b/observe-application-swing/src/main/java/fr/ird/observe/validation/ObserveSwingValidator.java @@ -19,7 +19,7 @@ * <http://www.gnu.org/licenses/gpl-3.0.html>. * #L% */ -package fr.ird.observe.business.validation; +package fr.ird.observe.validation; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.util.ValueStack; diff --git a/observe-application-swing/src/main/java/fr/ird/observe/business/validation/ValidationContext.java b/observe-application-swing/src/main/java/fr/ird/observe/validation/ValidationContext.java similarity index 52% rename from observe-application-swing/src/main/java/fr/ird/observe/business/validation/ValidationContext.java rename to observe-application-swing/src/main/java/fr/ird/observe/validation/ValidationContext.java index 0efb9b6..e71e7f2 100644 --- a/observe-application-swing/src/main/java/fr/ird/observe/business/validation/ValidationContext.java +++ b/observe-application-swing/src/main/java/fr/ird/observe/validation/ValidationContext.java @@ -19,12 +19,12 @@ * <http://www.gnu.org/licenses/gpl-3.0.html>. * #L% */ -package fr.ird.observe.business.validation; +package fr.ird.observe.validation; +import fr.ird.observe.ObserveSwingApplicationContext; import fr.ird.observe.business.db.DataContext; - import fr.ird.observe.db.ObserveSwingDataSource; -import fr.ird.observe.services.dto.AbstractObserveDto; +import fr.ird.observe.services.dto.IdDto; import fr.ird.observe.services.dto.longline.ActivityLonglineDto; import fr.ird.observe.services.dto.longline.SetLonglineDto; import fr.ird.observe.services.dto.longline.TripLonglineDto; @@ -53,11 +53,6 @@ public class ValidationContext { public static final String VALIDATION_TRANSACTION_NAME = "validation"; - protected ObserveSwingDataSource dataSource; - - //FIXME -// protected TopiaContext tx; - protected DataContext dataContext; protected Map<String, Object> cache; @@ -74,15 +69,13 @@ public class ValidationContext { public void cleanCache() { getCache().clear(); referentielList = null; - cleanTransaction(); } public ObserveSwingDataSource getDataSource() { - return dataSource; + return ObserveSwingApplicationContext.get().getDataSource(); } public void close() { - closeDataSource(); dataContext = null; } @@ -92,59 +85,10 @@ public class ValidationContext { close(); } - public void closeDataSource() { - closeTransaction(); - dataSource = null; - } - - protected void closeTransaction() { - //FIXME -// if (tx != null) { -// if (log.isDebugEnabled()) { -// log.debug("close 'validation' transaction"); -// } -// try { -// dataSource.closeTransaction(tx, VALIDATION_TRANSACTION_NAME); -// } catch (DataSourceException e) { -// if (log.isErrorEnabled()) { -// log.error("Could not close transaction", e); -// } -// } finally { -// tx = null; -// } -// } - } - - protected void cleanTransaction() { - //FIXME -// if (tx != null) { -// if (log.isDebugEnabled()) { -// log.debug("clean 'validation' transaction"); -// } -// try { -// dataSource.rollbackTransaction(tx, VALIDATION_TRANSACTION_NAME); -// } catch (DataSourceException e) { -// if (log.isErrorEnabled()) { -// log.error("Could not clean transaction", e); -// } -// } -// } - } - public DataContext getDataContext() { return dataContext; } - public void setDataSource(ObserveSwingDataSource dataSource) { - if (this.dataSource != null) { - closeDataSource(); - } - if (log.isDebugEnabled()) { - log.debug("Attach data source " + (dataSource == null ? "null" : dataSource.getLabel())); - } - this.dataSource = dataSource; - } - public void setDataContext(DataContext dataContext) { if (log.isInfoEnabled()) { log.info("Attach data context " + dataContext); @@ -153,23 +97,6 @@ public class ValidationContext { ObserveSwingValidator.reloadDataContext(this, false); } - //FIXME -// public Trip getCurrentTrip() { -// -// Trip result = null; -// -// String selectedTripId = dataContext.getSelectedTripId(); -// if (selectedTripId != null) { -// if (selectedTripId.contains("Seine")) { -// result = getCurrentTripSeine(); -// } else { -// result = getCurrentTripLongline(); -// } -// } -// return result; -// -// } - public TripSeineDto getCurrentTripSeine() { TripSeineDto result = getDto(TripSeineDto.class, dataContext.getSelectedTripId()); return result; @@ -185,23 +112,6 @@ public class ValidationContext { return result; } - //FIXME -// public Activity getCurrentActivity() { -// -// Activity result = null; -// -// String selectedActivityId = dataContext.getSelectedActivityId(); -// if (selectedActivityId != null) { -// if (selectedActivityId.contains("Seine")) { -// result = getCurrentActivitySeine(); -// } else { -// result = getCurrentActivityLongline(); -// } -// } -// return result; -// -// } - public ActivitySeineDto getCurrentActivitySeine() { ActivitySeineDto result = getDto(ActivitySeineDto.class, dataContext.getSelectedActivityId()); return result; @@ -212,23 +122,6 @@ public class ValidationContext { return result; } - //FIXME -// public Set getCurrentSet() { -// -// Set result = null; -// -// String selectedSetId = dataContext.getSelectedSetId(); -// if (selectedSetId != null) { -// if (selectedSetId.contains("Seine")) { -// result = getCurrentSetSeine(); -// } else { -// result = getCurrentSetLongline(); -// } -// } -// return result; -// -// } - public SetSeineDto getCurrentSetSeine() { SetSeineDto result = getDto(SetSeineDto.class, dataContext.getSelectedSetId()); return result; @@ -255,51 +148,27 @@ public class ValidationContext { this.referentielList = referentielList; } - //FIXME -// public TopiaContext getTx() { -// if (tx == null) { -// if (dataSource != null) { -// if (log.isInfoEnabled()) { -// log.info("Open a new transaction " + tx); -// } -// tx = dataSource.beginTransaction(VALIDATION_TRANSACTION_NAME); -// } -// } -// return tx; -// } + public <D extends IdDto> D getDto(Class<D> dtoType, String id) { - public <E extends AbstractObserveDto> E getDto(Class<E> klass, String id) { - - if (dataSource == null || dataContext == null || !dataSource.isOpen() || id == null) { - return null; - } Object o = getCache().get(id); if (o != null) { if (log.isDebugEnabled()) { log.debug("Use cached entity : " + id); } // found in cache - return (E) o; + return (D) o; } - //FIXME -// try { -// TopiaContext tx = getTx(); -// if (tx == null) { -// return null; -// } -// TopiaDAO<E> dao = dataSource.getDAO(tx, klass); -// E result = dao.findByTopiaId(id); -// if (log.isInfoEnabled()) { -// log.info("Put entity into cache : " + id); -// } -// getCache().put(id, result); -// return result; -// } catch (Exception e) { -// if (log.isErrorEnabled()) { -// log.error("Could not obtain " + id, e); -// } -// return null; -// } - return null; + + D result = getDataSource().getObserveDto(dtoType, id); + + if (result != null) { + if (log.isInfoEnabled()) { + log.info("Put entity into cache : " + id); + } + getCache().put(id, result); + + } + + return result; } } diff --git a/observe-application-swing/src/main/java/fr/ird/observe/business/validation/ValidationMessageDetector.java b/observe-application-swing/src/main/java/fr/ird/observe/validation/ValidationMessageDetector.java similarity index 99% rename from observe-application-swing/src/main/java/fr/ird/observe/business/validation/ValidationMessageDetector.java rename to observe-application-swing/src/main/java/fr/ird/observe/validation/ValidationMessageDetector.java index 0898862..1f57065 100644 --- a/observe-application-swing/src/main/java/fr/ird/observe/business/validation/ValidationMessageDetector.java +++ b/observe-application-swing/src/main/java/fr/ird/observe/validation/ValidationMessageDetector.java @@ -19,7 +19,7 @@ * <http://www.gnu.org/licenses/gpl-3.0.html>. * #L% */ -package fr.ird.observe.business.validation; +package fr.ird.observe.validation; import fr.ird.observe.ObserveServiceHelper; import fr.ird.observe.business.db.DataContext; diff --git a/observe-application-swing/src/main/java/fr/ird/observe/business/validation/ValidationModelMode.java b/observe-application-swing/src/main/java/fr/ird/observe/validation/ValidationModelMode.java similarity index 98% rename from observe-application-swing/src/main/java/fr/ird/observe/business/validation/ValidationModelMode.java rename to observe-application-swing/src/main/java/fr/ird/observe/validation/ValidationModelMode.java index c9e3fb4..a256abe 100644 --- a/observe-application-swing/src/main/java/fr/ird/observe/business/validation/ValidationModelMode.java +++ b/observe-application-swing/src/main/java/fr/ird/observe/validation/ValidationModelMode.java @@ -19,7 +19,7 @@ * <http://www.gnu.org/licenses/gpl-3.0.html>. * #L% */ -package fr.ird.observe.business.validation; +package fr.ird.observe.validation; import static org.nuiton.i18n.I18n.n; diff --git a/observe-application-swing/src/main/java/fr/ird/observe/business/validation/ValidationService.java b/observe-application-swing/src/main/java/fr/ird/observe/validation/ValidationService.java similarity index 97% rename from observe-application-swing/src/main/java/fr/ird/observe/business/validation/ValidationService.java rename to observe-application-swing/src/main/java/fr/ird/observe/validation/ValidationService.java index bba633e..8500d46 100644 --- a/observe-application-swing/src/main/java/fr/ird/observe/business/validation/ValidationService.java +++ b/observe-application-swing/src/main/java/fr/ird/observe/validation/ValidationService.java @@ -19,9 +19,10 @@ * <http://www.gnu.org/licenses/gpl-3.0.html>. * #L% */ -package fr.ird.observe.business.validation; +package fr.ird.observe.validation; import fr.ird.observe.services.dto.AbstractObserveDto; +import fr.ird.observe.services.dto.IdDto; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -104,13 +105,13 @@ public class ValidationService { * * @param contextName le lastName du context de validation * @param scopes les scopes autorisés - * @param entities les entités + * @param dtos les entités * @return le dictionnaire des validateurs par type d'entité. */ public ValidatorsMap getValidators( String contextName, NuitonValidatorScope[] scopes, - AbstractObserveDto... dtos) { + IdDto... dtos) { //FIXME Set<Class<? extends AbstractObserveDto>> types = null; diff --git a/observe-application-swing/src/main/java/fr/ird/observe/business/validation/ValidatorsMap.java b/observe-application-swing/src/main/java/fr/ird/observe/validation/ValidatorsMap.java similarity index 98% rename from observe-application-swing/src/main/java/fr/ird/observe/business/validation/ValidatorsMap.java rename to observe-application-swing/src/main/java/fr/ird/observe/validation/ValidatorsMap.java index b040f4c..c4f1a03 100644 --- a/observe-application-swing/src/main/java/fr/ird/observe/business/validation/ValidatorsMap.java +++ b/observe-application-swing/src/main/java/fr/ird/observe/validation/ValidatorsMap.java @@ -19,7 +19,7 @@ * <http://www.gnu.org/licenses/gpl-3.0.html>. * #L% */ -package fr.ird.observe.business.validation; +package fr.ird.observe.validation; import org.nuiton.validator.NuitonValidatorScope; import org.nuiton.validator.bean.simple.SimpleBeanValidator; diff --git a/observe-application-swing/src/main/java/fr/ird/observe/validation/validator/dto/AbstractEspeceFieldDtoValidator.java b/observe-application-swing/src/main/java/fr/ird/observe/validation/validator/dto/AbstractEspeceFieldDtoValidator.java new file mode 100644 index 0000000..fd4eaaa --- /dev/null +++ b/observe-application-swing/src/main/java/fr/ird/observe/validation/validator/dto/AbstractEspeceFieldDtoValidator.java @@ -0,0 +1,295 @@ +package fr.ird.observe.validation.validator.dto; + +/* + * #%L + * ObServe :: Validation + * %% + * Copyright (C) 2008 - 2013 IRD, Codelutin, Tony Chemit + * %% + * 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.opensymphony.xwork2.util.ValueStack; +import com.opensymphony.xwork2.validator.ValidationException; +import com.opensymphony.xwork2.validator.validators.FieldValidatorSupport; +import fr.ird.observe.services.dto.referential.SpeciesDto; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * <!-- START SNIPPET: javadoc --> + * Ce validateur verifie qu'une espece respece bien les tailles ou + * les poids définis par les bornes de l'espece : + * <ul> + * <li>minLength</li> + * <li>maxLength</li> + * <li>minWeight</li> + * <li>maxWeight</li> + * </ul> + * <p/> + * Lorsqu'il s'agit d'une espece faune, si aucune borne n'est trouvée, alors + * on se base sur les bornes définis dans son groupe d'espece (si il est défini). + * <p/> + * Le paramètre {@link #ratio} permet de spécifier une marge à appliquer sur + * les bornes, il s'agit d'un pourcentage décimal. + * <p/> + * Example : si ratio = 10, alors on utilise les bornes suivantes : + * <pre> + * bMin -10% et bMax + 10% + * </pre> + * <!-- END SNIPPET: javadoc --> + * + * @author Tony Chemit - chemit@codelutin.com + * @since 1.5 + */ +public abstract class AbstractEspeceFieldDtoValidator extends FieldValidatorSupport { + + /** Logger. */ + private static final Log log = + LogFactory.getLog(AbstractEspeceFieldDtoValidator.class); + + public static class Bound { + + private Float min; + + private Float max; + + Bound(Float min, Float max) { + this.min = min; + this.max = max; + } + + public Float getMin() { + return min; + } + + public Float getMax() { + return max; + } + + public Bound applyRatio(float ratio) { + float delta = min / 100 * ratio; + float min = this.min - delta; + if (min < 0) { + min = 0f; + } + delta = max / 100 * ratio; + float max = this.max + delta; + return new Bound(min, max); + } + + @Override + public String toString() { + return super.toString() + '<' + min + ',' + max + '>'; + } + } + + /** + * la stack de validation interceptée lors de la création du validateur. + * <p/> + * Utilisée pour pousser des données dans le context. + */ + protected ValueStack valueStack; + + /** le ratio a appliquer sur les bornes définies dans le référentiel */ + protected Float ratio; + + /** + * Une expression qui si elle est remplie doit être vérifié avant de faire + * la validation par borne, si l'expression n'est pas vérifiée, alors + * le test sur les borne n'est pas effectué. + * + * @since 2.3 + */ + protected String expression; + + protected String speciesField = "espece"; + + public ValueStack getValueStack() { + return valueStack; + } + + public String getSpeciesField() { + return speciesField; + } + + @Override + public void setValueStack(ValueStack valueStack) { + this.valueStack = valueStack; + super.setValueStack(valueStack); + } + + public void setSpeciesField(String speciesField) { + this.speciesField = speciesField; + } + + public void setRatio(float ratio) { + this.ratio = ratio; + } + + public void setExpression(String expression) { + this.expression = expression; + } + + protected abstract Float getBoundMin(SpeciesDto referentiel); + + protected abstract Float getBoundMax(SpeciesDto referentiel); + + protected boolean shouldValidate(Object object) throws ValidationException { + Object obj = null; + Boolean answer; + if (StringUtils.isNotEmpty(expression)) { + try { + obj = getFieldValue(expression, object); + } catch (ValidationException e) { + throw e; + } catch (Exception e) { + // let this pass, but it will be logged right below + } + + if (obj != null && obj instanceof Boolean) { + answer = (Boolean) obj; + } else { + answer = false; + if (log.isWarnEnabled()) { + log.warn("Got result of " + obj + + " when trying to get Boolean with expression [" + + expression + "]."); + } + } + } else { + + // no pre-expression, always wants to validate + answer = true; + } + + return answer; + } + + @Override + public void validate(Object object) throws ValidationException { + + if (ratio == null) { + throw new ValidationException("No parameter 'ratio' filled"); + } + + String fieldName = getFieldName(); + if (fieldName == null) { + throw new ValidationException("No parameter 'fieldName' filled"); + } + + String speciesFieldName = getSpeciesField(); + if (speciesFieldName == null) { + throw new ValidationException("No parameter 'speciesFieldName' filled"); + } + + boolean shouldValidate = shouldValidate(object); + + if (!shouldValidate) { + return; + } + + // la donnee a valider + Object value = getFieldValue(fieldName, object); + Float data = value == null ? null : Float.valueOf(String.valueOf(value)); + + if (data == null) { + // la donnee a valider n'est pas définie + return; + } + + if (log.isDebugEnabled()) { + log.debug("data to validate : " + data); + } + + // l'species associée + SpeciesDto species = (SpeciesDto) getFieldValue(speciesFieldName, object); + + if (species == null) { + + // pas de species trouvée, on ne peut pas valider + return; + } + + if (log.isDebugEnabled()) { + log.debug("Espece to validate : " + species); + } + + Bound bound = getBound(species); + + if (log.isDebugEnabled()) { + log.debug("Espece Bound to validate : " + bound); + } + + if (bound == null) { + + // pas de donnée dans le référentiel acceptable + return; + } + + Bound boundWithRatio = bound.applyRatio(ratio); + + if (log.isInfoEnabled()) { + log.info("Bound : " + bound); + log.info("Ratio to validate : " + ratio); + log.info("Bound with ratio : " + boundWithRatio); + } + + boolean valid = validateBound(data, boundWithRatio); + + if (!valid) { + + valueStack.push(bound); + + try { + addFieldError(fieldName, object); + } finally { + valueStack.pop(); + } + } + } + + protected Bound getBound(SpeciesDto referentiel) { + + Float min = getBoundMin(referentiel); + Float max = getBoundMax(referentiel); + + if (min == null || min == 0 || max == null || max == 0) { + // l'une des deux borne n'est pas définie, on ne peut pas utiliser + // la données + return null; + } + return new Bound(min, max); + } + + protected boolean validateBound(Float value, + Bound bound) { + if (value == null) { + + // valeur non définie + return true; + } + boolean valid; + + float min = bound.getMin(); + float max = bound.getMax(); + + valid = min <= value && value <= max; + return valid; + } + +} diff --git a/observe-application-swing/src/main/java/fr/ird/observe/validation/validator/dto/ActivityDebutDePecheSaneDtoValidator.java b/observe-application-swing/src/main/java/fr/ird/observe/validation/validator/dto/ActivityDebutDePecheSaneDtoValidator.java new file mode 100644 index 0000000..f31fe9c --- /dev/null +++ b/observe-application-swing/src/main/java/fr/ird/observe/validation/validator/dto/ActivityDebutDePecheSaneDtoValidator.java @@ -0,0 +1,205 @@ +package fr.ird.observe.validation.validator.dto; + +/* + * #%L + * ObServe :: Validation + * %% + * Copyright (C) 2008 - 2013 IRD, Codelutin, Tony Chemit + * %% + * 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.opensymphony.xwork2.util.ValueStack; +import com.opensymphony.xwork2.validator.ValidationException; +import com.opensymphony.xwork2.validator.validators.FieldValidatorSupport; +import fr.ird.observe.services.dto.seine.ActivitySeineDto; +import fr.ird.observe.services.dto.seine.RouteDto; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.util.Date; + +/** + * <!-- START SNIPPET: javadoc --> ActivityDebutDePecheSaneValidator vérifie que + * que l'utilisation d'une activity de début de calée est possible. + * <p/> + * On peut utiliser une activité de ce type uniquement si il n'existe pas déjà + * une telle activité de calée positive et qui n'est pas suivie d'une activité + * de fin de veille. <!-- END SNIPPET: javadoc + * --> + * <p/> + * <p/> + * <!-- START SNIPPET: parameters --> <ul> <li>fieldName - The field name this + * validator is validating. Required if using Plain-Validator Syntax otherwise + * not required</li> </ul> <!-- END SNIPPET: parameters --> + * <p/> + * <pre> + * <!-- START SNIPPET: examples --> + * <validators> + * <!-- Plain-Validator Syntax --> + * <validator type="invalidLochMatin"> + * <param name="fieldName">startLogValue</param> + * <message>loch matin must be greater or equals to last + * closed route loch soir</message> + * </validator> + * <p/> + * <!-- Field-Validator Syntax --> + * <field name="startLogValue"> + * <field-validator type="invalidLochMatin"> + * <message>loch matin must be greater or equals to last + * closed route loch soir</message> + * </field-validator> + * </field> + * </validators> + * <!-- END SNIPPET: examples --> + * </pre> + * + * @author Tony Chemit - chemit@codelutin.com + * @since 1.5 + */ +public class ActivityDebutDePecheSaneDtoValidator extends FieldValidatorSupport { + + /** Logger. */ + private static final Log log = + LogFactory.getLog(ActivityDebutDePecheSaneDtoValidator.class); + + private ValueStack stack; + + @Override + public String getValidatorType() { + return "activityDebutDePecheSane"; + } + + @Override + public void setValueStack(ValueStack stack) { + this.stack = stack; + super.setValueStack(stack); + } + + @Override + public void validate(Object object) throws ValidationException { + + if (object == null) { + + // pas d'objet, donc rien a faire + return; + } + + ActivitySeineDto activitySeine = (ActivitySeineDto) object; + + // FIXME migration client-serveur +// if (!activitySeine.isSetOperation()) { +// +// // rien a valider +// return; +// } + + if (activitySeine.getTime() == null) { + + // heure d'obsersation non encore positionne, on ne peut pas valider + return; + } + + // l'activity est une activite de début de pêche + // on doit vérifier qu'il n'existe pas déjà une autre telle + // activité (de caléé positive) qui n'est pas suivi d'une activité + // de fin de pêche + + RouteDto route = (RouteDto) stack.findValue("routeEntity"); + if (route == null) { + + if (log.isWarnEnabled()) { + log.warn("COULD NOT FIND DATA CONTEXT! [routeEntity]"); + } + return; + } + + boolean valid; + + if (activitySeine.getId() == null) { + + // activity en creation + valid = checkCreateMode(route, activitySeine); + + } else { + + // activity en mise a jour + valid = checkUpdateMode(route, activitySeine); + } + + if (!valid) { + + addError(object); + } + } + + protected boolean checkCreateMode(RouteDto route, ActivitySeineDto activitySeine) { + + Date currentTime = activitySeine.getTime(); + + // recuperation de l'activity de debut de peche juste avant la nouvelle + // activity + // FIXME migration client-serveur +// ActivitySeineDto openSet = +// ActivitySeineDtos.getLastActivityDebutDePechePositiveBefore(route, currentTime); + ActivitySeineDto openSet = null; + + if (openSet == null) { + + // pas de peche positive avant la nouvelle activity + // on autorise donc celle-ci + return true; + } + + // on cherche la fin de pêche associée à l'actitivé retenue + // FIXME migration client-serveur +// ActivitySeineDto closeSet = +// ActivitySeineDtos.getNextActivityFinDePeche(route, openSet); + ActivitySeineDto closeSet = null; + + return closeSet != null && + currentTime.after(closeSet.getTime()); + } + + protected boolean checkUpdateMode(RouteDto route, ActivitySeineDto activitySeine) { + + // on recupere l'activity de fermeture de l'activite de peche + // FIXME migration client-serveur +// ActivitySeineDto closeSet = +// ActivitySeineDtos.getNextActivityFinDePeche(route, activitySeine); + ActivitySeineDto closeSet = null; + + if (closeSet == null) { + // pas d'activity de fin, cela est possible ? + return true; + } + + Date currentTime = activitySeine.getTime(); + + // on doit vérifier que l'heure du debut de set n'est pas apres la fin + return !currentTime.after(closeSet.getTime()); + } + + protected void addError(Object object) { + // la set n'est pas fermee ou bien on veut inserer le debut de peche + // avant la fermeture d'une autre peche ce qui n'est pas possible + String fieldName = getFieldName(); + if (log.isInfoEnabled()) { + log.info("not valid , fieldName : " + fieldName); + } + addFieldError(fieldName, object); + } +} diff --git a/observe-application-swing/src/main/java/fr/ird/observe/validation/validator/dto/ActivityFinDePecheSaneDtoValidator.java b/observe-application-swing/src/main/java/fr/ird/observe/validation/validator/dto/ActivityFinDePecheSaneDtoValidator.java new file mode 100644 index 0000000..f83f48f --- /dev/null +++ b/observe-application-swing/src/main/java/fr/ird/observe/validation/validator/dto/ActivityFinDePecheSaneDtoValidator.java @@ -0,0 +1,242 @@ +package fr.ird.observe.validation.validator.dto; + +/* + * #%L + * ObServe :: Validation + * %% + * Copyright (C) 2008 - 2013 IRD, Codelutin, Tony Chemit + * %% + * 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.opensymphony.xwork2.util.ValueStack; +import com.opensymphony.xwork2.validator.ValidationException; +import com.opensymphony.xwork2.validator.validators.FieldValidatorSupport; +import fr.ird.observe.services.dto.seine.ActivitySeineDto; +import fr.ird.observe.services.dto.seine.RouteDto; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.util.Date; + +/** + * <!-- START SNIPPET: javadoc --> ActivityFinDePecheSaneValidator vérifie que + * que l'utilisation d'une activity de fin de pêche est requise ou non. + * <p/> + * On peut utiliser une activité de ce type uniquement si il existe déjà + * une activité de calée positive et sans activity de fin de pêche. + * <!-- END SNIPPET: javadoc --> + * <p/> + * <p/> + * <!-- START SNIPPET: parameters --> <ul> <li>fieldName - The field name this + * validator is validating. Required if using Plain-Validator Syntax otherwise + * not required</li> </ul> <!-- END SNIPPET: parameters --> + * <p/> + * <pre> + * <!-- START SNIPPET: examples --> + * <validators> + * <!-- Plain-Validator Syntax --> + * <validator type="invalidLochMatin"> + * <param name="fieldName">startLogValue</param> + * <message>loch matin must be greater or equals to last + * closed route loch soir</message> + * </validator> + * <p/> + * <!-- Field-Validator Syntax --> + * <field name="startLogValue"> + * <field-validator type="invalidLochMatin"> + * <message>loch matin must be greater or equals to last + * closed route loch soir</message> + * </field-validator> + * </field> + * </validators> + * <!-- END SNIPPET: examples --> + * </pre> + * + * @author Tony Chemit - chemit@codelutin.com + * @since 1.5 + */ +public class ActivityFinDePecheSaneDtoValidator extends FieldValidatorSupport { + + /** Logger. */ + private static final Log log = + LogFactory.getLog(ActivityFinDePecheSaneDtoValidator.class); + + private ValueStack stack; + + @Override + public String getValidatorType() { + return "activityFinDePecheSane"; + } + + @Override + public void setValueStack(ValueStack stack) { + this.stack = stack; + super.setValueStack(stack); + } + + @Override + public void validate(Object object) throws ValidationException { + + if (object == null) { + + // pas d'objet, donc rien a faire + return; + } + + ActivitySeineDto activitySeine = (ActivitySeineDto) object; + + // FIXME migration client-serveur +// if (!activitySeine.isActivityFinDePeche()) { +// +// // rien a valider +// return; +// } + + Date currentTime = activitySeine.getTime(); + + if (currentTime == null) { + + // heure d'obsersation non encore positionne, on ne peut pas valider + return; + } + + // l'activity est une activite de début de pêche + // on doit vérifier qu'il n'existe pas déjà une autre telle + // activité (de caléé positive) qui n'est pas suivi d'une activité + // de fin de pêche + + RouteDto route = (RouteDto) stack.findValue("routeEntity"); + if (route == null) { + + if (log.isWarnEnabled()) { + log.warn("COULD NOT FIND DATA CONTEXT! [routeEntity]"); + } + return; + } + + boolean valid; + + if (activitySeine.getId() == null) { + + // activity en creation + valid = checkCreateMode(route, activitySeine); + + } else { + + // activity en mise a jour + valid = checkUpdateMode(route, activitySeine); + } + + if (!valid) { + + addError(object); + } + + } + + + protected boolean checkCreateMode(RouteDto route, ActivitySeineDto activitySeine) { + + Date currentTime = activitySeine.getTime(); + + // recuperation de l'activity de debut de peche juste avant la nouvelle + // activity + // FIXME migration client-serveur +// ActivitySeineDto openSet = +// ActivitySeineDtos.getLastActivityDebutDePechePositiveBefore(route, currentTime); + ActivitySeineDto openSet = null; + + if (openSet == null) { + + // pas de peche positive avant la nouvelle activity + // pas possible de fermer une peche + return false; + } + + // on cherche la fin de pêche associée à l'actitivé retenue + // FIXME migration client-serveur +// ActivitySeineDto closeSet = ActivitySeineDtos.getNextActivityFinDePeche(route, openSet); + ActivitySeineDto closeSet = null; + + if (closeSet == null) { + + // la set n'est pas fermee, on peut donc ajouter une activity + // de fin de peche + return true; + } + + // la set est deja ferme, on ne peut donc pas creer une activity de + // fin de peche + return false; + } + + protected boolean checkUpdateMode(RouteDto route, ActivitySeineDto activitySeine) { + + Date currentTime = activitySeine.getTime(); + + // on recupere le debut de peche de cette activity de fin de peche + // FIXME migration client-serveur +// ActivitySeineDto openSet = ActivitySeineDtos.getLastActivityDebutDePechePositiveBefore(route, currentTime); + ActivitySeineDto openSet = null; + + if (openSet == null) { + + // la fin de peche ne couvre plus son debut de peche + return false; + } + + if (currentTime.before(openSet.getTime())) { + + // l'activity de fin ne peut pas etre avant le debut de peche + return false; + } + + // on recupere la prochaine activity de peche + // FIXME migration client-serveur +// openSet = ActivitySeineDtos.getNextActivityDebutDePechePositive(route, activitySeine); + + if (openSet == null) { + // pas de set apres cell-ci, donc pas de probleme + return true; + } + + + // il existe une activity de peche apres celle-ci + + if (currentTime.after(openSet.getTime())) { + + // la fin de peche ne couvre plus son debut de peche + return false; + } + + //TODO On doit interdire dans l'éditeur de temps la possibilite + //TODO de saisir une fil de set avant un debut de calee... + return true; + + } + + + protected void addError(Object object) { + // ce qui est requis et ce qui existe n'est pas en adequation + String fieldName = getFieldName(); + if (log.isInfoEnabled()) { + log.info("not valid , fieldName : " + fieldName); + } + addFieldError(fieldName, object); + } + +} diff --git a/observe-application-swing/src/main/java/fr/ird/observe/validation/validator/dto/ActivityFinDeVeilleExistsDtoValidator.java b/observe-application-swing/src/main/java/fr/ird/observe/validation/validator/dto/ActivityFinDeVeilleExistsDtoValidator.java new file mode 100644 index 0000000..dc7b743 --- /dev/null +++ b/observe-application-swing/src/main/java/fr/ird/observe/validation/validator/dto/ActivityFinDeVeilleExistsDtoValidator.java @@ -0,0 +1,185 @@ +package fr.ird.observe.validation.validator.dto; + +/* + * #%L + * ObServe :: Validation + * %% + * Copyright (C) 2008 - 2013 IRD, Codelutin, Tony Chemit + * %% + * 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.opensymphony.xwork2.util.ValueStack; +import com.opensymphony.xwork2.validator.ValidationException; +import com.opensymphony.xwork2.validator.validators.FieldValidatorSupport; +import fr.ird.observe.services.dto.seine.ActivitySeineDto; +import fr.ird.observe.services.dto.seine.RouteDto; +import fr.ird.observe.services.dto.seine.RouteDtos; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * <!-- START SNIPPET: javadoc --> VesselActivityFieldValidator vérifie que + * l'activity vessel d'une activité est cohérente. <!-- END SNIPPET: javadoc + * --> + * <p/> + * <p/> + * <!-- START SNIPPET: parameters --> <ul> <li>fieldName - The field name this + * validator is validating. Required if using Plain-Validator Syntax otherwise + * not required</li> </ul> <!-- END SNIPPET: parameters --> + * <p/> + * <pre> + * <!-- START SNIPPET: examples --> + * <validators> + * <!-- Plain-Validator Syntax --> + * <validator type="invalidLochMatin"> + * <param name="fieldName">startLogValue</param> + * <message>loch matin must be greater or equals to last + * closed route loch soir</message> + * </validator> + * <p/> + * <!-- Field-Validator Syntax --> + * <field name="startLogValue"> + * <field-validator type="invalidLochMatin"> + * <message>loch matin must be greater or equals to last + * closed route loch soir</message> + * </field-validator> + * </field> + * </validators> + * <!-- END SNIPPET: examples --> + * </pre> + * + * @author Tony Chemit - chemit@codelutin.com + * @since 1.0 + */ +public class ActivityFinDeVeilleExistsDtoValidator extends FieldValidatorSupport { + + /** Logger. */ + private static final Log log = + LogFactory.getLog(ActivityFinDeVeilleExistsDtoValidator.class); + + /** + * l'état attendu : la route possède-t-ell ou non une activity de fin de + * veille. + * <p/> + * Si le drapeau vaut {@code true}, la route est valide si elle possède une + * activité de fin de veille (cas de vérification de la présence de + * l'activité sur l'ensemble au niveau de sa route). + * <p/> + * Si le drapeau vaut {@code false}, la route est valide si elle ne possède + * déjà d'activité de fin de veille (cas de création d'une nouvelle + * activité). + */ + private Boolean required; + + private ValueStack stack; + + @Override + public String getValidatorType() { + return "activityFinDeVeilleExists"; + } + + public void setRequired(Boolean required) { + this.required = required; + } + + @Override + public void setValueStack(ValueStack stack) { + this.stack = stack; + super.setValueStack(stack); + } + + @Override + public void validate(Object object) throws ValidationException { + + if (required == null) { + throw new ValidationException("le parametre required est obligatoire"); + } + + if (object == null) { + + // pas d'objet, donc rien a faire + return; + } + + if (object instanceof RouteDto) { + + // on verifie qu'il existe bien une activity de fin de veille + // parmi les activitys de la route + + RouteDto route = (RouteDto) object; + + checkAgainstRequired(route, route); + return; + } + + if (object instanceof ActivitySeineDto) { + + // on verifie qu'il n'existe pas d'activity de fin de veille + + ActivitySeineDto activitySeine = (ActivitySeineDto) object; + + if (!activitySeine.isActivityFinDeVeille()) { + + // rien a valider (on est pas sur une activity de fin de veille + return; + } + + // l'activity est une activite de fin de veille + // on doit vérifier qu'il n'existe pas déjà une autre activité de + // fin de veille + + RouteDto route = (RouteDto) stack.findValue("routeEntity"); + if (route == null) { + + if (log.isWarnEnabled()) { + log.warn("COULD NOT FIND DATA CONTEXT! [routeEntity]"); + } + return; + } + + checkAgainstRequired(route, activitySeine); + } + } + + protected void checkAgainstRequired(RouteDto route, Object object) { + + if (log.isInfoEnabled()) { + + log.info("check [required : " + required + + "?] activity fin de veille sur la route " + + route.getId() + ":" + route.getDate() + + "sur " + route.sizeActivitySeine() + " activity(s)."); + } + + boolean detected = RouteDtos.isActivityFindDeVeilleFound(route); + boolean valid = required ? detected : !detected; + if (log.isDebugEnabled()) { + log.debug("detected activity fin de veille " + detected); + log.debug("is valid = " + valid); + } + + if (valid) { + return; + } + + String fieldName = getFieldName(); + if (log.isDebugEnabled()) { + log.debug("not valid , fieldName : " + fieldName); + } + addFieldError(fieldName, object); + } +} diff --git a/observe-application-swing/src/main/java/fr/ird/observe/validation/validator/dto/ActivitySimpleSpeedDtoValidator.java b/observe-application-swing/src/main/java/fr/ird/observe/validation/validator/dto/ActivitySimpleSpeedDtoValidator.java new file mode 100644 index 0000000..b569bb2 --- /dev/null +++ b/observe-application-swing/src/main/java/fr/ird/observe/validation/validator/dto/ActivitySimpleSpeedDtoValidator.java @@ -0,0 +1,183 @@ +package fr.ird.observe.validation.validator.dto; + +/* + * #%L + * ObServe :: Validation + * %% + * Copyright (C) 2008 - 2013 IRD, Codelutin, Tony Chemit + * %% + * 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.opensymphony.xwork2.util.ValueStack; +import com.opensymphony.xwork2.validator.ValidationException; +import com.opensymphony.xwork2.validator.validators.FieldValidatorSupport; +import fr.ird.observe.business.gps.GPSPoint; +import fr.ird.observe.business.gps.GpsPoints; +import fr.ird.observe.services.dto.seine.ActivitySeineDto; +import fr.ird.observe.services.dto.seine.RouteDto; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * <!-- START SNIPPET: javadoc --> ActivitySimpleSpeedValidator vérifie que + * la cohérence de vitesse entre l'activité courante et sa précédente. <!-- END SNIPPET: javadoc + * --> + * <p/> + * <p/> + * <!-- START SNIPPET: parameters --> <ul> <li>fieldName - The field name this + * validator is validating. Required if using Plain-Validator Syntax otherwise + * not required</li> </ul> <!-- END SNIPPET: parameters --> + * <p/> + * <pre> + * <!-- START SNIPPET: examples --> + * <validators> + * <!-- Plain-Validator Syntax --> + * <validator type="invalidLochMatin"> + * <param name="fieldName">startLogValue</param> + * <message>loch matin must be greater or equals to last + * closed route loch soir</message> + * </validator> + * + * <!-- Field-Validator Syntax --> + * <field name="startLogValue"> + * <field-validator type="invalidLochMatin"> + * <message>loch matin must be greater or equals to last + * closed route loch soir</message> + * </field-validator> + * </field> + * </validators> + * <!-- END SNIPPET: examples --> + * </pre> + * + * @author Tony Chemit - chemit@codelutin.com + * @since 1.0 + */ +public class ActivitySimpleSpeedDtoValidator extends FieldValidatorSupport { + + /** Logger. */ + private static final Log log = LogFactory.getLog(ActivitySimpleSpeedDtoValidator.class); + + private Float speed; + + public Float getSpeed() { + return speed; + } + + public void setSpeed(float speed) { + this.speed = speed; + } + + @Override + public void setValueStack(ValueStack stack) { + this.stack = stack; + super.setValueStack(stack); + } + + @Override + public void validate(Object object) throws ValidationException { + + if (speed == null) { + throw new ValidationException("le parametre speed est obligatoire"); + } + + if (object == null) { + + // pas d'objet, donc rien a faire + return; + } + + ActivitySeineDto activity = (ActivitySeineDto) object; + + if (activity.getTime() == null) { + + // heure d'observation non encore positionne, on ne peut pas valider + if (log.isDebugEnabled()) { + log.debug("Missing time on current activity : " + decorate(activity) + ", skip speed computation"); + } + return; + } + + + if (activity.getLatitude() == null || + activity.getLongitude() == null) { + + // pas de position, on ne peut pas valider + if (log.isDebugEnabled()) { + log.debug("Missing latitude or longitude on current activity : " + decorate(activity) + ", skip speed computation"); + } + return; + } + + RouteDto route = (RouteDto) stack.findValue("routeEntity"); + + // FIXME migration client-serveur +// ActivitySeineDto previousActivity = ActivitySeineDtos.getPreviousActivity(route, activity); + ActivitySeineDto previousActivity = null; + if (previousActivity == null) { + + // pas d'activity avant, rien à valider + if (log.isDebugEnabled()) { + log.debug("No previous activity for current activity : " + decorate(activity) + ", skip speed computation"); + } + return; + } + + if (previousActivity.getLatitude() == null || + previousActivity.getLongitude() == null) { + + // pas de position, on ne peut pas valider + if (log.isDebugEnabled()) { + log.debug("Missing latitude or longitude on previous activity : " + decorate(previousActivity) + ", skip speed computation"); + } + return; + } + + GPSPoint currentPoint = GpsPoints.newPoint(route, activity); + GPSPoint previousPoint = GpsPoints.newPoint(route, previousActivity); + + float computedSpeed = GpsPoints.getSpeed(previousPoint, currentPoint); + + if (log.isDebugEnabled()) { + log.debug("Speed computed between previous activity point " + decorate(previousPoint) + " to current activity point " + decorate(currentPoint) + ", speed is : " + computedSpeed); + } + boolean b = computedSpeed <= speed; + + if (!b) { + + stack.set("foundSpeed", computedSpeed); + + // vitesse trop grande + addFieldError(getFieldName(), object); + } + } + + @Override + public String getValidatorType() { + return "activitySimpleSpeed"; + } + + //FIXME + protected String decorate(ActivitySeineDto activitySeine) { + return activitySeine.toString(); + } + + //FIXME + protected String decorate(GPSPoint currentPoint) { + return currentPoint.toString(); + } + +} diff --git a/observe-application-swing/src/main/java/fr/ird/observe/validation/validator/dto/ActivitySpeedDtoValidator.java b/observe-application-swing/src/main/java/fr/ird/observe/validation/validator/dto/ActivitySpeedDtoValidator.java new file mode 100644 index 0000000..0b0149e --- /dev/null +++ b/observe-application-swing/src/main/java/fr/ird/observe/validation/validator/dto/ActivitySpeedDtoValidator.java @@ -0,0 +1,222 @@ +package fr.ird.observe.validation.validator.dto; + +/* + * #%L + * ObServe :: Validation + * %% + * Copyright (C) 2008 - 2013 IRD, Codelutin, Tony Chemit + * %% + * 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.opensymphony.xwork2.util.ValueStack; +import com.opensymphony.xwork2.validator.ValidationException; +import com.opensymphony.xwork2.validator.validators.FieldValidatorSupport; +import fr.ird.observe.business.gps.GPSPoint; +import fr.ird.observe.business.gps.GpsPoints; +import fr.ird.observe.services.dto.seine.ActivitySeineStubDto; +import fr.ird.observe.services.dto.seine.RouteDto; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.validator.xwork2.field.CollectionFieldExpressionValidator; + +/** + * <!-- START SNIPPET: javadoc --> ActivityspeedValidator vérifie que + * la cohérence de vitesses entre toutes les activités d'une route. <!-- END SNIPPET: javadoc + * --> + * <p/> + * <p/> + * <!-- START SNIPPET: parameters --> <ul> <li>fieldName - The field name this + * validator is validating. Required if using Plain-Validator Syntax otherwise + * not required</li> </ul> <!-- END SNIPPET: parameters --> + * <p/> + * <pre> + * <!-- START SNIPPET: examples --> + * <validators> + * <!-- Plain-Validator Syntax --> + * <validator type="invalidLochMatin"> + * <param name="fieldName">startLogValue</param> + * <message>loch matin must be greater or equals to last + * closed route loch soir</message> + * </validator> + * + * <!-- Field-Validator Syntax --> + * <field name="startLogValue"> + * <field-validator type="invalidLochMatin"> + * <message>loch matin must be greater or equals to last + * closed route loch soir</message> + * </field-validator> + * </field> + * </validators> + * <!-- END SNIPPET: examples --> + * </pre> + * + * @author Tony Chemit - chemit@codelutin.com + * @since 1.0 + */ +public class ActivitySpeedDtoValidator extends FieldValidatorSupport { + + /** Logger. */ + private static final Log LOG = LogFactory.getLog(ActivitySimpleSpeedDtoValidator.class); + + private CollectionFieldExpressionValidator delegate; + + private Float speed; + + public Float getSpeed() { + return speed; + } + + public void setSpeed(float speed) { + this.speed = speed; + } + + @Override + public void setValueStack(ValueStack stack) { + this.stack = stack; + super.setValueStack(stack); + } + + protected String invalidActivity; + + public String getInvalidActivity() { + return invalidActivity; + } + + //FIXME + protected String decorate(ActivitySeineStubDto activitySeine) { + return activitySeine.toString(); + } + + //FIXME + protected String decorate(GPSPoint currentPoint) { + return currentPoint.toString(); + } + + public CollectionFieldExpressionValidator getDelegate(final RouteDto route) { + if (delegate == null) { + delegate = new CollectionFieldExpressionValidator() { + + @Override + protected boolean validateOneEntry(Object object) { + + c.addCurrent(object); + + ActivitySeineStubDto previousActivity = (ActivitySeineStubDto) c.getPrevious(); + ActivitySeineStubDto currentActivity = (ActivitySeineStubDto) c.getCurrent(); + + if (previousActivity == null) { + if (LOG.isDebugEnabled()) { + LOG.debug("No previous activity for current activity : " + decorate(currentActivity) + ", skip speed computation"); + } + return true; + } + + if (previousActivity.getLatitude() == null || previousActivity.getLongitude() == null) { + // cas limite (pas de précédent ou position non renseigne) + + if (LOG.isDebugEnabled()) { + LOG.debug("Missing latitude or longitude on previous activity : " + decorate(previousActivity) + ", skip speed computation"); + } + + return true; + } + + if (currentActivity.getLongitude() == null || currentActivity.getLatitude() == null) { + // cas limite (pas de précédent ou position non renseigne) + if (LOG.isDebugEnabled()) { + LOG.debug("Missing latitude or longitude on current activity : " + decorate(currentActivity) + ", skip speed computation"); + } + return true; + } + + GPSPoint previousPoint = GpsPoints.newPoint(route, previousActivity); + GPSPoint currentPoint = GpsPoints.newPoint(route, currentActivity); + + float computedSpeed = GpsPoints.getSpeed(previousPoint, currentPoint); + + if (LOG.isDebugEnabled()) { + LOG.debug("Speed computed between previous activity point " + decorate(previousPoint) + " to current activity point " + decorate(currentPoint) + ", speed is : " + computedSpeed); + } + + boolean valid = computedSpeed <= speed; + + if (!valid) { + stack.set("foundSpeed", computedSpeed); + + invalidActivity = decorate(currentActivity); + + if (LOG.isInfoEnabled()) { + LOG.info("Speed from " + + decorate(previousActivity) + + " to " + invalidActivity + + " is " + computedSpeed + + " which is more thant authorized one " + + speed); + } + } + return valid; + } + + @Override + public String getMessage(Object object) { + boolean pop = false; + if (!stack.getRoot().contains(ActivitySpeedDtoValidator.this)) { + stack.push(ActivitySpeedDtoValidator.this); + pop = true; + } + try { + String message = super.getMessage(object); + return message; + } finally { + if (pop) { + stack.pop(); + } + } + } + }; + delegate.setCollectionFieldName(RouteDto.PROPERTY_ACTIVITY_SEINE); + delegate.setMode(CollectionFieldExpressionValidator.Mode.ALL); + delegate.setValueStack(stack); + delegate.setUseSensitiveContext(true); + delegate.setExpressionForFirst(null); + delegate.setExpressionForLast(null); + delegate.setFieldName(getFieldName()); + delegate.setExpression("true"); + delegate.setMessageKey(getMessageKey()); + delegate.setDefaultMessage(getDefaultMessage()); + delegate.setValidatorContext(getValidatorContext()); + } + return delegate; + } + + @Override + public void validate(Object object) throws ValidationException { + + if (speed == null) { + throw new ValidationException("le parametre speed est obligatoire"); + } + + invalidActivity = null; + + getDelegate((RouteDto) object).validate(object); + } + + @Override + public String getValidatorType() { + return "activitySpeed"; + } +} diff --git a/observe-application-swing/src/main/java/fr/ird/observe/validation/validator/dto/RouteActivitysFieldDtoValidator.java b/observe-application-swing/src/main/java/fr/ird/observe/validation/validator/dto/RouteActivitysFieldDtoValidator.java new file mode 100644 index 0000000..f0ca598 --- /dev/null +++ b/observe-application-swing/src/main/java/fr/ird/observe/validation/validator/dto/RouteActivitysFieldDtoValidator.java @@ -0,0 +1,132 @@ +package fr.ird.observe.validation.validator.dto; + +/* + * #%L + * ObServe :: Validation + * %% + * Copyright (C) 2008 - 2013 IRD, Codelutin, Tony Chemit + * %% + * 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.opensymphony.xwork2.util.ValueStack; +import com.opensymphony.xwork2.validator.ValidationException; +import com.opensymphony.xwork2.validator.validators.FieldValidatorSupport; +import fr.ird.observe.services.dto.seine.RouteDto; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * <!-- START SNIPPET: javadoc --> RouteActivitysFieldValidator vérifie que + * les activtés d'une route sont cohérentes au niveau des activités vessel. + * <p/> + * On vérifie que chaque activté de pêche positive a été fermée. + * <p/> + * <!-- END SNIPPET: javadoc --> + * <p/> + * <p/> + * <!-- START SNIPPET: parameters --> <ul> <li>fieldName - The field name this + * validator is validating. Required if using Plain-Validator Syntax otherwise + * not required</li> </ul> <!-- END SNIPPET: parameters --> + * <p/> + * <pre> + * <!-- START SNIPPET: examples --> + * <validators> + * <!-- Plain-Validator Syntax --> + * <validator type="invalidLochMatin"> + * <param name="fieldName">startLogValue</param> + * <message>loch matin must be greater or equals to last + * closed route loch soir</message> + * </validator> + * <p/> + * <!-- Field-Validator Syntax --> + * <field name="startLogValue"> + * <field-validator type="invalidLochMatin"> + * <message>loch matin must be greater or equals to last + * closed route loch soir</message> + * </field-validator> + * </field> + * </validators> + * <!-- END SNIPPET: examples --> + * </pre> + * + * @author Tony Chemit - chemit@codelutin.com + * @since 1.5 + */ +public class RouteActivitysFieldDtoValidator extends FieldValidatorSupport { + + /** Logger. */ + private static final Log log = + LogFactory.getLog(RouteActivitysFieldDtoValidator.class); + + private ValueStack stack; + + @Override + public String getValidatorType() { + return "routeActivitys"; + } + + @Override + public void setValueStack(ValueStack stack) { + this.stack = stack; + super.setValueStack(stack); + } + + @Override + public void validate(Object object) throws ValidationException { + + if (object == null) { + + // pas d'objet, donc rien a faire + return; + } + + // On utilise la route fournie par la pile pour pouvoir la parcourir + // en profondeur (alors que celle offerte par l 'objet est celle de l'ui + // et qu'elle est déconnectée de la base ). + + RouteDto route = (RouteDto) stack.findValue("routeEntity"); + if (route == null) { + + if (log.isWarnEnabled()) { + log.warn("COULD NOT FIND DATA CONTEXT! [routeEntity]"); + } + return; + } + + if (route.isActivitySeineEmpty()) { + + // aucune activité, donc rien à valider + return; + } + + // récupération des activités de pêche positive sur la route + // FIXME migration client-serveur +// List<ActivitySeineDto> positiveSet = ActivitySeineDtos.getActivityDebutDePechePositive(route); +// +// List<ActivitySeineDto> closedSet = ActivitySeineDtos.getActivityFinDePeche(route); +// +// if (positiveSet.size() < closedSet.size()) { +// +// // il manque une activity de fin de pêche +// String fieldName = getFieldName(); +// if (log.isInfoEnabled()) { +// log.info("missing a activity fin de peche , fieldName : " + fieldName); +// } +// addFieldError(fieldName, object); +// } + } +} diff --git a/observe-application-swing/src/main/java/fr/ird/observe/validation/validator/dto/SetLonglineUniqueHomeIdDtoValidator.java b/observe-application-swing/src/main/java/fr/ird/observe/validation/validator/dto/SetLonglineUniqueHomeIdDtoValidator.java new file mode 100644 index 0000000..16b1bd4 --- /dev/null +++ b/observe-application-swing/src/main/java/fr/ird/observe/validation/validator/dto/SetLonglineUniqueHomeIdDtoValidator.java @@ -0,0 +1,103 @@ +package fr.ird.observe.validation.validator.dto; + +/* + * #%L + * ObServe :: Validation + * %% + * Copyright (C) 2008 - 2014 IRD, Codelutin, Tony Chemit + * %% + * 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.Objects; +import com.opensymphony.xwork2.util.ValueStack; +import com.opensymphony.xwork2.validator.ValidationException; +import com.opensymphony.xwork2.validator.validators.FieldValidatorSupport; +import fr.ird.observe.services.dto.longline.SetLonglineDto; +import fr.ird.observe.services.dto.longline.TripLonglineActivityDto; +import fr.ird.observe.services.dto.longline.TripLonglineDto; + +import java.util.Set; + +/** + * Created on 12/7/14. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 3.9 + */ +public class SetLonglineUniqueHomeIdDtoValidator extends FieldValidatorSupport { + + @Override + public void setValueStack(ValueStack stack) { + this.stack = stack; + super.setValueStack(stack); + } + + @Override + public void validate(Object object) throws ValidationException { + + SetLonglineDto setLongline = (SetLonglineDto) object; + String homeId = setLongline.getHomeId(); + + if (homeId != null) { + + String setLonglineTopiaId = setLongline.getId(); + + TripLonglineDto tripLongline = (TripLonglineDto) stack.findValue("TripEntity"); + + Set<TripLonglineActivityDto> activityLonglines = tripLongline.getActivityLongline(); + + boolean notValid = false; + + for (TripLonglineActivityDto activityLongline : activityLonglines) { + + // FIXME migration client-serveur +// SetLonglineDto setLongline1 = activityLongline.getSetLongline(); + SetLonglineDto setLongline1 = null; + + if (setLongline1 != null + && !Objects.equal(setLonglineTopiaId, setLongline1.getId()) + && homeId.equals(setLongline1.getHomeId())) { + + notValid = true; + + //FIXME +// DecoratorService provider = ObserveServiceHelper.getDecoratorService(); +// Decorator<?> decorator = provider.getDecorator(activityLongline); + + stack.set("duplicatedActivity", activityLongline); + + break; + + } + + } + + if (notValid) { + + // vitesse trop grande + addFieldError(getFieldName(), object); + } + } + + + } + + @Override + public String getValidatorType() { + return "setLonglineUniqueHomeId"; + } +} \ No newline at end of file diff --git a/observe-application-swing/src/main/java/fr/ird/observe/validation/validator/dto/SetLonglineUniqueNumberDtoValidator.java b/observe-application-swing/src/main/java/fr/ird/observe/validation/validator/dto/SetLonglineUniqueNumberDtoValidator.java new file mode 100644 index 0000000..2debb46 --- /dev/null +++ b/observe-application-swing/src/main/java/fr/ird/observe/validation/validator/dto/SetLonglineUniqueNumberDtoValidator.java @@ -0,0 +1,99 @@ +package fr.ird.observe.validation.validator.dto; + +/* + * #%L + * ObServe :: Validation + * %% + * Copyright (C) 2008 - 2014 IRD, Codelutin, Tony Chemit + * %% + * 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.opensymphony.xwork2.util.ValueStack; +import com.opensymphony.xwork2.validator.ValidationException; +import com.opensymphony.xwork2.validator.validators.FieldValidatorSupport; +import fr.ird.observe.services.dto.longline.SetLonglineDto; +import fr.ird.observe.services.dto.longline.TripLonglineDto; + +/** + * Created on 12/7/14. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 3.9 + */ +public class SetLonglineUniqueNumberDtoValidator extends FieldValidatorSupport { + + @Override + public void setValueStack(ValueStack stack) { + this.stack = stack; + super.setValueStack(stack); + } + + @Override + public void validate(Object object) throws ValidationException { + + SetLonglineDto setLongline = (SetLonglineDto) object; + Integer number = setLongline.getNumber(); + + if (number != null) { + + String setLonglineTopiaId = setLongline.getId(); + + TripLonglineDto tripLongline = (TripLonglineDto) stack.findValue("tripEntity"); + + boolean notValid = false; + + // FIXME migration client-serveur +// Set<ActivityLonglineDto> activityLonglines = tripLongline.getActivityLongline(); +// +// for (ActivityLonglineDto activityLongline : activityLonglines) { +// +// SetLonglineDto setLongline1 = activityLongline.getSetLongline(); +// +// +// if (setLongline1 != null +// && !Objects.equal(setLonglineTopiaId, setLongline1.getId()) +// && number.equals(setLongline1.getNumber())) { +// +// notValid = true; +// +// //FIXME +//// DecoratorService provider = ObserveServiceHelper.getDecoratorService(); +//// Decorator<?> decorator = provider.getDecorator(activityLongline); +// +// stack.set("duplicatedActivity", activityLongline); +// +// break; +// +// } +// +// } + + if (notValid) { + + // vitesse trop grande + addFieldError(getFieldName(), object); + } + } + + + } + + @Override + public String getValidatorType() { + return "setLonglineUniqueNumber"; + } +} \ No newline at end of file diff --git a/observe-entities-validation/src/main/java/fr/ird/observe/business/validation/field/CollectionUniqueKeyValidator2.java b/observe-application-swing/src/main/java/fr/ird/observe/validation/validator/dto/SpeciesLengthFieldDtoValidator.java similarity index 50% copy from observe-entities-validation/src/main/java/fr/ird/observe/business/validation/field/CollectionUniqueKeyValidator2.java copy to observe-application-swing/src/main/java/fr/ird/observe/validation/validator/dto/SpeciesLengthFieldDtoValidator.java index 94d6b4d..546dd7c 100644 --- a/observe-entities-validation/src/main/java/fr/ird/observe/business/validation/field/CollectionUniqueKeyValidator2.java +++ b/observe-application-swing/src/main/java/fr/ird/observe/validation/validator/dto/SpeciesLengthFieldDtoValidator.java @@ -1,14 +1,14 @@ -package fr.ird.observe.business.validation.field; +package fr.ird.observe.validation.validator.dto; /* * #%L * ObServe :: Validation * %% - * Copyright (C) 2008 - 2015 IRD, Codelutin, Tony Chemit + * Copyright (C) 2008 - 2013 IRD, Codelutin, Tony Chemit * %% * 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 + * 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, @@ -16,36 +16,34 @@ package fr.ird.observe.business.validation.field; * 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 + * 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.opensymphony.xwork2.validator.ValidationException; -import org.nuiton.topia.persistence.TopiaEntity; -import org.nuiton.validator.xwork2.field.CollectionUniqueKeyValidator; +import fr.ird.observe.services.dto.referential.SpeciesDto; /** - * Created on 1/23/15. + * Validateurs sur la taille d'une species. * * @author Tony Chemit - chemit@codelutin.com - * @since XXX + * @since 1.5 */ -public class CollectionUniqueKeyValidator2 extends CollectionUniqueKeyValidator { +public class SpeciesLengthFieldDtoValidator extends AbstractEspeceFieldDtoValidator { @Override - protected Integer getUniqueKeyHashCode(Object o) throws ValidationException { - if (o instanceof TopiaEntity) { - o = ((TopiaEntity) o).getTopiaId(); - } - Integer uniqueKeyHashCode = super.getUniqueKeyHashCode(o); - return uniqueKeyHashCode; + protected Float getBoundMin(SpeciesDto referentiel) { + return referentiel.getMinLength(); } @Override - public String getValidatorType() { - return "collectionUniqueKey"; + protected Float getBoundMax(SpeciesDto referentiel) { + return referentiel.getMaxLength(); } + @Override + public String getValidatorType() { + return "species_length"; + } } diff --git a/observe-entities-validation/src/main/java/fr/ird/observe/business/validation/field/CollectionUniqueKeyValidator2.java b/observe-application-swing/src/main/java/fr/ird/observe/validation/validator/dto/SpeciesWeightFieldDtoValidator.java similarity index 50% copy from observe-entities-validation/src/main/java/fr/ird/observe/business/validation/field/CollectionUniqueKeyValidator2.java copy to observe-application-swing/src/main/java/fr/ird/observe/validation/validator/dto/SpeciesWeightFieldDtoValidator.java index 94d6b4d..3923256 100644 --- a/observe-entities-validation/src/main/java/fr/ird/observe/business/validation/field/CollectionUniqueKeyValidator2.java +++ b/observe-application-swing/src/main/java/fr/ird/observe/validation/validator/dto/SpeciesWeightFieldDtoValidator.java @@ -1,14 +1,14 @@ -package fr.ird.observe.business.validation.field; +package fr.ird.observe.validation.validator.dto; /* * #%L * ObServe :: Validation * %% - * Copyright (C) 2008 - 2015 IRD, Codelutin, Tony Chemit + * Copyright (C) 2008 - 2013 IRD, Codelutin, Tony Chemit * %% * 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 + * 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, @@ -16,36 +16,34 @@ package fr.ird.observe.business.validation.field; * 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 + * 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.opensymphony.xwork2.validator.ValidationException; -import org.nuiton.topia.persistence.TopiaEntity; -import org.nuiton.validator.xwork2.field.CollectionUniqueKeyValidator; +import fr.ird.observe.services.dto.referential.SpeciesDto; /** - * Created on 1/23/15. + * Validateur sur le weight d'une species. * * @author Tony Chemit - chemit@codelutin.com - * @since XXX + * @since 1.5 */ -public class CollectionUniqueKeyValidator2 extends CollectionUniqueKeyValidator { +public class SpeciesWeightFieldDtoValidator extends AbstractEspeceFieldDtoValidator { @Override - protected Integer getUniqueKeyHashCode(Object o) throws ValidationException { - if (o instanceof TopiaEntity) { - o = ((TopiaEntity) o).getTopiaId(); - } - Integer uniqueKeyHashCode = super.getUniqueKeyHashCode(o); - return uniqueKeyHashCode; + protected Float getBoundMin(SpeciesDto referentiel) { + return referentiel.getMinWeight(); } @Override - public String getValidatorType() { - return "collectionUniqueKey"; + protected Float getBoundMax(SpeciesDto referentiel) { + return referentiel.getMaxWeight(); } + @Override + public String getValidatorType() { + return "species_weight"; + } } diff --git a/observe-application-swing/src/main/java/fr/ird/observe/validation/validator/dto/VesselActivityFieldDtoValidator.java b/observe-application-swing/src/main/java/fr/ird/observe/validation/validator/dto/VesselActivityFieldDtoValidator.java new file mode 100644 index 0000000..635fa9e --- /dev/null +++ b/observe-application-swing/src/main/java/fr/ird/observe/validation/validator/dto/VesselActivityFieldDtoValidator.java @@ -0,0 +1,451 @@ +package fr.ird.observe.validation.validator.dto; + +/* + * #%L + * ObServe :: Validation + * %% + * Copyright (C) 2008 - 2013 IRD, Codelutin, Tony Chemit + * %% + * 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.opensymphony.xwork2.util.ValueStack; +import com.opensymphony.xwork2.validator.ValidationException; +import com.opensymphony.xwork2.validator.validators.FieldValidatorSupport; +import fr.ird.observe.services.dto.referential.seine.VesselActivitySeineDto; +import fr.ird.observe.services.dto.seine.ActivitySeineDto; +import fr.ird.observe.services.dto.seine.ActivitySeineStubDto; +import fr.ird.observe.services.dto.seine.RouteDto; +import fr.ird.observe.services.dto.seine.TripSeineDto; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.util.ArrayList; +import java.util.List; + +/** + * <!-- START SNIPPET: javadoc --> VesselActivityFieldValidator vérifie que + * l'activity vessel d'une activité est cohérente. <!-- END SNIPPET: javadoc + * --> + * <p/> + * <p/> + * <!-- START SNIPPET: parameters --> <ul> <li>fieldName - The field name this + * validator is validating. Required if using Plain-Validator Syntax otherwise + * not required</li> </ul> <!-- END SNIPPET: parameters --> + * <p/> + * <pre> + * <!-- START SNIPPET: examples --> + * <validators> + * <!-- Plain-Validator Syntax --> + * <validator type="invalidLochMatin"> + * <param name="fieldName">startLogValue</param> + * <message>loch matin must be greater or equals to last + * closed route loch soir</message> + * </validator> + * <p/> + * <!-- Field-Validator Syntax --> + * <field name="startLogValue"> + * <field-validator type="invalidLochMatin"> + * <message>loch matin must be greater or equals to last + * closed route loch soir</message> + * </field-validator> + * </field> + * </validators> + * <!-- END SNIPPET: examples --> + * </pre> + * + * @author Tony Chemit - chemit@codelutin.com + * @since 1.0 + */ +public class VesselActivityFieldDtoValidator extends FieldValidatorSupport { + + /** Logger. */ + private static final Log log = + LogFactory.getLog(VesselActivityFieldDtoValidator.class); + + private ValueStack stack; + + private String code; + + public void setCode(String code) { + this.code = code; + } + + @Override + public void setValueStack(ValueStack stack) { + this.stack = stack; + super.setValueStack(stack); + } + + @Override + public void validate(Object object) throws ValidationException { + if (code == null) { + throw new ValidationException("le parametre code est obligatoire"); + } + + try { + ActivitySeineDto activitySeine = (ActivitySeineDto) object; + if (activitySeine == null) { + if (log.isDebugEnabled()) { + log.debug("pas d'activity!"); + } + // pas d'activity + return; + } +// boolean create = activity.getTopiaId() == null; +// if (!create) { +// // l'activity vessel est uniquement modifiable en mode creation +// return; +// } + + VesselActivitySeineDto property; + property = (VesselActivitySeineDto) getFieldValue(ActivitySeineDto.PROPERTY_VESSEL_ACTIVITY_SEINE, + object); + if (property == null) { + // si pas de valeur, on ne fait rien + if (log.isDebugEnabled()) { + log.debug("pas d'activity vessel!"); + } + return; + } + + boolean valid = true; + + TripSeineDto maree = (TripSeineDto) stack.findValue("tripEntity"); + + if (maree == null) { + + log.warn("COULD NOT FIND DATA CONTEXT! [tripEntity]"); + return; + } + if (log.isDebugEnabled()) { + log.debug("maree : " + maree); + } + RouteDto route = (RouteDto) stack.findValue("routeEntity"); + if (route == null) { + + log.warn("COULD NOT FIND DATA CONTEXT! [routeEntity]"); + return; + } + if (log.isDebugEnabled()) { + log.debug("route : " + route); + } + + String activityCode = (String) activitySeine.getVesselActivitySeine().getPropertyValue(VesselActivitySeineDto.PROPERTY_CODE); + int nbActivitys = route.sizeActivitySeine(); + + if (code.equals("-16") && !activityCode.equals(ActivitySeineDto.ACTIVITY_FIN_DE_VEILLE)) { + + valid = validate_16(activitySeine, maree, route, nbActivitys, false); + } + + switch (Integer.valueOf(code)) { + case 6: + if (activityCode.equals(ActivitySeineDto.ACTIVITY_FIN_DE_PECHE)) { + valid = validate_6(activitySeine, maree, route, nbActivitys); + } + break; + case 7: + if (activityCode.equals(ActivitySeineDto.ACTIVITY_DEBUT_DE_PECHE)) { + valid = validate_7(activitySeine, maree, route, nbActivitys); + } + break; + case 16: + if (activityCode.equals(ActivitySeineDto.ACTIVITY_FIN_DE_VEILLE)) { + valid = validate_16(activitySeine, maree, route, + nbActivitys, true); + } + break; + } + + + if (!valid) { + String fieldName = getFieldName(); + if (log.isDebugEnabled()) { + log.debug("not valid , fieldName : " + fieldName); + } + addFieldError(fieldName, object); + } + } catch (ValidationException e) { + throw e; + } catch (Exception e) { + log.error(e.getMessage(), e); + + } + + } + + @Override + public String getValidatorType() { + return "activityvessel"; + } + + /** + * validation de l'activity vessel 6 (debut de peche). + * <p/> + * Pour accepter une activité de début de pêche, on doit vérifier toutes les + * conditions suivantes : + * <p/> + * - si une activité de début de pêches existe sur la route avant cette + * activité, elle doit être fermée. + * + * @param activitySeine l'activite en cours de creation + * @param maree la maree courante + * @param route la route courante + * @param nbActivitys le counts d'activités actuellement (sans l'activity a + * tester) + * @return {@code true} if valid, {@code false} otherwise + */ + protected boolean validate_6(ActivitySeineDto activitySeine, + TripSeineDto maree, + RouteDto route, + int nbActivitys) { + if (nbActivitys == 0) { + // aucune activity : ok + return true; + } + //FIXME: non l'algo ne fonctionne pas : il faut calculer les intervalles + //FIXME: de set (debut -fin) ou (debut) + //FIXME: si on un intervalle (debut) alors pas possible + //FIXME: sinon on verifier que l'activity qu'on veut créer n'est pas + //FIXME: dans un intervalle (debut-fin) + List<ActivitySeineStubDto> activitySeines = Lists.newArrayList(route.getActivitySeine()); + Integer[] detectDebutSet = detectActivity(route, ActivitySeineDto.ACTIVITY_FIN_DE_PECHE); + Integer[] detectFinSet = detectActivity(route, ActivitySeineDto.ACTIVITY_DEBUT_DE_PECHE); + int nbDebutReal = 0; + int lastDebutReal = 0; + for (Integer i : detectDebutSet) { + ActivitySeineStubDto bActivitySeine = activitySeines.get(i); + // FIXME migration client-serveur +// if (bActivitySeine.getReasonForNoFishing() == null +// && bActivitySeine.getSetSeine() != null ) { +// // une senne +// nbDebutReal++; +// lastDebutReal = i; +// } + } + // il n'y a pas d'activity de debut de peche disponible + if (nbDebutReal > detectFinSet.length) { + ActivitySeineStubDto bActivitySeine = activitySeines.get(lastDebutReal); + log.info("il existe deja une activity de peche non fini : " + + bActivitySeine.getTime()); + return false; + } + + // tout est ok + return true; + } + + /** + * validation de l'activity vessel 7 (fin de peche) + * <p/> + * Pour accepter une activité de fin de pêche, on doit vérifier que toutes + * les conditions suivantes sont remplies : + * <p/> + * - une activité de début de pêche (avec coup de senne ?) précède cette + * activité et n'est pas déjà associée à une activité de fin de pêche. + * + * @param activitySeine l'activite en cours de creation + * @param maree la maree courante + * @param route la route courante + * @param nbActivitys le counts d'activités actuellement (sans l'activity a + * tester) + * @return {@code true} if valid, {@code false} otherwise + */ + protected boolean validate_7(ActivitySeineDto activitySeine, + TripSeineDto maree, + RouteDto route, + int nbActivitys) { + if (nbActivitys == 0) { + // aucune activity : donc pas possible + return false; + } + List<ActivitySeineStubDto> activitySeines = Lists.newArrayList(route.getActivitySeine()); + Integer[] detectDebutSet = detectActivity(route, ActivitySeineDto.ACTIVITY_FIN_DE_PECHE); + Integer[] detectFinSet = detectActivity(route, ActivitySeineDto.ACTIVITY_DEBUT_DE_PECHE); + Integer lastFinSet = null; + if (detectFinSet.length > 0) { + lastFinSet = detectFinSet[detectFinSet.length - 1]; + } +// int nbDebutReal = 0; +// Integer lastDebutReal = 0; + Integer lastDebutReal = null; + for (Integer i : detectDebutSet) { + ActivitySeineStubDto bActivitySeine = activitySeines.get(i); + // FIXME migration client-serveur +// if (bActivitySeine.getReasonForNoFishing() == null +// +// && bActivitySeine.getSetSeine() != null ) { +// // une senne +//// nbDebutReal++; +// lastDebutReal = i; +// } + } + if (lastDebutReal == null) { + // pas de set ouverte + log.info("pas d'activity de debut de peche ouverte"); + return false; + } + + // il n'y a pas d'activity de debut de peche disponible + if (lastFinSet != null && lastDebutReal < lastFinSet) { + log.info("pas d'activity de debut de peche disponible"); + return false; + } + + // il existe une set ouverte + ActivitySeineStubDto bActivitySeine = activitySeines.get(lastDebutReal); + + if (bActivitySeine.getTime().after(activitySeine.getTime())) { + log.info("activity de fin " + activitySeine.getTime() + + " doit etre apres celle de debut de peche : " + + bActivitySeine.getTime()); + // pas ok + return false; + } + + // tout est ok + return true; + } + + /** + * validation de l'activity vessel 16 (fin de veille). + * <p/> + * Pour accepter une activité de fin de veille, on doit vérifier toutes les + * conditions suivantes sont remplies : + * <p/> + * <pre> + * - toute activité de début de pêche doit être associée à une activité de + * fin de pêche (sauf si non coup de senne ?). + * - une seule activité de fin par route + * </pre> + * <p/> + * Pour toutes les autres activités (<code>is16 == false</code>), on doit + * vérifier : + * <p/> + * - l'activité est toujours avant une éventuelle activité de fin de + * veille. + * + * @param activitySeine l'activite en cours de creation + * @param maree la maree courante + * @param route la route courante + * @param nbActivitys le counts d'activités actuellement (sans l'activity a + * tester) + * @param is16 drapeau pour savoir si on accepte la valeur ou toutes + * les autres valeurs. + * @return {@code true} if valid, {@code false} otherwise + */ + protected boolean validate_16(ActivitySeineDto activitySeine, + TripSeineDto maree, + RouteDto route, + int nbActivitys, + boolean is16) { + if (nbActivitys == 0) { + // pas d'autre activity : ok + return true; + } + + if (is16) { + // on est sur une activity de fin de veille + List<ActivitySeineStubDto> activitySeines = Lists.newArrayList(route.getActivitySeine()); + // une seule activity de fin de veille par route + Integer[] detectActivity = detectActivity(route, ActivitySeineDto.ACTIVITY_FIN_DE_VEILLE); + if (activitySeine.getId() == null && detectActivity.length > 0) { + + log.info("il existe deja une activity de fin de veille!"); + return false; + } + + // chemit 2010-05-23 Cela n'est plus d'actualité : On peut avoir une activité après celle de fin de veille + + // l'activity de fin de veille doit toujours etre la plus recente +// Activity lastActivity = route.getLastActivity(); +// if (activity.getTime().before( +// lastActivity.getTime())) { +// // activity pas en derniere position +// log.info("l'activity de fin de veille doit etre la derniere " + +// "activity de la route"); +// +// return false; +// } + // il ne peut pas rester une activity de debut de peche sans fin + // de set (sauf si non coup de senne ?) + Integer[] detectDebutSet = detectActivity(route, ActivitySeineDto.ACTIVITY_FIN_DE_PECHE); + Integer[] detectFinSet = detectActivity(route, ActivitySeineDto.ACTIVITY_DEBUT_DE_PECHE); + int nbDebutReal = 0; + for (Integer i : detectDebutSet) { + ActivitySeineStubDto bActivitySeine = activitySeines.get(i); + // FIXME migration client-serveur + // if (bActivitySeine.getReasonForNoFishing() == null + // && bActivitySeine.getSetSeine() != null) { + // // une senne + // nbDebutReal++; + //} + } + if (nbDebutReal > detectFinSet.length) { + log.info("il manque une activity de fin de peche"); + return false; + } + + // tout est ok + return true; + } + + // chemit 2010-05-23 Cela n'est plus d'actualité : On peut avoir une activité après celle de fin de veille + + // on est sur une autre activity que celle de fin de veille, + // elle doit obligatoirement etre avant une eventuelle activity + // de fin de veille + +// List<Activity> activitys = route.getActivity(); +// Integer[] detectActivity = detectActivity(route, 16); +// if (detectActivity.length > 0) { +// Activity activityFinVeille = activites.get(detectActivity[0]); +// if (activity.getTime().after( +// activityFinVeille.getTime())) { +// log.info("activity doit etre avant la fin de veille : " + +// activityFinVeille.getTime()); +// // pas ok +// return false; +// } +// } + + // tout est ok + return true; + } + + /** + * Recupere les positions des activitys d'un certain type + * + * @param route la route à inspecter + * @param code le code du type d'activité à rechercher + * @return les positions des activitys d'un certain type donné + */ + protected Integer[] detectActivity(RouteDto route, String code) { + List<Integer> list = new ArrayList<Integer>(); + int index = 0; + for (ActivitySeineStubDto a : route.getActivitySeine()) { + // FIXME migration client-serveur +// String c = (String) a.getVesselActivitySeine().getPropertyValue(VesselActivitySeineDto.PROPERTY_CODE); +// if (code.equals(c)) { +// list.add(index); +// } + index++; + } + return list.toArray(new Integer[list.size()]); + } +} diff --git a/observe-application-swing/src/main/resources/fr/ird/observe/services/dto/seine/RouteDto-n1-create-error-validation.xml b/observe-application-swing/src/main/resources/fr/ird/observe/services/dto/seine/RouteDto-n1-create-error-validation.xml new file mode 100644 index 0000000..4890f67 --- /dev/null +++ b/observe-application-swing/src/main/resources/fr/ird/observe/services/dto/seine/RouteDto-n1-create-error-validation.xml @@ -0,0 +1,65 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + #%L + ObServe :: Validation + %% + Copyright (C) 2008 - 2010 IRD, Codelutin, Tony Chemit + %% + 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% + --> + +<!DOCTYPE validators PUBLIC + "-//Apache Struts//XWork Validator 1.0.3//EN" + "http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd"> +<validators> + + <field name="date"> + + <!-- pas de jour d'observation --> + <field-validator type="required" short-circuit="true"> + <message>validator.route.required.date</message> + </field-validator> + + <!-- coherence jour observation < trip.startDate --> + <field-validator type="fieldexpression" short-circuit="true"> + <param name="expression"><![CDATA[ + currentTripSeine.startDate.time <= date.time + ]]> + </param> + <message>validator.route.invalid.date##${currentTripSeine.startDate}</message> + </field-validator> + + <!-- jour observation non duplique --> + <field-validator type="fieldexpression" short-circuit="true"> + <param name="expression"><![CDATA[ + currentTripSeine.isDateAvailable(topiaId, date) + ]]> + </param> + <message>validator.route.duplicated.date</message> + </field-validator> + </field> + + <field name="comment"> + + <!-- comentaire de moins de 1024 caractères --> + <field-validator type="stringlength"> + <param name="maxLength">1024</param> + <message>validator.route.comment.tobig</message> + </field-validator> + + </field> + +</validators> diff --git a/observe-application-swing/src/main/resources/fr/ird/observe/services/dto/seine/RouteDto-n1-create-warning-validation.xml b/observe-application-swing/src/main/resources/fr/ird/observe/services/dto/seine/RouteDto-n1-create-warning-validation.xml new file mode 100644 index 0000000..b07292d --- /dev/null +++ b/observe-application-swing/src/main/resources/fr/ird/observe/services/dto/seine/RouteDto-n1-create-warning-validation.xml @@ -0,0 +1,59 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + #%L + ObServe :: Validation + %% + Copyright (C) 2008 - 2010 IRD, Codelutin, Tony Chemit + %% + 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% + --> + +<!DOCTYPE validators PUBLIC + "-//Apache Struts//XWork Validator 1.0.3//EN" + "http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd"> +<validators> + + <field name="startLogValue"> + + <!-- loch matin >= 0 --> + <field-validator type="double" short-circuit="true"> + <param name="minInclusive">0</param> + <message>validator.route.positive.startLogValue</message> + </field-validator> + + <!-- coherence loch matin ( superieur a tout loch soir d'une route plus ancienne) --> + <field-validator type="collectionFieldExpression"> + <param name="mode">ALL</param> + <param name="useSensitiveContext">true</param> + <param name="collectionFieldName">tripSeineDto.route</param> + <!--param name="expressionForFirst"><![CDATA[ current.startLogValue == null || current.startLogValue == 0 ]]></param--> + <param name="expression"> + <![CDATA[ startLogValue == null || current.endLogValue == null || current.date.time > date.time || current.endLogValue <= startLogValue ]]> + </param> + <message>validator.route.invalid.startLogValue##${startLogValue}##${current.endLogValue}##${current.date}</message> + </field-validator> + + </field> + + <field name="comment"> + + <!-- pas de comment saisie --> + <field-validator type="requiredstring" short-circuit="true"> + <message>validator.route.null.comment</message> + </field-validator> + + </field> +</validators> diff --git a/observe-application-swing/src/main/resources/fr/ird/observe/services/dto/seine/RouteDto-n1-update-error-validation.xml b/observe-application-swing/src/main/resources/fr/ird/observe/services/dto/seine/RouteDto-n1-update-error-validation.xml new file mode 100644 index 0000000..fc8e70f --- /dev/null +++ b/observe-application-swing/src/main/resources/fr/ird/observe/services/dto/seine/RouteDto-n1-update-error-validation.xml @@ -0,0 +1,111 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + #%L + ObServe :: Validation + %% + Copyright (C) 2008 - 2010 IRD, Codelutin, Tony Chemit + %% + 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% + --> + +<!DOCTYPE validators PUBLIC + "-//Apache Struts//XWork Validator 1.0.3//EN" + "http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd"> +<validators> + + <field name="date"> + + <!-- pas de jour d'observation --> + <field-validator type="required" short-circuit="true"> + <message>validator.route.required.date</message> + </field-validator> + + <!-- coherence jour observation < maree.startDate --> + <field-validator type="fieldexpression" short-circuit="true"> + <param name="expression"><![CDATA[ + currentTripSeine.startDate.time <= date.time + ]]> + </param> + <message>validator.route.invalid.date##${currentTripSeine.startDate}</message> + </field-validator> + + <!-- jour observation non duplique --> + <field-validator type="fieldexpression" short-circuit="true"> + <param name="expression"><![CDATA[ + currentTripSeine.isDateAvailable(id, date) + ]]> + </param> + <message>validator.route.duplicated.date</message> + </field-validator> + + </field> + + <field name="activitySeine"> + + <!-- coherence time des activitys --> + <field-validator type="collectionFieldExpression"> + <param name="mode">ALL</param> + <param name="useSensitiveContext">true</param> + <param name="expression"><![CDATA[ + previous == null || previous.time.time <= current.time.time + ]]> + </param> + <message>validator.route.invalid.time##${index}</message> + </field-validator> + + <!-- coherence seaSurfaceTemperature des activitys (moins de 12 de delta) --> + <field-validator type="collectionFieldExpression"> + <param name="mode">ALL</param> + <param name="useSensitiveContext">true</param> + <param name="expression"><![CDATA[ + previous == null || previous.seaSurfaceTemperature == null || current.seaSurfaceTemperature == null + || (previous.seaSurfaceTemperature > current.seaSurfaceTemperature ? + previous.seaSurfaceTemperature - current.seaSurfaceTemperature <= 12.0 + : current.seaSurfaceTemperature - previous.seaSurfaceTemperature <= 12.0 + ) + ]]> + </param> + <message>validator.route.invalid.seaSurfaceTemperature##${index}</message> + </field-validator> + + <!-- coherence quadrant des activitys --> + <field-validator type="collectionFieldExpression"> + <param name="mode">ALL</param> + <param name="useSensitiveContext">true</param> + <param name="expression"><![CDATA[ + currentTripSeine.ocean == null || current.longitude == null || current.latitude == null + || (currentTripSeine.ocean.getPropertyValue("code") == 3) + || (currentTripSeine.ocean.getPropertyValue("code") == 1) + || (currentTripSeine.ocean.getPropertyValue("code") == 2 && ( current.longitude >= 0)) + ]]> + </param> + <message>validator.route.invalid.quadrant##${index}##${tripSeineDto.ocean.libelle}</message> + </field-validator> + + </field> + + <field name="comment"> + + <!-- comentaire de moins de 1024 caractères --> + <field-validator type="stringlength"> + <param name="maxLength">1024</param> + <message>validator.route.comment.tobig</message> + </field-validator> + + </field> + + +</validators> diff --git a/observe-application-swing/src/main/resources/fr/ird/observe/services/dto/seine/RouteDto-n1-update-warning-validation.xml b/observe-application-swing/src/main/resources/fr/ird/observe/services/dto/seine/RouteDto-n1-update-warning-validation.xml new file mode 100644 index 0000000..d230be8 --- /dev/null +++ b/observe-application-swing/src/main/resources/fr/ird/observe/services/dto/seine/RouteDto-n1-update-warning-validation.xml @@ -0,0 +1,116 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + #%L + ObServe :: Validation + %% + Copyright (C) 2008 - 2010 IRD, Codelutin, Tony Chemit + %% + 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% + --> + +<!DOCTYPE validators PUBLIC + "-//Apache Struts//XWork Validator 1.0.3//EN" + "http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd"> +<validators> + + <field name="startLogValue"> + + <!-- loch matin non defini --> + <!--field-validator type="fieldexpression" short-circuit="true"> + <param name="expression"><![CDATA[(endLogValue == null && startLogValue == null) || startLogValue != null]]> + </param> + <message>validator.route.undefined.startLogValue</message> + </field-validator--> + + <!-- loch matin >= 0 --> + <field-validator type="double" short-circuit="true"> + <param name="minInclusive">0</param> + <message>validator.route.positive.startLogValue</message> + </field-validator> + + <!-- coherence loch matin ( superieur a tout loch soir d'une route plus ancienne) --> + <field-validator type="collectionFieldExpression"> + <param name="mode">ALL</param> + <param name="useSensitiveContext">true</param> + <param name="collectionFieldName">tripSeineDto.route</param> + <param name="expression"> + <![CDATA[ startLogValue == null || current.endLogValue == null || current.topiaId == topiaId || current.date.time > date.time || current.endLogValue <= startLogValue ]]> + </param> + <message> + validator.route.invalid.startLogValue##${startLogValue}##${current.endLogValue}##${current.date} + </message> + </field-validator> + + </field> + + <field name="endLogValue"> + + <!-- loch matin < endLogValue ou l'un des deux lochs non renseigne --> + <field-validator type="fieldexpression" short-circuit="true"> + <param name="expression"> + <![CDATA[(startLogValue == null || endLogValue == null) || endLogValue > startLogValue]]> + </param> + <message>validator.route.invalid.endLogValue.minimum</message> + </field-validator> + + <!-- | endLogValue - loch Matin | < maxGap ou l'un des deux lochs non renseigne --> + <field-validator type="fieldexpressionwithparams"> + <param name="intParams">maxGap:400</param> + <param name="expression"> + <![CDATA[(startLogValue == null || endLogValue == null) || endLogValue <= startLogValue + ints.maxGap]]> + </param> + <message>validator.route.invalid.endLogValue.maximum##${ints.maxGap} + </message> + </field-validator> + + </field> + + <field name="comment"> + + <!-- pas de comment saisie --> + <field-validator type="requiredstring" short-circuit="true"> + <message>validator.route.null.comment</message> + </field-validator> + + </field> + + <field name="activitySeine"> + + <!-- activity non fermee --> + <!--<field-validator type="openableEntity">--> + <!--<message>validator.route.unclosed.activity##${openValueAsString}</message>--> + <!--</field-validator>--> + + <!-- activity de fin de pêche requise --> + <!--field-validator type="routeActivitys"> + <message>validator.route.missing.activityFinDePeche</message> + </field-validator--> + + <!-- activity de fin de veille requise --> + <field-validator type="activityFinDeVeilleExistsDto"> + <param name="required">true</param> + <message>validator.route.missing.activityFinDeVeille</message> + </field-validator> + + <!-- coherence vitesse des activites --> + <field-validator type="activitySpeedDto"> + <param name="speed">30.0</param> + <message>validator.route.invalid.speed##${speed}##${invalidActivity}##${foundSpeed}</message> + </field-validator> + + </field> + +</validators> diff --git a/observe-entities-validation/src/main/resources/validators.xml b/observe-application-swing/src/main/resources/validators.xml similarity index 65% copy from observe-entities-validation/src/main/resources/validators.xml copy to observe-application-swing/src/main/resources/validators.xml index 857ceef..f2f63bd 100644 --- a/observe-entities-validation/src/main/resources/validators.xml +++ b/observe-application-swing/src/main/resources/validators.xml @@ -53,19 +53,33 @@ <validator name="fieldexpressionwithparams" class="org.nuiton.validator.xwork2.field.FieldExpressionWithParamsValidator"/> <!-- les validateurs spécifiques à ObServe --> + <validator name="collectionFieldExpression2" class="fr.ird.observe.validation.validator.CollectionFieldExpressionValidator2"/> + <validator name="collectionFieldExpression" class="fr.ird.observe.validation.validator.CollectionFieldExpressionValidator2"/> + <validator name="collectionUniqueKey" class="fr.ird.observe.validation.validator.CollectionUniqueKeyValidator2"/> + <validator name="observeCollectionUniqueKey" class="fr.ird.observe.validation.validator.ObserveCollectionUniqueKeyValidator"/> + + <!-- Les validateurs spécifique aux entitées dans observe --> + <!--<validator name="openableEntity" class="fr.ird.observe.business.validation.field.OpenableFieldValidator"/>--> + <validator name="species_length" class="fr.ird.observe.validation.validator.entities.SpeciesLengthFieldValidator"/> + <validator name="species_weight" class="fr.ird.observe.validation.validator.entities.SpeciesWeightFieldValidator"/> + <validator name="activitybateau" class="fr.ird.observe.validation.validator.entities.VesselActivityFieldValidator"/> + <validator name="activitySpeed" class="fr.ird.observe.validation.validator.entities.ActivitySpeedValidator"/> + <validator name="activitySimpleSpeed" class="fr.ird.observe.validation.validator.entities.ActivitySimpleSpeedValidator"/> + <validator name="activityFinDeVeilleExists" class="fr.ird.observe.validation.validator.entities.ActivityFinDeVeilleExistsValidator"/> + <validator name="setLonglineUniqueHomeId" class="fr.ird.observe.validation.validator.entities.SetLonglineUniqueHomeIdValidator"/> + <validator name="setLonglineUniqueNumber" class="fr.ird.observe.validation.validator.entities.SetLonglineUniqueNumberValidator"/> + + <!-- Les validateurs spécifique aux Dto dans observe --> <!--<validator name="openableEntity" class="fr.ird.observe.business.validation.field.OpenableFieldValidator"/>--> - <validator name="species_length" class="fr.ird.observe.business.validation.field.SpeciesLengthFieldValidator"/> - <validator name="species_weight" class="fr.ird.observe.business.validation.field.SpeciesWeightFieldValidator"/> - <validator name="activitybateau" class="fr.ird.observe.business.validation.field.VesselActivityFieldValidator"/> - <validator name="activitySpeed" class="fr.ird.observe.business.validation.field.ActivitySpeedValidator"/> - <validator name="activitySimpleSpeed" class="fr.ird.observe.business.validation.field.ActivitySimpleSpeedValidator"/> - <validator name="activityFinDeVeilleExists" class="fr.ird.observe.business.validation.field.ActivityFinDeVeilleExistsValidator"/> - <validator name="setLonglineUniqueHomeId" class="fr.ird.observe.business.validation.field.SetLonglineUniqueHomeIdValidator"/> - <validator name="setLonglineUniqueNumber" class="fr.ird.observe.business.validation.field.SetLonglineUniqueNumberValidator"/> + <validator name="species_lengthDto" class="fr.ird.observe.validation.validator.dto.SpeciesLengthFieldDtoValidator"/> + <validator name="species_weightDto" class="fr.ird.observe.validation.validator.dto.SpeciesWeightFieldDtoValidator"/> + <validator name="activitybateauDto" class="fr.ird.observe.validation.validator.dto.VesselActivityFieldDtoValidator"/> + <validator name="activitySpeedDto" class="fr.ird.observe.validation.validator.dto.ActivitySpeedDtoValidator"/> + <validator name="activitySimpleSpeedDto" class="fr.ird.observe.validation.validator.dto.ActivitySimpleSpeedDtoValidator"/> + <validator name="activityFinDeVeilleExistsDto" class="fr.ird.observe.validation.validator.dto.ActivityFinDeVeilleExistsDtoValidator"/> + <validator name="setLonglineUniqueHomeIdDto" class="fr.ird.observe.validation.validator.dto.SetLonglineUniqueHomeIdDtoValidator"/> + <validator name="setLonglineUniqueNumberDto" class="fr.ird.observe.validation.validator.dto.SetLonglineUniqueNumberDtoValidator"/> + - <validator name="collectionFieldExpression2" class="fr.ird.observe.business.validation.field.CollectionFieldExpressionValidator2"/> - <validator name="collectionFieldExpression" class="fr.ird.observe.business.validation.field.CollectionFieldExpressionValidator2"/> - <validator name="collectionUniqueKey" class="fr.ird.observe.business.validation.field.CollectionUniqueKeyValidator2"/> - <validator name="observeCollectionUniqueKey" class="fr.ird.observe.business.validation.field.ObserveCollectionUniqueKeyValidator"/> </validators> diff --git a/observe-entities-validation/src/main/resources/validators.xml b/observe-application-web/src/main/resources/validators.xml similarity index 80% rename from observe-entities-validation/src/main/resources/validators.xml rename to observe-application-web/src/main/resources/validators.xml index 857ceef..1f8667a 100644 --- a/observe-entities-validation/src/main/resources/validators.xml +++ b/observe-application-web/src/main/resources/validators.xml @@ -53,19 +53,20 @@ <validator name="fieldexpressionwithparams" class="org.nuiton.validator.xwork2.field.FieldExpressionWithParamsValidator"/> <!-- les validateurs spécifiques à ObServe --> - <!--<validator name="openableEntity" class="fr.ird.observe.business.validation.field.OpenableFieldValidator"/>--> - <validator name="species_length" class="fr.ird.observe.business.validation.field.SpeciesLengthFieldValidator"/> - <validator name="species_weight" class="fr.ird.observe.business.validation.field.SpeciesWeightFieldValidator"/> - <validator name="activitybateau" class="fr.ird.observe.business.validation.field.VesselActivityFieldValidator"/> - <validator name="activitySpeed" class="fr.ird.observe.business.validation.field.ActivitySpeedValidator"/> - <validator name="activitySimpleSpeed" class="fr.ird.observe.business.validation.field.ActivitySimpleSpeedValidator"/> - <validator name="activityFinDeVeilleExists" class="fr.ird.observe.business.validation.field.ActivityFinDeVeilleExistsValidator"/> - <validator name="setLonglineUniqueHomeId" class="fr.ird.observe.business.validation.field.SetLonglineUniqueHomeIdValidator"/> - <validator name="setLonglineUniqueNumber" class="fr.ird.observe.business.validation.field.SetLonglineUniqueNumberValidator"/> + <validator name="collectionFieldExpression2" class="fr.ird.observe.validation.validator.CollectionFieldExpressionValidator2"/> + <validator name="collectionFieldExpression" class="fr.ird.observe.validation.validator.CollectionFieldExpressionValidator2"/> + <validator name="collectionUniqueKey" class="fr.ird.observe.validation.validator.CollectionUniqueKeyValidator2"/> + <validator name="observeCollectionUniqueKey" class="fr.ird.observe.validation.validator.ObserveCollectionUniqueKeyValidator"/> - <validator name="collectionFieldExpression2" class="fr.ird.observe.business.validation.field.CollectionFieldExpressionValidator2"/> - <validator name="collectionFieldExpression" class="fr.ird.observe.business.validation.field.CollectionFieldExpressionValidator2"/> - <validator name="collectionUniqueKey" class="fr.ird.observe.business.validation.field.CollectionUniqueKeyValidator2"/> - <validator name="observeCollectionUniqueKey" class="fr.ird.observe.business.validation.field.ObserveCollectionUniqueKeyValidator"/> + <!-- Les validateurs spécifique aux entitées dans observe --> + <!--<validator name="openableEntity" class="fr.ird.observe.business.validation.field.OpenableFieldValidator"/>--> + <validator name="species_length" class="fr.ird.observe.validation.validator.entities.SpeciesLengthFieldValidator"/> + <validator name="species_weight" class="fr.ird.observe.validation.validator.entities.SpeciesWeightFieldValidator"/> + <validator name="activitybateau" class="fr.ird.observe.validation.validator.entities.VesselActivityFieldValidator"/> + <validator name="activitySpeed" class="fr.ird.observe.validation.validator.entities.ActivitySpeedValidator"/> + <validator name="activitySimpleSpeed" class="fr.ird.observe.validation.validator.entities.ActivitySimpleSpeedValidator"/> + <validator name="activityFinDeVeilleExists" class="fr.ird.observe.validation.validator.entities.ActivityFinDeVeilleExistsValidator"/> + <validator name="setLonglineUniqueHomeId" class="fr.ird.observe.validation.validator.entities.SetLonglineUniqueHomeIdValidator"/> + <validator name="setLonglineUniqueNumber" class="fr.ird.observe.validation.validator.entities.SetLonglineUniqueNumberValidator"/> </validators> diff --git a/observe-entities-validation/src/main/java/fr/ird/observe/business/validation/field/CollectionFieldExpressionValidator2.java b/observe-entities-validation/src/main/java/fr/ird/observe/validation/validator/CollectionFieldExpressionValidator2.java similarity index 98% rename from observe-entities-validation/src/main/java/fr/ird/observe/business/validation/field/CollectionFieldExpressionValidator2.java rename to observe-entities-validation/src/main/java/fr/ird/observe/validation/validator/CollectionFieldExpressionValidator2.java index 41baf7d..b3a0e82 100644 --- a/observe-entities-validation/src/main/java/fr/ird/observe/business/validation/field/CollectionFieldExpressionValidator2.java +++ b/observe-entities-validation/src/main/java/fr/ird/observe/validation/validator/CollectionFieldExpressionValidator2.java @@ -1,4 +1,4 @@ -package fr.ird.observe.business.validation.field; +package fr.ird.observe.validation.validator; /* * #%L diff --git a/observe-entities-validation/src/main/java/fr/ird/observe/business/validation/field/CollectionUniqueKeyValidator2.java b/observe-entities-validation/src/main/java/fr/ird/observe/validation/validator/CollectionUniqueKeyValidator2.java similarity index 96% copy from observe-entities-validation/src/main/java/fr/ird/observe/business/validation/field/CollectionUniqueKeyValidator2.java copy to observe-entities-validation/src/main/java/fr/ird/observe/validation/validator/CollectionUniqueKeyValidator2.java index 94d6b4d..de3fd78 100644 --- a/observe-entities-validation/src/main/java/fr/ird/observe/business/validation/field/CollectionUniqueKeyValidator2.java +++ b/observe-entities-validation/src/main/java/fr/ird/observe/validation/validator/CollectionUniqueKeyValidator2.java @@ -1,4 +1,4 @@ -package fr.ird.observe.business.validation.field; +package fr.ird.observe.validation.validator; /* * #%L diff --git a/observe-entities-validation/src/main/java/fr/ird/observe/business/validation/field/ObserveCollectionUniqueKeyValidator.java b/observe-entities-validation/src/main/java/fr/ird/observe/validation/validator/ObserveCollectionUniqueKeyValidator.java similarity index 99% rename from observe-entities-validation/src/main/java/fr/ird/observe/business/validation/field/ObserveCollectionUniqueKeyValidator.java rename to observe-entities-validation/src/main/java/fr/ird/observe/validation/validator/ObserveCollectionUniqueKeyValidator.java index 799b40f..7871ccc 100644 --- a/observe-entities-validation/src/main/java/fr/ird/observe/business/validation/field/ObserveCollectionUniqueKeyValidator.java +++ b/observe-entities-validation/src/main/java/fr/ird/observe/validation/validator/ObserveCollectionUniqueKeyValidator.java @@ -1,4 +1,4 @@ -package fr.ird.observe.business.validation.field; +package fr.ird.observe.validation.validator; /* * #%L diff --git a/observe-entities-validation/src/main/java/fr/ird/observe/validation/validator/entities/AbstractEspeceFieldValidator.java b/observe-entities-validation/src/main/java/fr/ird/observe/validation/validator/entities/AbstractEspeceFieldValidator.java new file mode 100644 index 0000000..708260b --- /dev/null +++ b/observe-entities-validation/src/main/java/fr/ird/observe/validation/validator/entities/AbstractEspeceFieldValidator.java @@ -0,0 +1,295 @@ +package fr.ird.observe.validation.validator.entities; + +/* + * #%L + * ObServe :: Validation + * %% + * Copyright (C) 2008 - 2013 IRD, Codelutin, Tony Chemit + * %% + * 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.opensymphony.xwork2.util.ValueStack; +import com.opensymphony.xwork2.validator.ValidationException; +import com.opensymphony.xwork2.validator.validators.FieldValidatorSupport; +import fr.ird.observe.entities.referentiel.Species; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * <!-- START SNIPPET: javadoc --> + * Ce validateur verifie qu'une espece respece bien les tailles ou + * les poids définis par les bornes de l'espece : + * <ul> + * <li>minLength</li> + * <li>maxLength</li> + * <li>minWeight</li> + * <li>maxWeight</li> + * </ul> + * <p/> + * Lorsqu'il s'agit d'une espece faune, si aucune borne n'est trouvée, alors + * on se base sur les bornes définis dans son groupe d'espece (si il est défini). + * <p/> + * Le paramètre {@link #ratio} permet de spécifier une marge à appliquer sur + * les bornes, il s'agit d'un pourcentage décimal. + * <p/> + * Example : si ratio = 10, alors on utilise les bornes suivantes : + * <pre> + * bMin -10% et bMax + 10% + * </pre> + * <!-- END SNIPPET: javadoc --> + * + * @author Tony Chemit - chemit@codelutin.com + * @since 1.5 + */ +public abstract class AbstractEspeceFieldValidator extends FieldValidatorSupport { + + /** Logger. */ + private static final Log log = + LogFactory.getLog(AbstractEspeceFieldValidator.class); + + public static class Bound { + + private Float min; + + private Float max; + + Bound(Float min, Float max) { + this.min = min; + this.max = max; + } + + public Float getMin() { + return min; + } + + public Float getMax() { + return max; + } + + public Bound applyRatio(float ratio) { + float delta = min / 100 * ratio; + float min = this.min - delta; + if (min < 0) { + min = 0f; + } + delta = max / 100 * ratio; + float max = this.max + delta; + return new Bound(min, max); + } + + @Override + public String toString() { + return super.toString() + '<' + min + ',' + max + '>'; + } + } + + /** + * la stack de validation interceptée lors de la création du validateur. + * <p/> + * Utilisée pour pousser des données dans le context. + */ + protected ValueStack valueStack; + + /** le ratio a appliquer sur les bornes définies dans le référentiel */ + protected Float ratio; + + /** + * Une expression qui si elle est remplie doit être vérifié avant de faire + * la validation par borne, si l'expression n'est pas vérifiée, alors + * le test sur les borne n'est pas effectué. + * + * @since 2.3 + */ + protected String expression; + + protected String speciesField = "espece"; + + public ValueStack getValueStack() { + return valueStack; + } + + public String getSpeciesField() { + return speciesField; + } + + @Override + public void setValueStack(ValueStack valueStack) { + this.valueStack = valueStack; + super.setValueStack(valueStack); + } + + public void setSpeciesField(String speciesField) { + this.speciesField = speciesField; + } + + public void setRatio(float ratio) { + this.ratio = ratio; + } + + public void setExpression(String expression) { + this.expression = expression; + } + + protected abstract Float getBoundMin(Species referentiel); + + protected abstract Float getBoundMax(Species referentiel); + + protected boolean shouldValidate(Object object) throws ValidationException { + Object obj = null; + Boolean answer; + if (StringUtils.isNotEmpty(expression)) { + try { + obj = getFieldValue(expression, object); + } catch (ValidationException e) { + throw e; + } catch (Exception e) { + // let this pass, but it will be logged right below + } + + if (obj != null && obj instanceof Boolean) { + answer = (Boolean) obj; + } else { + answer = false; + if (log.isWarnEnabled()) { + log.warn("Got result of " + obj + + " when trying to get Boolean with expression [" + + expression + "]."); + } + } + } else { + + // no pre-expression, always wants to validate + answer = true; + } + + return answer; + } + + @Override + public void validate(Object object) throws ValidationException { + + if (ratio == null) { + throw new ValidationException("No parameter 'ratio' filled"); + } + + String fieldName = getFieldName(); + if (fieldName == null) { + throw new ValidationException("No parameter 'fieldName' filled"); + } + + String speciesFieldName = getSpeciesField(); + if (speciesFieldName == null) { + throw new ValidationException("No parameter 'speciesFieldName' filled"); + } + + boolean shouldValidate = shouldValidate(object); + + if (!shouldValidate) { + return; + } + + // la donnee a valider + Object value = getFieldValue(fieldName, object); + Float data = value == null ? null : Float.valueOf(String.valueOf(value)); + + if (data == null) { + // la donnee a valider n'est pas définie + return; + } + + if (log.isDebugEnabled()) { + log.debug("data to validate : " + data); + } + + // l'species associée + Species species = (Species) getFieldValue(speciesFieldName, object); + + if (species == null) { + + // pas de species trouvée, on ne peut pas valider + return; + } + + if (log.isDebugEnabled()) { + log.debug("Espece to validate : " + species); + } + + Bound bound = getBound(species); + + if (log.isDebugEnabled()) { + log.debug("Espece Bound to validate : " + bound); + } + + if (bound == null) { + + // pas de donnée dans le référentiel acceptable + return; + } + + Bound boundWithRatio = bound.applyRatio(ratio); + + if (log.isInfoEnabled()) { + log.info("Bound : " + bound); + log.info("Ratio to validate : " + ratio); + log.info("Bound with ratio : " + boundWithRatio); + } + + boolean valid = validateBound(data, boundWithRatio); + + if (!valid) { + + valueStack.push(bound); + + try { + addFieldError(fieldName, object); + } finally { + valueStack.pop(); + } + } + } + + protected Bound getBound(Species referentiel) { + + Float min = getBoundMin(referentiel); + Float max = getBoundMax(referentiel); + + if (min == null || min == 0 || max == null || max == 0) { + // l'une des deux borne n'est pas définie, on ne peut pas utiliser + // la données + return null; + } + return new Bound(min, max); + } + + protected boolean validateBound(Float value, + Bound bound) { + if (value == null) { + + // valeur non définie + return true; + } + boolean valid; + + float min = bound.getMin(); + float max = bound.getMax(); + + valid = min <= value && value <= max; + return valid; + } + +} diff --git a/observe-entities-validation/src/main/java/fr/ird/observe/validation/validator/entities/ActivityDebutDePecheSaneValidator.java b/observe-entities-validation/src/main/java/fr/ird/observe/validation/validator/entities/ActivityDebutDePecheSaneValidator.java new file mode 100644 index 0000000..b0ba32a --- /dev/null +++ b/observe-entities-validation/src/main/java/fr/ird/observe/validation/validator/entities/ActivityDebutDePecheSaneValidator.java @@ -0,0 +1,199 @@ +package fr.ird.observe.validation.validator.entities; + +/* + * #%L + * ObServe :: Validation + * %% + * Copyright (C) 2008 - 2013 IRD, Codelutin, Tony Chemit + * %% + * 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.opensymphony.xwork2.util.ValueStack; +import com.opensymphony.xwork2.validator.ValidationException; +import com.opensymphony.xwork2.validator.validators.FieldValidatorSupport; +import fr.ird.observe.entities.seine.ActivitySeine; +import fr.ird.observe.entities.seine.ActivitySeines; +import fr.ird.observe.entities.seine.Route; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.util.Date; + +/** + * <!-- START SNIPPET: javadoc --> ActivityDebutDePecheSaneValidator vérifie que + * que l'utilisation d'une activity de début de calée est possible. + * <p/> + * On peut utiliser une activité de ce type uniquement si il n'existe pas déjà + * une telle activité de calée positive et qui n'est pas suivie d'une activité + * de fin de veille. <!-- END SNIPPET: javadoc + * --> + * <p/> + * <p/> + * <!-- START SNIPPET: parameters --> <ul> <li>fieldName - The field name this + * validator is validating. Required if using Plain-Validator Syntax otherwise + * not required</li> </ul> <!-- END SNIPPET: parameters --> + * <p/> + * <pre> + * <!-- START SNIPPET: examples --> + * <validators> + * <!-- Plain-Validator Syntax --> + * <validator type="invalidLochMatin"> + * <param name="fieldName">startLogValue</param> + * <message>loch matin must be greater or equals to last + * closed route loch soir</message> + * </validator> + * <p/> + * <!-- Field-Validator Syntax --> + * <field name="startLogValue"> + * <field-validator type="invalidLochMatin"> + * <message>loch matin must be greater or equals to last + * closed route loch soir</message> + * </field-validator> + * </field> + * </validators> + * <!-- END SNIPPET: examples --> + * </pre> + * + * @author Tony Chemit - chemit@codelutin.com + * @since 1.5 + */ +public class ActivityDebutDePecheSaneValidator extends FieldValidatorSupport { + + /** Logger. */ + private static final Log log = + LogFactory.getLog(ActivityDebutDePecheSaneValidator.class); + + private ValueStack stack; + + @Override + public String getValidatorType() { + return "activityDebutDePecheSane"; + } + + @Override + public void setValueStack(ValueStack stack) { + this.stack = stack; + super.setValueStack(stack); + } + + @Override + public void validate(Object object) throws ValidationException { + + if (object == null) { + + // pas d'objet, donc rien a faire + return; + } + + ActivitySeine activitySeine = (ActivitySeine) object; + + if (!activitySeine.isSetOperation()) { + + // rien a valider + return; + } + + if (activitySeine.getTime() == null) { + + // heure d'obsersation non encore positionne, on ne peut pas valider + return; + } + + // l'activity est une activite de début de pêche + // on doit vérifier qu'il n'existe pas déjà une autre telle + // activité (de caléé positive) qui n'est pas suivi d'une activité + // de fin de pêche + + Route route = (Route) stack.findValue("routeEntity"); + if (route == null) { + + if (log.isWarnEnabled()) { + log.warn("COULD NOT FIND DATA CONTEXT! [routeEntity]"); + } + return; + } + + boolean valid; + + if (activitySeine.getTopiaId() == null) { + + // activity en creation + valid = checkCreateMode(route, activitySeine); + + } else { + + // activity en mise a jour + valid = checkUpdateMode(route, activitySeine); + } + + if (!valid) { + + addError(object); + } + } + + protected boolean checkCreateMode(Route route, ActivitySeine activitySeine) { + + Date currentTime = activitySeine.getTime(); + + // recuperation de l'activity de debut de peche juste avant la nouvelle + // activity + ActivitySeine openSet = + ActivitySeines.getLastActivityDebutDePechePositiveBefore(route, currentTime); + + if (openSet == null) { + + // pas de peche positive avant la nouvelle activity + // on autorise donc celle-ci + return true; + } + + // on cherche la fin de pêche associée à l'actitivé retenue + ActivitySeine closeSet = + ActivitySeines.getNextActivityFinDePeche(route, openSet); + + return closeSet != null && + currentTime.after(closeSet.getTime()); + } + + protected boolean checkUpdateMode(Route route, ActivitySeine activitySeine) { + + // on recupere l'activity de fermeture de l'activite de peche + ActivitySeine closeSet = + ActivitySeines.getNextActivityFinDePeche(route, activitySeine); + + if (closeSet == null) { + // pas d'activity de fin, cela est possible ? + return true; + } + + Date currentTime = activitySeine.getTime(); + + // on doit vérifier que l'heure du debut de set n'est pas apres la fin + return !currentTime.after(closeSet.getTime()); + } + + protected void addError(Object object) { + // la set n'est pas fermee ou bien on veut inserer le debut de peche + // avant la fermeture d'une autre peche ce qui n'est pas possible + String fieldName = getFieldName(); + if (log.isInfoEnabled()) { + log.info("not valid , fieldName : " + fieldName); + } + addFieldError(fieldName, object); + } +} diff --git a/observe-entities-validation/src/main/java/fr/ird/observe/validation/validator/entities/ActivityFinDePecheSaneValidator.java b/observe-entities-validation/src/main/java/fr/ird/observe/validation/validator/entities/ActivityFinDePecheSaneValidator.java new file mode 100644 index 0000000..34e6232 --- /dev/null +++ b/observe-entities-validation/src/main/java/fr/ird/observe/validation/validator/entities/ActivityFinDePecheSaneValidator.java @@ -0,0 +1,237 @@ +package fr.ird.observe.validation.validator.entities; + +/* + * #%L + * ObServe :: Validation + * %% + * Copyright (C) 2008 - 2013 IRD, Codelutin, Tony Chemit + * %% + * 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.opensymphony.xwork2.util.ValueStack; +import com.opensymphony.xwork2.validator.ValidationException; +import com.opensymphony.xwork2.validator.validators.FieldValidatorSupport; +import fr.ird.observe.entities.seine.ActivitySeine; +import fr.ird.observe.entities.seine.ActivitySeines; +import fr.ird.observe.entities.seine.Route; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.util.Date; + +/** + * <!-- START SNIPPET: javadoc --> ActivityFinDePecheSaneValidator vérifie que + * que l'utilisation d'une activity de fin de pêche est requise ou non. + * <p/> + * On peut utiliser une activité de ce type uniquement si il existe déjà + * une activité de calée positive et sans activity de fin de pêche. + * <!-- END SNIPPET: javadoc --> + * <p/> + * <p/> + * <!-- START SNIPPET: parameters --> <ul> <li>fieldName - The field name this + * validator is validating. Required if using Plain-Validator Syntax otherwise + * not required</li> </ul> <!-- END SNIPPET: parameters --> + * <p/> + * <pre> + * <!-- START SNIPPET: examples --> + * <validators> + * <!-- Plain-Validator Syntax --> + * <validator type="invalidLochMatin"> + * <param name="fieldName">startLogValue</param> + * <message>loch matin must be greater or equals to last + * closed route loch soir</message> + * </validator> + * <p/> + * <!-- Field-Validator Syntax --> + * <field name="startLogValue"> + * <field-validator type="invalidLochMatin"> + * <message>loch matin must be greater or equals to last + * closed route loch soir</message> + * </field-validator> + * </field> + * </validators> + * <!-- END SNIPPET: examples --> + * </pre> + * + * @author Tony Chemit - chemit@codelutin.com + * @since 1.5 + */ +public class ActivityFinDePecheSaneValidator extends FieldValidatorSupport { + + /** Logger. */ + private static final Log log = + LogFactory.getLog(ActivityFinDePecheSaneValidator.class); + + private ValueStack stack; + + @Override + public String getValidatorType() { + return "activityFinDePecheSane"; + } + + @Override + public void setValueStack(ValueStack stack) { + this.stack = stack; + super.setValueStack(stack); + } + + @Override + public void validate(Object object) throws ValidationException { + + if (object == null) { + + // pas d'objet, donc rien a faire + return; + } + + ActivitySeine activitySeine = (ActivitySeine) object; + + if (!activitySeine.isActivityFinDePeche()) { + + // rien a valider + return; + } + + Date currentTime = activitySeine.getTime(); + + if (currentTime == null) { + + // heure d'obsersation non encore positionne, on ne peut pas valider + return; + } + + // l'activity est une activite de début de pêche + // on doit vérifier qu'il n'existe pas déjà une autre telle + // activité (de caléé positive) qui n'est pas suivi d'une activité + // de fin de pêche + + Route route = (Route) stack.findValue("routeEntity"); + if (route == null) { + + if (log.isWarnEnabled()) { + log.warn("COULD NOT FIND DATA CONTEXT! [routeEntity]"); + } + return; + } + + boolean valid; + + if (activitySeine.getTopiaId() == null) { + + // activity en creation + valid = checkCreateMode(route, activitySeine); + + } else { + + // activity en mise a jour + valid = checkUpdateMode(route, activitySeine); + } + + if (!valid) { + + addError(object); + } + + } + + + protected boolean checkCreateMode(Route route, ActivitySeine activitySeine) { + + Date currentTime = activitySeine.getTime(); + + // recuperation de l'activity de debut de peche juste avant la nouvelle + // activity + ActivitySeine openSet = + ActivitySeines.getLastActivityDebutDePechePositiveBefore(route, currentTime); + + if (openSet == null) { + + // pas de peche positive avant la nouvelle activity + // pas possible de fermer une peche + return false; + } + + // on cherche la fin de pêche associée à l'actitivé retenue + ActivitySeine closeSet = ActivitySeines.getNextActivityFinDePeche(route, openSet); + + if (closeSet == null) { + + // la set n'est pas fermee, on peut donc ajouter une activity + // de fin de peche + return true; + } + + // la set est deja ferme, on ne peut donc pas creer une activity de + // fin de peche + return false; + } + + protected boolean checkUpdateMode(Route route, ActivitySeine activitySeine) { + + Date currentTime = activitySeine.getTime(); + + // on recupere le debut de peche de cette activity de fin de peche + ActivitySeine openSet = + ActivitySeines.getLastActivityDebutDePechePositiveBefore(route, currentTime); + + if (openSet == null) { + + // la fin de peche ne couvre plus son debut de peche + return false; + } + + if (currentTime.before(openSet.getTime())) { + + // l'activity de fin ne peut pas etre avant le debut de peche + return false; + } + + // on recupere la prochaine activity de peche + openSet = + ActivitySeines.getNextActivityDebutDePechePositive(route, activitySeine); + + if (openSet == null) { + // pas de set apres cell-ci, donc pas de probleme + return true; + } + + + // il existe une activity de peche apres celle-ci + + if (currentTime.after(openSet.getTime())) { + + // la fin de peche ne couvre plus son debut de peche + return false; + } + + //TODO On doit interdire dans l'éditeur de temps la possibilite + //TODO de saisir une fil de set avant un debut de calee... + return true; + + } + + + protected void addError(Object object) { + // ce qui est requis et ce qui existe n'est pas en adequation + String fieldName = getFieldName(); + if (log.isInfoEnabled()) { + log.info("not valid , fieldName : " + fieldName); + } + addFieldError(fieldName, object); + } + +} diff --git a/observe-entities-validation/src/main/java/fr/ird/observe/validation/validator/entities/ActivityFinDeVeilleExistsValidator.java b/observe-entities-validation/src/main/java/fr/ird/observe/validation/validator/entities/ActivityFinDeVeilleExistsValidator.java new file mode 100644 index 0000000..751ca75 --- /dev/null +++ b/observe-entities-validation/src/main/java/fr/ird/observe/validation/validator/entities/ActivityFinDeVeilleExistsValidator.java @@ -0,0 +1,185 @@ +package fr.ird.observe.validation.validator.entities; + +/* + * #%L + * ObServe :: Validation + * %% + * Copyright (C) 2008 - 2013 IRD, Codelutin, Tony Chemit + * %% + * 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.opensymphony.xwork2.util.ValueStack; +import com.opensymphony.xwork2.validator.ValidationException; +import com.opensymphony.xwork2.validator.validators.FieldValidatorSupport; +import fr.ird.observe.entities.seine.ActivitySeine; +import fr.ird.observe.entities.seine.ActivitySeines; +import fr.ird.observe.entities.seine.Route; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * <!-- START SNIPPET: javadoc --> VesselActivityFieldValidator vérifie que + * l'activity vessel d'une activité est cohérente. <!-- END SNIPPET: javadoc + * --> + * <p/> + * <p/> + * <!-- START SNIPPET: parameters --> <ul> <li>fieldName - The field name this + * validator is validating. Required if using Plain-Validator Syntax otherwise + * not required</li> </ul> <!-- END SNIPPET: parameters --> + * <p/> + * <pre> + * <!-- START SNIPPET: examples --> + * <validators> + * <!-- Plain-Validator Syntax --> + * <validator type="invalidLochMatin"> + * <param name="fieldName">startLogValue</param> + * <message>loch matin must be greater or equals to last + * closed route loch soir</message> + * </validator> + * <p/> + * <!-- Field-Validator Syntax --> + * <field name="startLogValue"> + * <field-validator type="invalidLochMatin"> + * <message>loch matin must be greater or equals to last + * closed route loch soir</message> + * </field-validator> + * </field> + * </validators> + * <!-- END SNIPPET: examples --> + * </pre> + * + * @author Tony Chemit - chemit@codelutin.com + * @since 1.0 + */ +public class ActivityFinDeVeilleExistsValidator extends FieldValidatorSupport { + + /** Logger. */ + private static final Log log = + LogFactory.getLog(ActivityFinDeVeilleExistsValidator.class); + + /** + * l'état attendu : la route possède-t-ell ou non une activity de fin de + * veille. + * <p/> + * Si le drapeau vaut {@code true}, la route est valide si elle possède une + * activité de fin de veille (cas de vérification de la présence de + * l'activité sur l'ensemble au niveau de sa route). + * <p/> + * Si le drapeau vaut {@code false}, la route est valide si elle ne possède + * déjà d'activité de fin de veille (cas de création d'une nouvelle + * activité). + */ + private Boolean required; + + private ValueStack stack; + + @Override + public String getValidatorType() { + return "activityFinDeVeilleExists"; + } + + public void setRequired(Boolean required) { + this.required = required; + } + + @Override + public void setValueStack(ValueStack stack) { + this.stack = stack; + super.setValueStack(stack); + } + + @Override + public void validate(Object object) throws ValidationException { + + if (required == null) { + throw new ValidationException("le parametre required est obligatoire"); + } + + if (object == null) { + + // pas d'objet, donc rien a faire + return; + } + + if (object instanceof Route) { + + // on verifie qu'il existe bien une activity de fin de veille + // parmi les activitys de la route + + Route route = (Route) object; + + checkAgainstRequired(route, route); + return; + } + + if (object instanceof ActivitySeine) { + + // on verifie qu'il n'existe pas d'activity de fin de veille + + ActivitySeine activitySeine = (ActivitySeine) object; + + if (!activitySeine.isActivityFinDeVeille()) { + + // rien a valider (on est pas sur une activity de fin de veille + return; + } + + // l'activity est une activite de fin de veille + // on doit vérifier qu'il n'existe pas déjà une autre activité de + // fin de veille + + Route route = (Route) stack.findValue("routeEntity"); + if (route == null) { + + if (log.isWarnEnabled()) { + log.warn("COULD NOT FIND DATA CONTEXT! [routeEntity]"); + } + return; + } + + checkAgainstRequired(route, activitySeine); + } + } + + protected void checkAgainstRequired(Route route, Object object) { + + if (log.isInfoEnabled()) { + + log.info("check [required : " + required + + "?] activity fin de veille sur la route " + + route.getTopiaId() + ":" + route.getDate() + + "sur " + route.sizeActivitySeine() + " activity(s)."); + } + + boolean detected = ActivitySeines.isActivityFindDeVeilleFound(route); + boolean valid = required ? detected : !detected; + if (log.isDebugEnabled()) { + log.debug("detected activity fin de veille " + detected); + log.debug("is valid = " + valid); + } + + if (valid) { + return; + } + + String fieldName = getFieldName(); + if (log.isDebugEnabled()) { + log.debug("not valid , fieldName : " + fieldName); + } + addFieldError(fieldName, object); + } +} diff --git a/observe-entities-validation/src/main/java/fr/ird/observe/validation/validator/entities/ActivitySimpleSpeedValidator.java b/observe-entities-validation/src/main/java/fr/ird/observe/validation/validator/entities/ActivitySimpleSpeedValidator.java new file mode 100644 index 0000000..ea0eeca --- /dev/null +++ b/observe-entities-validation/src/main/java/fr/ird/observe/validation/validator/entities/ActivitySimpleSpeedValidator.java @@ -0,0 +1,183 @@ +package fr.ird.observe.validation.validator.entities; + +/* + * #%L + * ObServe :: Validation + * %% + * Copyright (C) 2008 - 2013 IRD, Codelutin, Tony Chemit + * %% + * 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.opensymphony.xwork2.util.ValueStack; +import com.opensymphony.xwork2.validator.ValidationException; +import com.opensymphony.xwork2.validator.validators.FieldValidatorSupport; +import fr.ird.observe.entities.seine.ActivitySeine; +import fr.ird.observe.entities.seine.ActivitySeines; +import fr.ird.observe.entities.seine.Route; +import fr.ird.observe.business.gps.GPSPoint; +import fr.ird.observe.business.gps.GpsPoints; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * <!-- START SNIPPET: javadoc --> ActivitySimpleSpeedValidator vérifie que + * la cohérence de vitesse entre l'activité courante et sa précédente. <!-- END SNIPPET: javadoc + * --> + * <p/> + * <p/> + * <!-- START SNIPPET: parameters --> <ul> <li>fieldName - The field name this + * validator is validating. Required if using Plain-Validator Syntax otherwise + * not required</li> </ul> <!-- END SNIPPET: parameters --> + * <p/> + * <pre> + * <!-- START SNIPPET: examples --> + * <validators> + * <!-- Plain-Validator Syntax --> + * <validator type="invalidLochMatin"> + * <param name="fieldName">startLogValue</param> + * <message>loch matin must be greater or equals to last + * closed route loch soir</message> + * </validator> + * + * <!-- Field-Validator Syntax --> + * <field name="startLogValue"> + * <field-validator type="invalidLochMatin"> + * <message>loch matin must be greater or equals to last + * closed route loch soir</message> + * </field-validator> + * </field> + * </validators> + * <!-- END SNIPPET: examples --> + * </pre> + * + * @author Tony Chemit - chemit@codelutin.com + * @since 1.0 + */ +public class ActivitySimpleSpeedValidator extends FieldValidatorSupport { + + /** Logger. */ + private static final Log log = LogFactory.getLog(ActivitySimpleSpeedValidator.class); + + private Float speed; + + public Float getSpeed() { + return speed; + } + + public void setSpeed(float speed) { + this.speed = speed; + } + + @Override + public void setValueStack(ValueStack stack) { + this.stack = stack; + super.setValueStack(stack); + } + + @Override + public void validate(Object object) throws ValidationException { + + if (speed == null) { + throw new ValidationException("le parametre speed est obligatoire"); + } + + if (object == null) { + + // pas d'objet, donc rien a faire + return; + } + + ActivitySeine activity = (ActivitySeine) object; + + if (activity.getTime() == null) { + + // heure d'observation non encore positionne, on ne peut pas valider + if (log.isDebugEnabled()) { + log.debug("Missing time on current activity : " + decorate(activity) + ", skip speed computation"); + } + return; + } + + + if (activity.getLatitude() == null || + activity.getLongitude() == null) { + + // pas de position, on ne peut pas valider + if (log.isDebugEnabled()) { + log.debug("Missing latitude or longitude on current activity : " + decorate(activity) + ", skip speed computation"); + } + return; + } + + Route route = (Route) stack.findValue("routeEntity"); + + ActivitySeine previousActivity = ActivitySeines.getPreviousActivity(route, activity); + + if (previousActivity == null) { + + // pas d'activity avant, rien à valider + if (log.isDebugEnabled()) { + log.debug("No previous activity for current activity : " + decorate(activity) + ", skip speed computation"); + } + return; + } + + if (previousActivity.getLatitude() == null || + previousActivity.getLongitude() == null) { + + // pas de position, on ne peut pas valider + if (log.isDebugEnabled()) { + log.debug("Missing latitude or longitude on previous activity : " + decorate(previousActivity) + ", skip speed computation"); + } + return; + } + + GPSPoint currentPoint = GpsPoints.newPoint(route, activity); + GPSPoint previousPoint = GpsPoints.newPoint(route, previousActivity); + + float computedSpeed = GpsPoints.getSpeed(previousPoint, currentPoint); + + if (log.isDebugEnabled()) { + log.debug("Speed computed between previous activity point " + decorate(previousPoint) + " to current activity point " + decorate(currentPoint) + ", speed is : " + computedSpeed); + } + boolean b = computedSpeed <= speed; + + if (!b) { + + stack.set("foundSpeed", computedSpeed); + + // vitesse trop grande + addFieldError(getFieldName(), object); + } + } + + @Override + public String getValidatorType() { + return "activitySimpleSpeed"; + } + + //FIXME + protected String decorate(ActivitySeine activitySeine) { + return activitySeine.toString(); + } + + //FIXME + protected String decorate(GPSPoint currentPoint) { + return currentPoint.toString(); + } + +} diff --git a/observe-entities-validation/src/main/java/fr/ird/observe/validation/validator/entities/ActivitySpeedValidator.java b/observe-entities-validation/src/main/java/fr/ird/observe/validation/validator/entities/ActivitySpeedValidator.java new file mode 100644 index 0000000..ed430e5 --- /dev/null +++ b/observe-entities-validation/src/main/java/fr/ird/observe/validation/validator/entities/ActivitySpeedValidator.java @@ -0,0 +1,222 @@ +package fr.ird.observe.validation.validator.entities; + +/* + * #%L + * ObServe :: Validation + * %% + * Copyright (C) 2008 - 2013 IRD, Codelutin, Tony Chemit + * %% + * 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.opensymphony.xwork2.util.ValueStack; +import com.opensymphony.xwork2.validator.ValidationException; +import com.opensymphony.xwork2.validator.validators.FieldValidatorSupport; +import fr.ird.observe.entities.seine.ActivitySeine; +import fr.ird.observe.entities.seine.Route; +import fr.ird.observe.business.gps.GPSPoint; +import fr.ird.observe.business.gps.GpsPoints; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.validator.xwork2.field.CollectionFieldExpressionValidator; + +/** + * <!-- START SNIPPET: javadoc --> ActivityspeedValidator vérifie que + * la cohérence de vitesses entre toutes les activités d'une route. <!-- END SNIPPET: javadoc + * --> + * <p/> + * <p/> + * <!-- START SNIPPET: parameters --> <ul> <li>fieldName - The field name this + * validator is validating. Required if using Plain-Validator Syntax otherwise + * not required</li> </ul> <!-- END SNIPPET: parameters --> + * <p/> + * <pre> + * <!-- START SNIPPET: examples --> + * <validators> + * <!-- Plain-Validator Syntax --> + * <validator type="invalidLochMatin"> + * <param name="fieldName">startLogValue</param> + * <message>loch matin must be greater or equals to last + * closed route loch soir</message> + * </validator> + * + * <!-- Field-Validator Syntax --> + * <field name="startLogValue"> + * <field-validator type="invalidLochMatin"> + * <message>loch matin must be greater or equals to last + * closed route loch soir</message> + * </field-validator> + * </field> + * </validators> + * <!-- END SNIPPET: examples --> + * </pre> + * + * @author Tony Chemit - chemit@codelutin.com + * @since 1.0 + */ +public class ActivitySpeedValidator extends FieldValidatorSupport { + + /** Logger. */ + private static final Log LOG = LogFactory.getLog(ActivitySimpleSpeedValidator.class); + + private CollectionFieldExpressionValidator delegate; + + private Float speed; + + public Float getSpeed() { + return speed; + } + + public void setSpeed(float speed) { + this.speed = speed; + } + + @Override + public void setValueStack(ValueStack stack) { + this.stack = stack; + super.setValueStack(stack); + } + + protected String invalidActivity; + + public String getInvalidActivity() { + return invalidActivity; + } + + //FIXME + protected String decorate(ActivitySeine activitySeine) { + return activitySeine.toString(); + } + + //FIXME + protected String decorate(GPSPoint currentPoint) { + return currentPoint.toString(); + } + + public CollectionFieldExpressionValidator getDelegate(final Route route) { + if (delegate == null) { + delegate = new CollectionFieldExpressionValidator() { + + @Override + protected boolean validateOneEntry(Object object) { + + c.addCurrent(object); + + ActivitySeine previousActivity = (ActivitySeine) c.getPrevious(); + ActivitySeine currentActivity = (ActivitySeine) c.getCurrent(); + + if (previousActivity == null) { + if (LOG.isDebugEnabled()) { + LOG.debug("No previous activity for current activity : " + decorate(currentActivity) + ", skip speed computation"); + } + return true; + } + + if (previousActivity.getLatitude() == null || previousActivity.getLongitude() == null) { + // cas limite (pas de précédent ou position non renseigne) + + if (LOG.isDebugEnabled()) { + LOG.debug("Missing latitude or longitude on previous activity : " + decorate(previousActivity) + ", skip speed computation"); + } + + return true; + } + + if (currentActivity.getLongitude() == null || currentActivity.getLatitude() == null) { + // cas limite (pas de précédent ou position non renseigne) + if (LOG.isDebugEnabled()) { + LOG.debug("Missing latitude or longitude on current activity : " + decorate(currentActivity) + ", skip speed computation"); + } + return true; + } + + GPSPoint previousPoint = GpsPoints.newPoint(route, previousActivity); + GPSPoint currentPoint = GpsPoints.newPoint(route, currentActivity); + + float computedSpeed = GpsPoints.getSpeed(previousPoint, currentPoint); + + if (LOG.isDebugEnabled()) { + LOG.debug("Speed computed between previous activity point " + decorate(previousPoint) + " to current activity point " + decorate(currentPoint) + ", speed is : " + computedSpeed); + } + + boolean valid = computedSpeed <= speed; + + if (!valid) { + stack.set("foundSpeed", computedSpeed); + + invalidActivity = decorate(currentActivity); + + if (LOG.isInfoEnabled()) { + LOG.info("Speed from " + + decorate(previousActivity) + + " to " + invalidActivity + + " is " + computedSpeed + + " which is more thant authorized one " + + speed); + } + } + return valid; + } + + @Override + public String getMessage(Object object) { + boolean pop = false; + if (!stack.getRoot().contains(ActivitySpeedValidator.this)) { + stack.push(ActivitySpeedValidator.this); + pop = true; + } + try { + String message = super.getMessage(object); + return message; + } finally { + if (pop) { + stack.pop(); + } + } + } + }; + delegate.setCollectionFieldName(Route.PROPERTY_ACTIVITY_SEINE); + delegate.setMode(CollectionFieldExpressionValidator.Mode.ALL); + delegate.setValueStack(stack); + delegate.setUseSensitiveContext(true); + delegate.setExpressionForFirst(null); + delegate.setExpressionForLast(null); + delegate.setFieldName(getFieldName()); + delegate.setExpression("true"); + delegate.setMessageKey(getMessageKey()); + delegate.setDefaultMessage(getDefaultMessage()); + delegate.setValidatorContext(getValidatorContext()); + } + return delegate; + } + + @Override + public void validate(Object object) throws ValidationException { + + if (speed == null) { + throw new ValidationException("le parametre speed est obligatoire"); + } + + invalidActivity = null; + + getDelegate((Route) object).validate(object); + } + + @Override + public String getValidatorType() { + return "activitySpeed"; + } +} diff --git a/observe-entities-validation/src/main/java/fr/ird/observe/validation/validator/entities/RouteActivitysFieldValidator.java b/observe-entities-validation/src/main/java/fr/ird/observe/validation/validator/entities/RouteActivitysFieldValidator.java new file mode 100644 index 0000000..f530449 --- /dev/null +++ b/observe-entities-validation/src/main/java/fr/ird/observe/validation/validator/entities/RouteActivitysFieldValidator.java @@ -0,0 +1,135 @@ +package fr.ird.observe.validation.validator.entities; + +/* + * #%L + * ObServe :: Validation + * %% + * Copyright (C) 2008 - 2013 IRD, Codelutin, Tony Chemit + * %% + * 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.opensymphony.xwork2.util.ValueStack; +import com.opensymphony.xwork2.validator.ValidationException; +import com.opensymphony.xwork2.validator.validators.FieldValidatorSupport; +import fr.ird.observe.entities.seine.ActivitySeine; +import fr.ird.observe.entities.seine.ActivitySeines; +import fr.ird.observe.entities.seine.Route; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.util.List; + +/** + * <!-- START SNIPPET: javadoc --> RouteActivitysFieldValidator vérifie que + * les activtés d'une route sont cohérentes au niveau des activités vessel. + * <p/> + * On vérifie que chaque activté de pêche positive a été fermée. + * <p/> + * <!-- END SNIPPET: javadoc --> + * <p/> + * <p/> + * <!-- START SNIPPET: parameters --> <ul> <li>fieldName - The field name this + * validator is validating. Required if using Plain-Validator Syntax otherwise + * not required</li> </ul> <!-- END SNIPPET: parameters --> + * <p/> + * <pre> + * <!-- START SNIPPET: examples --> + * <validators> + * <!-- Plain-Validator Syntax --> + * <validator type="invalidLochMatin"> + * <param name="fieldName">startLogValue</param> + * <message>loch matin must be greater or equals to last + * closed route loch soir</message> + * </validator> + * <p/> + * <!-- Field-Validator Syntax --> + * <field name="startLogValue"> + * <field-validator type="invalidLochMatin"> + * <message>loch matin must be greater or equals to last + * closed route loch soir</message> + * </field-validator> + * </field> + * </validators> + * <!-- END SNIPPET: examples --> + * </pre> + * + * @author Tony Chemit - chemit@codelutin.com + * @since 1.5 + */ +public class RouteActivitysFieldValidator extends FieldValidatorSupport { + + /** Logger. */ + private static final Log log = + LogFactory.getLog(RouteActivitysFieldValidator.class); + + private ValueStack stack; + + @Override + public String getValidatorType() { + return "routeActivitys"; + } + + @Override + public void setValueStack(ValueStack stack) { + this.stack = stack; + super.setValueStack(stack); + } + + @Override + public void validate(Object object) throws ValidationException { + + if (object == null) { + + // pas d'objet, donc rien a faire + return; + } + + // On utilise la route fournie par la pile pour pouvoir la parcourir + // en profondeur (alors que celle offerte par l 'objet est celle de l'ui + // et qu'elle est déconnectée de la base ). + + Route route = (Route) stack.findValue("routeEntity"); + if (route == null) { + + if (log.isWarnEnabled()) { + log.warn("COULD NOT FIND DATA CONTEXT! [routeEntity]"); + } + return; + } + + if (route.isActivitySeineEmpty()) { + + // aucune activité, donc rien à valider + return; + } + + // récupération des activités de pêche positive sur la route + List<ActivitySeine> positiveSet = ActivitySeines.getActivityDebutDePechePositive(route); + + List<ActivitySeine> closedSet = ActivitySeines.getActivityFinDePeche(route); + + if (positiveSet.size() < closedSet.size()) { + + // il manque une activity de fin de pêche + String fieldName = getFieldName(); + if (log.isInfoEnabled()) { + log.info("missing a activity fin de peche , fieldName : " + fieldName); + } + addFieldError(fieldName, object); + } + } +} diff --git a/observe-entities-validation/src/main/java/fr/ird/observe/validation/validator/entities/SetLonglineUniqueHomeIdValidator.java b/observe-entities-validation/src/main/java/fr/ird/observe/validation/validator/entities/SetLonglineUniqueHomeIdValidator.java new file mode 100644 index 0000000..ab97374 --- /dev/null +++ b/observe-entities-validation/src/main/java/fr/ird/observe/validation/validator/entities/SetLonglineUniqueHomeIdValidator.java @@ -0,0 +1,102 @@ +package fr.ird.observe.validation.validator.entities; + +/* + * #%L + * ObServe :: Validation + * %% + * Copyright (C) 2008 - 2014 IRD, Codelutin, Tony Chemit + * %% + * 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.Objects; +import com.opensymphony.xwork2.util.ValueStack; +import com.opensymphony.xwork2.validator.ValidationException; +import com.opensymphony.xwork2.validator.validators.FieldValidatorSupport; +import fr.ird.observe.entities.longline.ActivityLongline; +import fr.ird.observe.entities.longline.SetLongline; +import fr.ird.observe.entities.longline.TripLongline; + +import java.util.Set; + +/** + * Created on 12/7/14. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 3.9 + */ +public class SetLonglineUniqueHomeIdValidator extends FieldValidatorSupport { + + @Override + public void setValueStack(ValueStack stack) { + this.stack = stack; + super.setValueStack(stack); + } + + @Override + public void validate(Object object) throws ValidationException { + + SetLongline setLongline = (SetLongline) object; + String homeId = setLongline.getHomeId(); + + if (homeId != null) { + + String setLonglineTopiaId = setLongline.getTopiaId(); + + TripLongline tripLongline = (TripLongline) stack.findValue("TripEntity"); + + Set<ActivityLongline> activityLonglines = tripLongline.getActivityLongline(); + + boolean notValid = false; + + for (ActivityLongline activityLongline : activityLonglines) { + + SetLongline setLongline1 = activityLongline.getSetLongline(); + + + if (setLongline1 != null + && !Objects.equal(setLonglineTopiaId, setLongline1.getTopiaId()) + && homeId.equals(setLongline1.getHomeId())) { + + notValid = true; + + //FIXME +// DecoratorService provider = ObserveServiceHelper.getDecoratorService(); +// Decorator<?> decorator = provider.getDecorator(activityLongline); + + stack.set("duplicatedActivity", activityLongline); + + break; + + } + + } + + if (notValid) { + + // vitesse trop grande + addFieldError(getFieldName(), object); + } + } + + + } + + @Override + public String getValidatorType() { + return "setLonglineUniqueHomeId"; + } +} \ No newline at end of file diff --git a/observe-entities-validation/src/main/java/fr/ird/observe/validation/validator/entities/SetLonglineUniqueNumberValidator.java b/observe-entities-validation/src/main/java/fr/ird/observe/validation/validator/entities/SetLonglineUniqueNumberValidator.java new file mode 100644 index 0000000..05920f4 --- /dev/null +++ b/observe-entities-validation/src/main/java/fr/ird/observe/validation/validator/entities/SetLonglineUniqueNumberValidator.java @@ -0,0 +1,102 @@ +package fr.ird.observe.validation.validator.entities; + +/* + * #%L + * ObServe :: Validation + * %% + * Copyright (C) 2008 - 2014 IRD, Codelutin, Tony Chemit + * %% + * 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.Objects; +import com.opensymphony.xwork2.util.ValueStack; +import com.opensymphony.xwork2.validator.ValidationException; +import com.opensymphony.xwork2.validator.validators.FieldValidatorSupport; +import fr.ird.observe.entities.longline.ActivityLongline; +import fr.ird.observe.entities.longline.SetLongline; +import fr.ird.observe.entities.longline.TripLongline; + +import java.util.Set; + +/** + * Created on 12/7/14. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 3.9 + */ +public class SetLonglineUniqueNumberValidator extends FieldValidatorSupport { + + @Override + public void setValueStack(ValueStack stack) { + this.stack = stack; + super.setValueStack(stack); + } + + @Override + public void validate(Object object) throws ValidationException { + + SetLongline setLongline = (SetLongline) object; + Integer number = setLongline.getNumber(); + + if (number != null) { + + String setLonglineTopiaId = setLongline.getTopiaId(); + + TripLongline tripLongline = (TripLongline) stack.findValue("tripEntity"); + + Set<ActivityLongline> activityLonglines = tripLongline.getActivityLongline(); + + boolean notValid = false; + + for (ActivityLongline activityLongline : activityLonglines) { + + SetLongline setLongline1 = activityLongline.getSetLongline(); + + + if (setLongline1 != null + && !Objects.equal(setLonglineTopiaId, setLongline1.getTopiaId()) + && number.equals(setLongline1.getNumber())) { + + notValid = true; + + //FIXME +// DecoratorService provider = ObserveServiceHelper.getDecoratorService(); +// Decorator<?> decorator = provider.getDecorator(activityLongline); + + stack.set("duplicatedActivity", activityLongline); + + break; + + } + + } + + if (notValid) { + + // vitesse trop grande + addFieldError(getFieldName(), object); + } + } + + + } + + @Override + public String getValidatorType() { + return "setLonglineUniqueNumber"; + } +} \ No newline at end of file diff --git a/observe-entities-validation/src/main/java/fr/ird/observe/business/validation/field/CollectionUniqueKeyValidator2.java b/observe-entities-validation/src/main/java/fr/ird/observe/validation/validator/entities/SpeciesLengthFieldValidator.java similarity index 50% copy from observe-entities-validation/src/main/java/fr/ird/observe/business/validation/field/CollectionUniqueKeyValidator2.java copy to observe-entities-validation/src/main/java/fr/ird/observe/validation/validator/entities/SpeciesLengthFieldValidator.java index 94d6b4d..f5a356d 100644 --- a/observe-entities-validation/src/main/java/fr/ird/observe/business/validation/field/CollectionUniqueKeyValidator2.java +++ b/observe-entities-validation/src/main/java/fr/ird/observe/validation/validator/entities/SpeciesLengthFieldValidator.java @@ -1,14 +1,14 @@ -package fr.ird.observe.business.validation.field; +package fr.ird.observe.validation.validator.entities; /* * #%L * ObServe :: Validation * %% - * Copyright (C) 2008 - 2015 IRD, Codelutin, Tony Chemit + * Copyright (C) 2008 - 2013 IRD, Codelutin, Tony Chemit * %% * 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 + * 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, @@ -16,36 +16,34 @@ package fr.ird.observe.business.validation.field; * 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 + * 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.opensymphony.xwork2.validator.ValidationException; -import org.nuiton.topia.persistence.TopiaEntity; -import org.nuiton.validator.xwork2.field.CollectionUniqueKeyValidator; +import fr.ird.observe.entities.referentiel.Species; /** - * Created on 1/23/15. + * Validateurs sur la taille d'une species. * * @author Tony Chemit - chemit@codelutin.com - * @since XXX + * @since 1.5 */ -public class CollectionUniqueKeyValidator2 extends CollectionUniqueKeyValidator { +public class SpeciesLengthFieldValidator extends AbstractEspeceFieldValidator { @Override - protected Integer getUniqueKeyHashCode(Object o) throws ValidationException { - if (o instanceof TopiaEntity) { - o = ((TopiaEntity) o).getTopiaId(); - } - Integer uniqueKeyHashCode = super.getUniqueKeyHashCode(o); - return uniqueKeyHashCode; + protected Float getBoundMin(Species referentiel) { + return referentiel.getMinLength(); } @Override - public String getValidatorType() { - return "collectionUniqueKey"; + protected Float getBoundMax(Species referentiel) { + return referentiel.getMaxLength(); } + @Override + public String getValidatorType() { + return "species_length"; + } } diff --git a/observe-entities-validation/src/main/java/fr/ird/observe/business/validation/field/CollectionUniqueKeyValidator2.java b/observe-entities-validation/src/main/java/fr/ird/observe/validation/validator/entities/SpeciesWeightFieldValidator.java similarity index 50% rename from observe-entities-validation/src/main/java/fr/ird/observe/business/validation/field/CollectionUniqueKeyValidator2.java rename to observe-entities-validation/src/main/java/fr/ird/observe/validation/validator/entities/SpeciesWeightFieldValidator.java index 94d6b4d..69ac4d6 100644 --- a/observe-entities-validation/src/main/java/fr/ird/observe/business/validation/field/CollectionUniqueKeyValidator2.java +++ b/observe-entities-validation/src/main/java/fr/ird/observe/validation/validator/entities/SpeciesWeightFieldValidator.java @@ -1,14 +1,14 @@ -package fr.ird.observe.business.validation.field; +package fr.ird.observe.validation.validator.entities; /* * #%L * ObServe :: Validation * %% - * Copyright (C) 2008 - 2015 IRD, Codelutin, Tony Chemit + * Copyright (C) 2008 - 2013 IRD, Codelutin, Tony Chemit * %% * 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 + * 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, @@ -16,36 +16,34 @@ package fr.ird.observe.business.validation.field; * 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 + * 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.opensymphony.xwork2.validator.ValidationException; -import org.nuiton.topia.persistence.TopiaEntity; -import org.nuiton.validator.xwork2.field.CollectionUniqueKeyValidator; +import fr.ird.observe.entities.referentiel.Species; /** - * Created on 1/23/15. + * Validateur sur le weight d'une species. * * @author Tony Chemit - chemit@codelutin.com - * @since XXX + * @since 1.5 */ -public class CollectionUniqueKeyValidator2 extends CollectionUniqueKeyValidator { +public class SpeciesWeightFieldValidator extends AbstractEspeceFieldValidator { @Override - protected Integer getUniqueKeyHashCode(Object o) throws ValidationException { - if (o instanceof TopiaEntity) { - o = ((TopiaEntity) o).getTopiaId(); - } - Integer uniqueKeyHashCode = super.getUniqueKeyHashCode(o); - return uniqueKeyHashCode; + protected Float getBoundMin(Species referentiel) { + return referentiel.getMinWeight(); } @Override - public String getValidatorType() { - return "collectionUniqueKey"; + protected Float getBoundMax(Species referentiel) { + return referentiel.getMaxWeight(); } + @Override + public String getValidatorType() { + return "species_weight"; + } } diff --git a/observe-entities-validation/src/main/java/fr/ird/observe/validation/validator/entities/VesselActivityFieldValidator.java b/observe-entities-validation/src/main/java/fr/ird/observe/validation/validator/entities/VesselActivityFieldValidator.java new file mode 100644 index 0000000..a3b389c --- /dev/null +++ b/observe-entities-validation/src/main/java/fr/ird/observe/validation/validator/entities/VesselActivityFieldValidator.java @@ -0,0 +1,446 @@ +package fr.ird.observe.validation.validator.entities; + +/* + * #%L + * ObServe :: Validation + * %% + * Copyright (C) 2008 - 2013 IRD, Codelutin, Tony Chemit + * %% + * 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.opensymphony.xwork2.util.ValueStack; +import com.opensymphony.xwork2.validator.ValidationException; +import com.opensymphony.xwork2.validator.validators.FieldValidatorSupport; +import fr.ird.observe.entities.referentiel.seine.VesselActivitySeine; +import fr.ird.observe.entities.seine.ActivitySeine; +import fr.ird.observe.entities.seine.ActivitySeineImpl; +import fr.ird.observe.entities.seine.Route; +import fr.ird.observe.entities.seine.TripSeine; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.util.ArrayList; +import java.util.List; + +/** + * <!-- START SNIPPET: javadoc --> VesselActivityFieldValidator vérifie que + * l'activity vessel d'une activité est cohérente. <!-- END SNIPPET: javadoc + * --> + * <p/> + * <p/> + * <!-- START SNIPPET: parameters --> <ul> <li>fieldName - The field name this + * validator is validating. Required if using Plain-Validator Syntax otherwise + * not required</li> </ul> <!-- END SNIPPET: parameters --> + * <p/> + * <pre> + * <!-- START SNIPPET: examples --> + * <validators> + * <!-- Plain-Validator Syntax --> + * <validator type="invalidLochMatin"> + * <param name="fieldName">startLogValue</param> + * <message>loch matin must be greater or equals to last + * closed route loch soir</message> + * </validator> + * <p/> + * <!-- Field-Validator Syntax --> + * <field name="startLogValue"> + * <field-validator type="invalidLochMatin"> + * <message>loch matin must be greater or equals to last + * closed route loch soir</message> + * </field-validator> + * </field> + * </validators> + * <!-- END SNIPPET: examples --> + * </pre> + * + * @author Tony Chemit - chemit@codelutin.com + * @since 1.0 + */ +public class VesselActivityFieldValidator extends FieldValidatorSupport { + + /** Logger. */ + private static final Log log = + LogFactory.getLog(VesselActivityFieldValidator.class); + + private ValueStack stack; + + private String code; + + public void setCode(String code) { + this.code = code; + } + + @Override + public void setValueStack(ValueStack stack) { + this.stack = stack; + super.setValueStack(stack); + } + + @Override + public void validate(Object object) throws ValidationException { + if (code == null) { + throw new ValidationException("le parametre code est obligatoire"); + } + + try { + ActivitySeine activitySeine = (ActivitySeine) object; + if (activitySeine == null) { + if (log.isDebugEnabled()) { + log.debug("pas d'activity!"); + } + // pas d'activity + return; + } +// boolean create = activity.getTopiaId() == null; +// if (!create) { +// // l'activity vessel est uniquement modifiable en mode creation +// return; +// } + + VesselActivitySeine property; + property = (VesselActivitySeine) getFieldValue(ActivitySeine.PROPERTY_VESSEL_ACTIVITY_SEINE, + object); + if (property == null) { + // si pas de valeur, on ne fait rien + if (log.isDebugEnabled()) { + log.debug("pas d'activity vessel!"); + } + return; + } + + boolean valid = true; + + TripSeine maree = (TripSeine) stack.findValue("tripEntity"); + + if (maree == null) { + + log.warn("COULD NOT FIND DATA CONTEXT! [tripEntity]"); + return; + } + if (log.isDebugEnabled()) { + log.debug("maree : " + maree); + } + Route route = (Route) stack.findValue("routeEntity"); + if (route == null) { + + log.warn("COULD NOT FIND DATA CONTEXT! [routeEntity]"); + return; + } + if (log.isDebugEnabled()) { + log.debug("route : " + route); + } + + String activityCode = activitySeine.getVesselActivitySeine().getCode(); + int nbActivitys = route.sizeActivitySeine(); + + if (code.equals("-16") && !activityCode.equals(ActivitySeineImpl.ACTIVITY_FIN_DE_VEILLE)) { + + valid = validate_16(activitySeine, maree, route, nbActivitys, false); + } + + switch (Integer.valueOf(code)) { + case 6: + if (activityCode.equals(ActivitySeineImpl.ACTIVITY_FIN_DE_PECHE)) { + valid = validate_6(activitySeine, maree, route, nbActivitys); + } + break; + case 7: + if (activityCode.equals(ActivitySeineImpl.ACTIVITY_DEBUT_DE_PECHE)) { + valid = validate_7(activitySeine, maree, route, nbActivitys); + } + break; + case 16: + if (activityCode.equals(ActivitySeineImpl.ACTIVITY_FIN_DE_VEILLE)) { + valid = validate_16(activitySeine, maree, route, + nbActivitys, true); + } + break; + } + + + if (!valid) { + String fieldName = getFieldName(); + if (log.isDebugEnabled()) { + log.debug("not valid , fieldName : " + fieldName); + } + addFieldError(fieldName, object); + } + } catch (ValidationException e) { + throw e; + } catch (Exception e) { + log.error(e.getMessage(), e); + + } + + } + + @Override + public String getValidatorType() { + return "activityvessel"; + } + + /** + * validation de l'activity vessel 6 (debut de peche). + * <p/> + * Pour accepter une activité de début de pêche, on doit vérifier toutes les + * conditions suivantes : + * <p/> + * - si une activité de début de pêches existe sur la route avant cette + * activité, elle doit être fermée. + * + * @param activitySeine l'activite en cours de creation + * @param maree la maree courante + * @param route la route courante + * @param nbActivitys le counts d'activités actuellement (sans l'activity a + * tester) + * @return {@code true} if valid, {@code false} otherwise + */ + protected boolean validate_6(ActivitySeine activitySeine, + TripSeine maree, + Route route, + int nbActivitys) { + if (nbActivitys == 0) { + // aucune activity : ok + return true; + } + //FIXME: non l'algo ne fonctionne pas : il faut calculer les intervalles + //FIXME: de set (debut -fin) ou (debut) + //FIXME: si on un intervalle (debut) alors pas possible + //FIXME: sinon on verifier que l'activity qu'on veut créer n'est pas + //FIXME: dans un intervalle (debut-fin) + List<ActivitySeine> activitySeines = Lists.newArrayList(route.getActivitySeine()); + Integer[] detectDebutSet = detectActivity(route, ActivitySeineImpl.ACTIVITY_FIN_DE_PECHE); + Integer[] detectFinSet = detectActivity(route, ActivitySeineImpl.ACTIVITY_DEBUT_DE_PECHE); + int nbDebutReal = 0; + int lastDebutReal = 0; + for (Integer i : detectDebutSet) { + ActivitySeine bActivitySeine = activitySeines.get(i); + if (bActivitySeine.getReasonForNoFishing() == null && + bActivitySeine.getSetSeine() != null) { + // une senne + nbDebutReal++; + lastDebutReal = i; + } + } + // il n'y a pas d'activity de debut de peche disponible + if (nbDebutReal > detectFinSet.length) { + ActivitySeine bActivitySeine = activitySeines.get(lastDebutReal); + log.info("il existe deja une activity de peche non fini : " + + bActivitySeine.getTime()); + return false; + } + + // tout est ok + return true; + } + + /** + * validation de l'activity vessel 7 (fin de peche) + * <p/> + * Pour accepter une activité de fin de pêche, on doit vérifier que toutes + * les conditions suivantes sont remplies : + * <p/> + * - une activité de début de pêche (avec coup de senne ?) précède cette + * activité et n'est pas déjà associée à une activité de fin de pêche. + * + * @param activitySeine l'activite en cours de creation + * @param maree la maree courante + * @param route la route courante + * @param nbActivitys le counts d'activités actuellement (sans l'activity a + * tester) + * @return {@code true} if valid, {@code false} otherwise + */ + protected boolean validate_7(ActivitySeine activitySeine, + TripSeine maree, + Route route, + int nbActivitys) { + if (nbActivitys == 0) { + // aucune activity : donc pas possible + return false; + } + List<ActivitySeine> activitySeines = Lists.newArrayList(route.getActivitySeine()); + Integer[] detectDebutSet = detectActivity(route, ActivitySeineImpl.ACTIVITY_FIN_DE_PECHE); + Integer[] detectFinSet = detectActivity(route, ActivitySeineImpl.ACTIVITY_DEBUT_DE_PECHE); + Integer lastFinSet = null; + if (detectFinSet.length > 0) { + lastFinSet = detectFinSet[detectFinSet.length - 1]; + } +// int nbDebutReal = 0; +// Integer lastDebutReal = 0; + Integer lastDebutReal = null; + for (Integer i : detectDebutSet) { + ActivitySeine bActivitySeine = activitySeines.get(i); + if (bActivitySeine.getReasonForNoFishing() == null && + bActivitySeine.getSetSeine() != null) { + // une senne +// nbDebutReal++; + lastDebutReal = i; + } + } + if (lastDebutReal == null) { + // pas de set ouverte + log.info("pas d'activity de debut de peche ouverte"); + return false; + } + + // il n'y a pas d'activity de debut de peche disponible + if (lastFinSet != null && lastDebutReal < lastFinSet) { + log.info("pas d'activity de debut de peche disponible"); + return false; + } + + // il existe une set ouverte + ActivitySeine bActivitySeine = activitySeines.get(lastDebutReal); + + if (bActivitySeine.getTime().after(activitySeine.getTime())) { + log.info("activity de fin " + activitySeine.getTime() + + " doit etre apres celle de debut de peche : " + + bActivitySeine.getTime()); + // pas ok + return false; + } + + // tout est ok + return true; + } + + /** + * validation de l'activity vessel 16 (fin de veille). + * <p/> + * Pour accepter une activité de fin de veille, on doit vérifier toutes les + * conditions suivantes sont remplies : + * <p/> + * <pre> + * - toute activité de début de pêche doit être associée à une activité de + * fin de pêche (sauf si non coup de senne ?). + * - une seule activité de fin par route + * </pre> + * <p/> + * Pour toutes les autres activités (<code>is16 == false</code>), on doit + * vérifier : + * <p/> + * - l'activité est toujours avant une éventuelle activité de fin de + * veille. + * + * @param activitySeine l'activite en cours de creation + * @param maree la maree courante + * @param route la route courante + * @param nbActivitys le counts d'activités actuellement (sans l'activity a + * tester) + * @param is16 drapeau pour savoir si on accepte la valeur ou toutes + * les autres valeurs. + * @return {@code true} if valid, {@code false} otherwise + */ + protected boolean validate_16(ActivitySeine activitySeine, + TripSeine maree, + Route route, + int nbActivitys, + boolean is16) { + if (nbActivitys == 0) { + // pas d'autre activity : ok + return true; + } + + if (is16) { + // on est sur une activity de fin de veille + List<ActivitySeine> activitySeines = Lists.newArrayList(route.getActivitySeine()); + // une seule activity de fin de veille par route + Integer[] detectActivity = detectActivity(route, ActivitySeineImpl.ACTIVITY_FIN_DE_VEILLE); + if (activitySeine.getTopiaId() == null && detectActivity.length > 0) { + + log.info("il existe deja une activity de fin de veille!"); + return false; + } + + // chemit 2010-05-23 Cela n'est plus d'actualité : On peut avoir une activité après celle de fin de veille + + // l'activity de fin de veille doit toujours etre la plus recente +// Activity lastActivity = route.getLastActivity(); +// if (activity.getTime().before( +// lastActivity.getTime())) { +// // activity pas en derniere position +// log.info("l'activity de fin de veille doit etre la derniere " + +// "activity de la route"); +// +// return false; +// } + // il ne peut pas rester une activity de debut de peche sans fin + // de set (sauf si non coup de senne ?) + Integer[] detectDebutSet = detectActivity(route, ActivitySeineImpl.ACTIVITY_FIN_DE_PECHE); + Integer[] detectFinSet = detectActivity(route, ActivitySeineImpl.ACTIVITY_DEBUT_DE_PECHE); + int nbDebutReal = 0; + for (Integer i : detectDebutSet) { + ActivitySeine bActivitySeine = activitySeines.get(i); + if (bActivitySeine.getReasonForNoFishing() == null && + bActivitySeine.getSetSeine() != null) { + // une senne + nbDebutReal++; + } + } + if (nbDebutReal > detectFinSet.length) { + log.info("il manque une activity de fin de peche"); + return false; + } + + // tout est ok + return true; + } + + // chemit 2010-05-23 Cela n'est plus d'actualité : On peut avoir une activité après celle de fin de veille + + // on est sur une autre activity que celle de fin de veille, + // elle doit obligatoirement etre avant une eventuelle activity + // de fin de veille + +// List<Activity> activitys = route.getActivity(); +// Integer[] detectActivity = detectActivity(route, 16); +// if (detectActivity.length > 0) { +// Activity activityFinVeille = activites.get(detectActivity[0]); +// if (activity.getTime().after( +// activityFinVeille.getTime())) { +// log.info("activity doit etre avant la fin de veille : " + +// activityFinVeille.getTime()); +// // pas ok +// return false; +// } +// } + + // tout est ok + return true; + } + + /** + * Recupere les positions des activitys d'un certain type + * + * @param route la route à inspecter + * @param code le code du type d'activité à rechercher + * @return les positions des activitys d'un certain type donné + */ + protected Integer[] detectActivity(Route route, String code) { + List<Integer> list = new ArrayList<Integer>(); + int index = 0; + for (ActivitySeine a : route.getActivitySeine()) { + String c = a.getVesselActivitySeine().getCode(); + if (code.equals(c)) { + list.add(index); + } + index++; + } + return list.toArray(new Integer[list.size()]); + } +} diff --git a/observe-entities-validation/src/test/java/fr/ird/observe/validation/validator/entities/ActivitySeineSpeedValidatorTest.java b/observe-entities-validation/src/test/java/fr/ird/observe/validation/validator/entities/ActivitySeineSpeedValidatorTest.java new file mode 100644 index 0000000..554c5d3 --- /dev/null +++ b/observe-entities-validation/src/test/java/fr/ird/observe/validation/validator/entities/ActivitySeineSpeedValidatorTest.java @@ -0,0 +1,121 @@ +package fr.ird.observe.validation.validator.entities; + +/* + * #%L + * ObServe :: Validation + * %% + * Copyright (C) 2008 - 2013 IRD, Codelutin, Tony Chemit + * %% + * 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.ird.observe.entities.referentiel.seine.VesselActivitySeine; +import fr.ird.observe.entities.referentiel.seine.VesselActivitySeineImpl; +import fr.ird.observe.entities.seine.ActivitySeine; +import fr.ird.observe.entities.seine.ActivitySeineImpl; +import fr.ird.observe.entities.seine.Route; +import fr.ird.observe.entities.seine.RouteImpl; +import org.apache.commons.lang3.time.DateUtils; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; +import org.nuiton.util.DateUtil; +import org.nuiton.validator.NuitonValidator; +import org.nuiton.validator.NuitonValidatorFactory; +import org.nuiton.validator.NuitonValidatorResult; + +import java.util.Date; +import java.util.Locale; + +/** + * @author Tony Chemit - chemit@codelutin.com + * @since 3.0 + */ +public class ActivitySeineSpeedValidatorTest { + + NuitonValidatorResult messages; + + static VesselActivitySeine vesselActivitySeine; + + static Locale locale; + + @BeforeClass + public static void beforeTest() { + + locale = Locale.getDefault(); + + Locale.setDefault(Locale.FRENCH); + +// TestHelper.createApplicationContext(); + + vesselActivitySeine = new VesselActivitySeineImpl(); + + vesselActivitySeine.setLabel1("VesselActivity"); + } + + @After + public void tearDonw() { + if (messages != null) { + messages = null; + } + } + + @AfterClass + public static void afterTest() { + Locale.setDefault(locale); + } + + @Test + public void testValidate() { + + NuitonValidator<Route> validator = + NuitonValidatorFactory.newValidator(Route.class, "testSpeed"); + + // il y a 316 Km (196 Miles) en tre Rouen et Nantes + ActivitySeine aFromNantes = new ActivitySeineImpl(); + aFromNantes.setVesselActivitySeine(vesselActivitySeine); + + aFromNantes.setLatitude(47.197f); + aFromNantes.setLongitude(-1.525f); + Date nantesTime = DateUtil.getTime(DateUtil.createDate(0, 10, 10, 1, 1, 2014), false, false); + + aFromNantes.setTime(nantesTime); + + ActivitySeine aFromRouen = new ActivitySeineImpl(); + aFromRouen.setVesselActivitySeine(vesselActivitySeine); + aFromRouen.setLatitude(49.447f); + aFromRouen.setLongitude(1.096f); + + + Route r = new RouteImpl(); + r.setDate(DateUtil.createDate(13, 12, 2014)); + r.addActivitySeine(aFromNantes); + r.addActivitySeine(aFromRouen); + + // en 1 heure, on fait pas plus de 100 miles + + aFromRouen.setTime(DateUtils.addHours(nantesTime, 1)); + messages = validator.validate(r); + Assert.assertFalse(messages.isValid()); + + aFromRouen.setTime(DateUtils.addHours(nantesTime, 2)); + + messages = validator.validate(r); + Assert.assertTrue(messages.isValid()); + } +} -- To stop receiving notification emails like this one, please contact codelutin.com SCM administrator <admin+scm@list.forge.codelutin.com>.