package nl.ipo.cds.etl.operations.transform; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import nl.ipo.cds.attributemapping.MappingSource; import nl.ipo.cds.attributemapping.operations.annotation.Execute; import nl.ipo.cds.attributemapping.operations.annotation.Input; import nl.ipo.cds.attributemapping.operations.annotation.MappingOperation; import nl.ipo.cds.etl.operations.transform.ConditionalTransform.Settings; import org.deegree.geometry.Geometry; import org.deegree.geometry.multi.MultiCurve; import org.deegree.geometry.multi.MultiGeometry; import org.deegree.geometry.multi.MultiLineString; import org.deegree.geometry.multi.MultiPoint; import org.deegree.geometry.multi.MultiPolygon; import org.deegree.geometry.multi.MultiSurface; import org.deegree.geometry.primitive.Curve; import org.deegree.geometry.primitive.Point; import org.deegree.geometry.primitive.Polygon; import org.deegree.geometry.primitive.Surface; @MappingOperation (propertiesClass = Settings.class, internal = true) public class ConditionalTransform { public final static Map<String, Class<? extends Geometry>> geometryTypeMap; static { final HashMap<String, Class<? extends Geometry>> dict = new HashMap<> (); dict.put ("curve", Curve.class); dict.put ("point", Point.class); dict.put ("surface", Surface.class); dict.put ("polygon", Polygon.class); dict.put ("multi", MultiGeometry.class); dict.put ("multiCurve", MultiCurve.class); dict.put ("multiLineString", MultiLineString.class); dict.put ("multiPoint", MultiPoint.class); dict.put ("multiSurface", MultiSurface.class); dict.put ("multiPolygon", MultiPolygon.class); geometryTypeMap = Collections.unmodifiableMap (dict); } @Execute public Object execute (final Settings settings, final MappingSource source, final @Input("values") Object ... values) { final Condition[] conditions = settings.conditions; final int conditionCount = conditions.length; if (values.length != conditionCount + 1) { throw new IllegalArgumentException (String.format ("Invalid number of arguments to conditional transform, expected %d", conditionCount + 1)); } loop: for (int i = 0; i < conditionCount; ++ i) { final Condition condition = conditions[i]; final Object attributeValue = source.getAttributeValue (condition.attribute); final Operation operation = condition.operation; switch (operation) { case IN: { if (attributeValue == null) { continue; } final String stringAttributeValue = attributeValue.toString (); for (final String s: condition.values) { if (stringAttributeValue.equals (s)) { return values[i]; } } break; } case NOT_IN: { if (attributeValue == null) { return values[i]; } final String stringAttributeValue = attributeValue.toString (); for (final String s: condition.values) { if (stringAttributeValue.equals (s)) { continue loop; } } return values[i]; } case IS_EMPTY: if (attributeValue == null || (attributeValue instanceof String && ((String)attributeValue).trim ().isEmpty ())) { return values[i]; } break; case IS_NOT_EMPTY: if (attributeValue != null && !(attributeValue instanceof String && ((String)attributeValue).trim ().isEmpty ())) { return values[i]; } break; case IS_NULL: if (attributeValue == null) { return values[i]; } break; case IS_NOT_NULL: if (attributeValue != null) { return values[i]; } break; case IS_GEOMETRY_TYPE: if (attributeValue == null || !(attributeValue instanceof Geometry)) { continue; } final Geometry geom = (Geometry)attributeValue; final Class<? extends Geometry> geomClass = geom.getClass (); for (final String typeString: condition.values) { final Class<? extends Geometry> cls = geometryTypeMap.get (typeString); if (cls == null) { continue; } if (cls.isAssignableFrom (geomClass)) { return values[i]; } } break; } } return values[conditionCount]; } public final static class Settings { Condition[] conditions = new Condition[0]; public List<Condition> getConditions() { return conditions == null ? Collections.<Condition>emptyList () : Arrays.asList (conditions); } public void setConditions (final List<Condition> conditions) { if (conditions == null) { throw new NullPointerException (); } this.conditions = conditions.toArray (new Condition[conditions.size ()]); } } public static enum Operation { IS_EMPTY, IS_NULL, IS_NOT_NULL, IS_NOT_EMPTY, IN, NOT_IN, IS_GEOMETRY_TYPE } public final static class Condition { String attribute; Operation operation = Operation.IN; String[] values; public String getAttribute () { return attribute; } public void setAttribute (final String attribute) { this.attribute = attribute; } public Operation getOperation () { return operation; } public void setOperation (final Operation operation) { this.operation = operation; } public String[] getValues () { return values; } public void setValues (final String[] values) { if (values == null) { throw new NullPointerException (); } for (final String s: values) { if (s == null) { throw new NullPointerException (); } } this.values = Arrays.copyOf (values, values.length); } } }