package nl.ipo.cds.etl.theme.exposedelements;
import static nl.ipo.cds.etl.theme.exposedelements.Message.ATTRIBUTES_EXCLUSIVE;
import static nl.ipo.cds.etl.theme.exposedelements.Message.ATTRIBUTE_CODE_CODESPACE_INVALID;
import static nl.ipo.cds.etl.theme.exposedelements.Message.ATTRIBUTE_CODE_INVALID;
import static nl.ipo.cds.etl.theme.exposedelements.Message.ATTRIBUTE_EMPTY;
import static nl.ipo.cds.etl.theme.exposedelements.Message.ATTRIBUTE_GROUP_INCONSISTENT;
import static nl.ipo.cds.etl.theme.exposedelements.Message.ATTRIBUTE_NULL;
import static nl.ipo.cds.etl.theme.exposedelements.Message.ATTRIBUTE_VALUE_INVALID;
import static nl.ipo.cds.etl.theme.exposedelements.Message.ATTRIBUTE_VALUE_NEGATIVE;
import static nl.ipo.cds.etl.theme.exposedelements.Message.ATTRIBUTE_VALUE_TOO_HIGH;
import static nl.ipo.cds.etl.theme.exposedelements.Message.GEOMETRY_DISCONTINUITY;
import static nl.ipo.cds.etl.theme.exposedelements.Message.GEOMETRY_EMPTY_MULTIGEOMETRY;
import static nl.ipo.cds.etl.theme.exposedelements.Message.GEOMETRY_EXTERIOR_RING_CW;
import static nl.ipo.cds.etl.theme.exposedelements.Message.GEOMETRY_INTERIOR_DISCONNECTED;
import static nl.ipo.cds.etl.theme.exposedelements.Message.GEOMETRY_INTERIOR_RINGS_TOUCH;
import static nl.ipo.cds.etl.theme.exposedelements.Message.GEOMETRY_INTERIOR_RINGS_WITHIN;
import static nl.ipo.cds.etl.theme.exposedelements.Message.GEOMETRY_INTERIOR_RING_CCW;
import static nl.ipo.cds.etl.theme.exposedelements.Message.GEOMETRY_INTERIOR_RING_TOUCHES_EXTERIOR;
import static nl.ipo.cds.etl.theme.exposedelements.Message.GEOMETRY_ONLY_SURFACE_OR_MULTISURFACE;
import static nl.ipo.cds.etl.theme.exposedelements.Message.GEOMETRY_POINT_DUPLICATION;
import static nl.ipo.cds.etl.theme.exposedelements.Message.GEOMETRY_RING_NOT_CLOSED;
import static nl.ipo.cds.etl.theme.exposedelements.Message.GEOMETRY_RING_SELF_INTERSECTION;
import static nl.ipo.cds.etl.theme.exposedelements.Message.GEOMETRY_SELF_INTERSECTION;
import static nl.ipo.cds.etl.theme.exposedelements.Message.GEOMETRY_SRS_NOT_RD;
import static nl.ipo.cds.etl.theme.exposedelements.Message.GEOMETRY_SRS_NULL;
import static nl.ipo.cds.etl.theme.exposedelements.Message.QUALITATIVE_OR_QUANTITATIVE_LIKELIKHOOD_EXCLUSIVE;
import static nl.ipo.cds.etl.theme.exposedelements.Message.QUALITATIVE_OR_QUANTITATIVE_LIKELIKHOOD_REQUIRED;
import java.util.Map;
import nl.ipo.cds.domain.EtlJob;
import nl.ipo.cds.etl.AbstractValidator;
import nl.ipo.cds.validation.AttributeExpression;
import nl.ipo.cds.validation.ValidationReporter;
import nl.ipo.cds.validation.Validator;
import nl.ipo.cds.validation.constants.Constant;
import nl.ipo.cds.validation.execute.CompilerException;
import nl.ipo.cds.validation.geometry.GeometryExpression;
import nl.ipo.cds.validation.gml.CodeExpression;
import nl.ipo.cds.validation.gml.codelists.CodeListFactory;
import org.deegree.geometry.Geometry;
public class ExposedElementsValidator extends AbstractValidator<ExposedElements, Message, Context> {
private final CodeExpression<Message,Context> inspireIdDatasetCode = code ("inspireIdDatasetCode");
private final AttributeExpression<Message, Context, String> inspireIdLocalId = stringAttr ("inspireIdLocalId");
private final AttributeExpression<Message, Context, String> hazardAreaId = stringAttr ("hazardAreaId");
private final AttributeExpression<Message, Context, String> determinationMethod = stringAttr ("determinationMethod");
private final CodeExpression<Message,Context> typeOfHazardHazardCategory = code ("typeOfHazardHazardCategory");
private final GeometryExpression<Message, Context, Geometry> geometry = geometry ("geometry");
private final AttributeExpression<Message, Context, String> likelihoodOfOccurrenceAssessmentMethodName = stringAttr ("likelihoodOfOccurrenceAssessmentMethodName");
private final AttributeExpression<Message, Context, String> likelihoodOfOccurrenceAssessmentMethodLink = stringAttr ("likelihoodOfOccurrenceAssessmentMethodLink");
private final AttributeExpression<Message, Context, String> likelihoodOfOccurrenceQualitativeLikelihood = stringAttr ("likelihoodOfOccurrenceQualitativeLikelihood");
private final AttributeExpression<Message, Context, Double> likelihoodOfOccurrenceQuantitativeLikelihoodProbabilityOfOccurrence = doubleAttr( "likelihoodOfOccurrenceQuantitativeLikelihoodProbabilityOfOccurrence");
private final AttributeExpression<Message, Context, Double> likelihoodOfOccurrenceQuantitativeLikelihoodReturnPeriod = doubleAttr( "likelihoodOfOccurrenceQuantitativeLikelihoodReturnPeriod");
private final Constant<Message, Context, String> inspireIdDatasetCodeSpace = constant ("http://www.inspire-provincies.nl/codeList/DatasetTypeCode/HazardArea");
private final Constant<Message, Context, String> typeOfHazardHazardCategoryCodeSpace = constant ("http://inspire.ec.europa.eu/codeList/RiskOrHazardCategoryValue");
public ExposedElementsValidator(final Map<Object, Object> validatorMessages) throws CompilerException {
super(Context.class, ExposedElements.class, validatorMessages);
compile();
}
@Override
public Context beforeJob(final EtlJob job, final CodeListFactory codeListFactory,
final ValidationReporter<Message, Context> reporter) {
return new Context(codeListFactory, reporter);
}
public Validator<Message, Context> getInspireIdDatasetCodeValidator () {
return getNotNullCodeValidator(inspireIdDatasetCode, inspireIdDatasetCodeSpace);
}
public Validator<Message, Context> getInspireIdLocalIdValidator () {
return getNotNullNotEmptyStringValidator(inspireIdLocalId);
}
public Validator<Message, Context> getHazardAreaIdValidator () {
return getNotNullNotEmptyStringValidator(hazardAreaId);
}
public Validator<Message, Context> getDeterminationMethodValidator () {
return validate (
validate(
and(
not (determinationMethod.isNull ()),
or(
eq (constant ("modelling"), determinationMethod ),
eq (constant ("indirectDetermination"), determinationMethod )
)
).shortCircuit()
).message(ATTRIBUTE_VALUE_INVALID, determinationMethod, constant(determinationMethod.name), constant ("modelling, indirectDetermination"))
);
}
public Validator<Message, Context> getTypeOfHazardHazardCategoryValidator () {
return getNotNullCodeValidator(typeOfHazardHazardCategory, typeOfHazardHazardCategoryCodeSpace);
}
public Validator<Message, Context> getGeometryValidator () {
return getNotNullSurfaceGeometryValidator(geometry);
}
public Validator<Message, Context> getLikelihoodOfOccurrenceValidator () {
return validate (
and (
validate (
not (
and (
likelihoodOfOccurrenceQualitativeLikelihood.isNull(),
and (
likelihoodOfOccurrenceQuantitativeLikelihoodProbabilityOfOccurrence.isNull(),
likelihoodOfOccurrenceQuantitativeLikelihoodReturnPeriod.isNull()
)
)
)
).message(QUALITATIVE_OR_QUANTITATIVE_LIKELIKHOOD_REQUIRED),
validate (
not (
and (
not (likelihoodOfOccurrenceQualitativeLikelihood.isNull()),
or (
not (likelihoodOfOccurrenceQuantitativeLikelihoodProbabilityOfOccurrence.isNull()),
not (likelihoodOfOccurrenceQuantitativeLikelihoodReturnPeriod.isNull())
)
)
)
).message(QUALITATIVE_OR_QUANTITATIVE_LIKELIKHOOD_EXCLUSIVE)
)
);
}
public Validator<Message, Context> getLikelihoodOfOccurrenceAssessmentMethodValidator () {
return validate (
or (
not (likelihoodOfOccurrenceAssessmentMethodName.isNull()),
likelihoodOfOccurrenceAssessmentMethodLink.isNull()
)
).message(ATTRIBUTE_GROUP_INCONSISTENT, constant (likelihoodOfOccurrenceAssessmentMethodName.name), constant (likelihoodOfOccurrenceAssessmentMethodLink.name));
}
public Validator<Message, Context> getLikelihoodOfOccurrenceQualitativeLikelihoodValidator () {
return getNullOrNotEmptyStringValidator(likelihoodOfOccurrenceQualitativeLikelihood);
}
public Validator<Message, Context> getLikelihoodOfOccurrenceAssessmentMethodNameValidator () {
return getNullOrNotEmptyStringValidator(likelihoodOfOccurrenceAssessmentMethodName);
}
public Validator<Message, Context> getLikelihoodOfOccurrenceAssessmentMethodLinkValidator () {
return getNullOrNotEmptyStringValidator(likelihoodOfOccurrenceAssessmentMethodLink);
}
public Validator<Message, Context> getLikelihoodOfOccurrenceQuantitativeLikelihoodValidator () {
return validate (
not (
and (
not (likelihoodOfOccurrenceQuantitativeLikelihoodProbabilityOfOccurrence.isNull()),
not (likelihoodOfOccurrenceQuantitativeLikelihoodReturnPeriod.isNull())
)
)
).message(ATTRIBUTES_EXCLUSIVE,
constant(likelihoodOfOccurrenceQuantitativeLikelihoodProbabilityOfOccurrence.name),
constant(likelihoodOfOccurrenceQuantitativeLikelihoodReturnPeriod.name));
}
public Validator<Message, Context> getLikelihoodOfOccurrenceQuantitativeLikelihoodProbabilityOfOccurrenceValidator () {
return validate (
ifExp (
likelihoodOfOccurrenceQuantitativeLikelihoodProbabilityOfOccurrence.isNull (),
constant (true),
and (
validate (gte(likelihoodOfOccurrenceQuantitativeLikelihoodProbabilityOfOccurrence, constant(0.0))).message (ATTRIBUTE_VALUE_NEGATIVE, constant (likelihoodOfOccurrenceQuantitativeLikelihoodProbabilityOfOccurrence.name)),
validate (lte(likelihoodOfOccurrenceQuantitativeLikelihoodProbabilityOfOccurrence, constant(1.0))).message (ATTRIBUTE_VALUE_TOO_HIGH, constant (likelihoodOfOccurrenceQuantitativeLikelihoodProbabilityOfOccurrence.name))
)
)
);
}
public Validator<Message, Context> getLikelihoodOfOccurrenceQuantitativeLikelihoodReturnPeriodValidator () {
return validate (
ifExp (
likelihoodOfOccurrenceQuantitativeLikelihoodReturnPeriod.isNull (),
constant (true),
validate (gte(likelihoodOfOccurrenceQuantitativeLikelihoodReturnPeriod, constant(0.0))).message (ATTRIBUTE_VALUE_NEGATIVE, constant (likelihoodOfOccurrenceQuantitativeLikelihoodReturnPeriod.name))
)
);
}
private Validator<Message, Context> getNotNullSurfaceGeometryValidator (GeometryExpression<Message, Context, Geometry> surfaceGeometry) {
return validate (
and (
// The following validations short-circuit, there must be a non-empty, Surface geometry:
validate (not (geometry.isNull ())).message (ATTRIBUTE_NULL, constant (surfaceGeometry.name)),
validate (not (surfaceGeometry.isEmptyMultiGeometry())).message (GEOMETRY_EMPTY_MULTIGEOMETRY),
validate (surfaceGeometry.isSurfaceOrMultiSurface()).message (GEOMETRY_ONLY_SURFACE_OR_MULTISURFACE),
// Non short-circuited validations:
and (
// Short circuit to prevent the interiorDisconnected validation if
// any of the other validations fail:
and (
and (
validate (not (surfaceGeometry.hasCurveDuplicatePoint ())).message (GEOMETRY_POINT_DUPLICATION, lastLocation ()),
validate (not (surfaceGeometry.hasCurveDiscontinuity ())).message (GEOMETRY_DISCONTINUITY),
validate (not (surfaceGeometry.hasCurveSelfIntersection ())).message (GEOMETRY_SELF_INTERSECTION, lastLocation ()),
validate (not (surfaceGeometry.hasUnclosedRing ())).message (GEOMETRY_RING_NOT_CLOSED),
validate (not (surfaceGeometry.hasRingSelfIntersection ())).message (GEOMETRY_RING_SELF_INTERSECTION, lastLocation ()),
validate (not (surfaceGeometry.hasTouchingInteriorRings ())).message(GEOMETRY_INTERIOR_RINGS_TOUCH, lastLocation ()),
validate (not (surfaceGeometry.hasInteriorRingsWithin ())).message (GEOMETRY_INTERIOR_RINGS_WITHIN)
),
validate (not (surfaceGeometry.isInteriorDisconnected ())).message (GEOMETRY_INTERIOR_DISCONNECTED)
).shortCircuit (),
// Non-blocking validations:
validate (not (surfaceGeometry.hasExteriorRingCW ())).nonBlocking ().message (GEOMETRY_EXTERIOR_RING_CW),
validate (not (surfaceGeometry.hasInteriorRingCCW ())).nonBlocking ().message (GEOMETRY_INTERIOR_RING_CCW),
validate (not (surfaceGeometry.hasInteriorRingTouchingExterior ())).nonBlocking ().message (GEOMETRY_INTERIOR_RING_TOUCHES_EXTERIOR, lastLocation ()),
validate (not (surfaceGeometry.hasInteriorRingOutsideExterior ())).nonBlocking ().message (GEOMETRY_DISCONTINUITY),
// SRS validations:
and (
validate (surfaceGeometry.hasSrs ()).message (GEOMETRY_SRS_NULL),
validate (surfaceGeometry.isSrs (constant ("28992"))).message (GEOMETRY_SRS_NOT_RD, surfaceGeometry.srsName ())
).shortCircuit()
)
).shortCircuit ()
);
}
private Validator<Message, Context> getNotNullCodeValidator (CodeExpression<Message,Context> codeAttr, Constant<Message, Context, String> codeSpace) {
return validate (
and(
validate (not (codeAttr.isNull ())).message (ATTRIBUTE_NULL, constant (codeAttr.name)),
validate (not (isBlank (codeAttr.code()))).message (ATTRIBUTE_EMPTY, constant (codeAttr.name)),
validate (codeAttr.hasCodeSpace (codeSpace)).message (ATTRIBUTE_CODE_CODESPACE_INVALID, codeAttr.codeSpace(), constant(codeAttr.name), codeSpace),
validate (codeAttr.isValid ()).message (ATTRIBUTE_CODE_INVALID, codeAttr.code(), constant (codeAttr.name), codeSpace)
).shortCircuit()
);
}
private Validator<Message, Context> getNotNullNotEmptyStringValidator (AttributeExpression<Message, Context, String> attr) {
return validate (
and(
validate (not (attr.isNull ())).message (ATTRIBUTE_NULL, constant(attr.name)),
validate (not (isBlank (attr))).message (ATTRIBUTE_EMPTY, constant(attr.name))
).shortCircuit()
);
}
private Validator<Message, Context> getNullOrNotEmptyStringValidator (AttributeExpression<Message, Context, String> attr) {
return validate (
ifExp(
attr.isNull (),
constant(true),
validate (not (isBlank (attr))).message (ATTRIBUTE_EMPTY, constant(attr.name))
)
);
}
}