tim@101: package de.intevation.gnv.utils;
tim@101:
sascha@779: import com.vividsolutions.jts.geom.Coordinate;
sascha@779: import com.vividsolutions.jts.geom.GeometryFactory;
sascha@779: import com.vividsolutions.jts.geom.Point;
sascha@779:
sascha@779: import com.vividsolutions.jts.io.ParseException;
sascha@779: import com.vividsolutions.jts.io.WKTReader;
sascha@779:
sascha@779: import de.intevation.gnv.geobackend.util.DateUtils;
sascha@779:
sascha@779: import de.intevation.gnv.utils.exception.ValidationException;
sascha@779:
tim@252: import java.util.Date;
tim@252:
tim@116: import org.apache.commons.validator.GenericValidator;
tim@101:
sascha@779: import org.apache.log4j.Logger;
tim@101:
tim@101: /**
sascha@780: * @author Tim Englich
ingo@785: * @author Ingo Weinzierl
sascha@778: *
tim@101: */
tim@101: public class InputValidator {
tim@101: /**
tim@101: * the logger, used to log exceptions and additonaly information
tim@101: */
tim@101: private static Logger log = Logger.getLogger(InputValidator.class);
sascha@778:
sascha@778:
tim@222: public final static String NODATASELECTEDVALUE = "n/n";
tim@101:
tim@101: /**
tim@101: * Constructor
tim@101: */
tim@101: public InputValidator() {
tim@101: super();
tim@101: }
tim@171:
ingo@806: /**
ingo@806: * Validates the input of a range of double or date values. The input values
ingo@806: * need to be valid double or date values. minInput needs to be
ingo@806: * smaller or equal maxInput.
ingo@806: *
ingo@806: * @param minInput The lower bound.
ingo@806: * @param maxInput The upper bound.
ingo@806: * @param type One of 'Date' or 'Double'.
ingo@806: * @return true, if the input is valid, otherwise false.
ingo@806: */
ingo@785: public static boolean isInputValid(String minInput, String maxInput, String type) {
tim@252: log.debug("InputValidator.isInputValid " + minInput + " " + maxInput + " " +type);
tim@252: boolean returnValue = false;
tim@252: if ("Date".equalsIgnoreCase(type)) {
tim@252: try {
tim@252: Date min = DateUtils.getDateFromString(minInput,DateUtils.DATE_PATTERN);
tim@252: Date max = DateUtils.getDateFromString(maxInput,DateUtils.DATE_PATTERN);
tim@252: int value = max.compareTo(min);
tim@252: returnValue = value >= 0;
tim@252: } catch (Exception e) {
tim@252: log.error(e,e);
tim@252: }
tim@252: } else if ("Double".equalsIgnoreCase(type)) {
tim@252: try {
tim@252: double min = Double.parseDouble(minInput);
tim@252: double max = Double.parseDouble(maxInput);
tim@252: returnValue = max >= min;
tim@252: } catch (Exception e) {
tim@252: log.error(e,e);
tim@252: }
tim@252: }
tim@252: log.debug("Is valid? " + returnValue);
tim@252: return returnValue;
tim@252: }
sascha@778:
ingo@806: /**
ingo@806: * Validates an input.
ingo@806: *
ingo@806: * @param input The input value.
ingo@806: * @param type The input value type.
ingo@806: * @return true if the input is valid, otherwise false.
ingo@806: */
ingo@785: public static boolean isInputValid(String input, String type) {
tim@171: log.debug("InputValidator.isInputValid " + input + " " + type);
ingo@787:
sascha@803: // Let's check polygons and linestrings first, because they might
ingo@787: // contain comma. A splitting at comma characters wouldn't be good here.
ingo@787: if ("Polygon".equalsIgnoreCase(type) || "Linestring".equalsIgnoreCase(type))
ingo@787: {
ingo@787: try {
ingo@787: WKTReader reader = new WKTReader();
ingo@787: reader.read(input);
ingo@787:
ingo@787: return true;
ingo@787: }
ingo@787: catch (ParseException pe) {
ingo@787: log.warn(pe, pe);
ingo@787: return false;
ingo@787: }
ingo@787: }
ingo@787:
ingo@787: // Check all the other input here
tim@101: boolean returnValue = false;
tim@101: String[] values = input.split(",");
ingo@787:
tim@171: for (int i = 0; i < values.length; i++) {
tim@101: boolean valid;
sascha@778:
tim@222: if (NODATASELECTEDVALUE.equals(values[i].trim())){
tim@222: valid = true;
tim@222: } else if ("Integer".equalsIgnoreCase(type)) {
sascha@115: valid = GenericValidator.isInt(values[i].trim());
tim@171: } else if ("Double".equalsIgnoreCase(type)) {
tim@171: valid = GenericValidator.isDouble(values[i].trim());
tim@171: } else if ("String".equalsIgnoreCase(type)) {
tim@171: valid = GenericValidator.matchRegexp(values[i], "[a-zA-Z0-9]"); // TODO:
tim@171: // FIXME:
tim@171: // VALIDATE
tim@171: // REGEXP
tim@171: } else if ("Date".equalsIgnoreCase(type)) {
tim@171: valid = GenericValidator.isDate(values[i].trim(),
tim@171: DateUtils.DATE_PATTERN, true);
tim@731: } else if ("Point".equalsIgnoreCase(type) || "Geometry".equals(type)) {
tim@171: valid = GenericValidator.matchRegexp(values[i], "[0-9]"); // TODO:
tim@171: // FIXME:
tim@171: // VALIDATE
tim@171: // REGEXP
tim@171: } else if ("AttributeName".equalsIgnoreCase(type)) {
tim@171: valid = org.apache.commons.validator.GenericValidator
tim@171: .matchRegexp(values[i], "[a-zA-Z0-9]"); // TODO: FIXME:
tim@171: // VALIDATE
tim@171: // REGEXP
tim@173: } else if ("Coordinate".equalsIgnoreCase(type)) {
tim@173: try {
ingo@785: valid = getPointValue(values[i]) != null;
tim@173: } catch (ValidationException e) {
tim@173: log.debug(e.getMessage());
tim@173: valid = false;
tim@173: }
tim@171: } else {
tim@101: valid = false;
tim@101: }
tim@171: if (!valid) {
tim@171: returnValue = false;
tim@101: break;
tim@171: } else {
tim@101: returnValue = true;
tim@101: }
tim@101: }
tim@171: log.debug("Is valid? " + returnValue);
tim@101: return returnValue;
tim@101: }
sascha@778:
sascha@778:
ingo@806: /**
ingo@806: * Returns a point from wkt string.
ingo@806: *
ingo@806: * @param value The wkt string.
ingo@806: * @return a point.
ingo@806: * @throws ValidationException if value is not valid.
ingo@806: */
ingo@785: public static Point getPointValue(String value) throws ValidationException{
tim@173: log.debug("InputValidator.getPointValue " + value);
sascha@778:
tim@746: if (value.toLowerCase().startsWith("point")){
tim@746: try {
tim@746: return (Point)new WKTReader().read(value);
tim@746: } catch (ParseException e) {
tim@746: log.error(e,e);
tim@746: throw new ValidationException(e);
tim@746: }
tim@746: }else{
tim@746: String[] s, p;
sascha@778:
tim@746: double x=0,y=0;
tim@746: log.info("Position :"+value);
tim@746: s = value.split(" ");
tim@746: if (s.length != 2) {
tim@746: throw new ValidationException("Kein Blank separiert Breite und Länge");
tim@746: }
tim@746: p = s[0].split("[nNsS]");
tim@746: try {
tim@746: if (p.length == 1)
tim@746: y = new Double(p[0]);
tim@746: else
tim@746: y = new Double(p[0]) + new Double(p[1]) / new Double(60.);
tim@746: if (s[0].toLowerCase().contains("s"))
tim@746: y = -y;
tim@746: }
tim@746: catch (Exception e) {
tim@746: throw new ValidationException("Kein N|S oder nicht im ersten Substring, zB 56n42");
sascha@778:
sascha@778: }
tim@746: p = s[1].split("[eEwW]");
tim@746: try {
tim@746: if (p.length ==1)
tim@746: x = new Double(p[0]);
tim@746: else
tim@746: x = new Double(p[0]) + new Double(p[1]) / new Double(60.) ;
tim@746: if (s[1].toLowerCase().contains("w"))
tim@746: x = -x;
tim@746: }
tim@746: catch (Exception e) {
tim@746: throw new ValidationException("Kein E|W oder nicht im zweiten Substring");
sascha@778: }
tim@746: return new GeometryFactory().createPoint(new Coordinate(x,y));
tim@173: }
tim@173: }
tim@101:
ingo@784:
ingo@806: /**
ingo@806: * Makes sure that tmp is between lo and up.
ingo@806: *
ingo@806: * @param tmp The value to validate.
ingo@806: * @param lo The lower range bound.
ingo@806: * @param up The upper range bound.
ingo@806: * @return true, if tmp is valid, otherwise false.
ingo@806: */
ingo@785: public static boolean isDateValid(Date tmp, Date lo, Date up) {
ingo@784: // we need to transform the given dates into seconds, because
ingo@784: // they differ in milliseconds -> that's why we cannot use the
ingo@784: // Date.compareTo(Date) method.
ingo@784: long tmpTime = tmp.getTime() / 1000;
ingo@784: long tmpLow = lo.getTime() / 1000;
ingo@784: long tmpUp = up.getTime() / 1000;
ingo@784:
ingo@784: if (tmpTime < tmpLow || tmpTime > tmpUp) {
ingo@784: log.warn(
ingo@784: "Date [" + tmp.toString() + "] is out of range ["
ingo@784: + lo.toString() + " to "+ up.toString() + "].");
ingo@784: return false;
ingo@784: }
ingo@784:
ingo@784: return true;
ingo@784: }
tim@101: }
sascha@836: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :