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) { ingo@860: if (input.length() == 0 || input.equals("")) { ingo@860: return false; ingo@860: } ingo@860: 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@1088: // take the time in seconds to compare ingo@1088: long tmpTime = tmp.getTime() / 1000; ingo@1088: long tmpLow = lo.getTime() / 1000; ingo@1088: long tmpUp = up.getTime() / 1000; ingo@784: ingo@1088: if (log.isDebugEnabled()) { ingo@1088: log.debug("Date validation..."); ingo@1088: log.debug("-> lower bound [sec]: " + tmpLow); ingo@1088: log.debug("-> upper bound [sec]: " + tmpUp); ingo@1088: log.debug("-> input data [sec]: " + tmpTime); ingo@1088: } ingo@1088: ingo@1109: // XXX There is a buffer of 1 second for the valid range of the time. ingo@1109: if (tmpTime < (tmpLow-1) || tmpTime > (tmpUp+1)) { 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 :