branch feature/7591 created (now 7c2189f)
This is an automated email from the git hooks/post-receive script. New change to branch feature/7591 in repository observe. See http://git.codelutin.com/observe.git at 7c2189f mise en place de la validation de DTO (refs #7591) This branch includes the following new commits: new 7c2189f mise en place de la validation de DTO (refs #7591) The 1 revisions listed above as "new" are entirely new to this repository and will be described in separate emails. The revisions listed as "adds" were already present in the repository and have only been added to this reference. Detailed log of new commits: 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) -- To stop receiving notification emails like this one, please contact codelutin.com SCM administrator <admin+scm@list.forge.codelutin.com>.
This is an automated email from the git hooks/post-receive script. New commit to branch feature/7591 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>.
participants (1)
-
codelutin.com scm