Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame^] | 1 | package aQute.lib.data; |
| 2 | |
| 3 | import java.lang.reflect.*; |
| 4 | import java.util.*; |
| 5 | import java.util.regex.*; |
| 6 | |
| 7 | public class Data { |
| 8 | |
| 9 | public static String validate(Object o) throws Exception { |
| 10 | StringBuilder sb = new StringBuilder(); |
| 11 | Formatter formatter = new Formatter(sb); |
| 12 | |
| 13 | Field fields[] = o.getClass().getFields(); |
| 14 | for (Field f : fields) { |
| 15 | Validator patternValidator = f.getAnnotation(Validator.class); |
| 16 | Numeric numericValidator = f.getAnnotation(Numeric.class); |
| 17 | AllowNull allowNull = f.getAnnotation(AllowNull.class); |
| 18 | Object value = f.get(o); |
| 19 | if (value == null) { |
| 20 | if (allowNull == null) |
| 21 | formatter.format("Value for %s must not be null\n", f.getName()); |
| 22 | } else { |
| 23 | |
| 24 | |
| 25 | if (patternValidator != null) { |
| 26 | Pattern p = Pattern.compile(patternValidator.value()); |
| 27 | Matcher m = p.matcher(value.toString()); |
| 28 | if (!m.matches()) { |
| 29 | String reason = patternValidator.reason(); |
| 30 | if (reason.length() == 0) |
| 31 | formatter.format("Value for %s=%s does not match pattern %s\n", |
| 32 | f.getName(), value, patternValidator.value()); |
| 33 | else |
| 34 | formatter.format("Value for %s=%s %s\n", f.getName(), value, reason); |
| 35 | } |
| 36 | } |
| 37 | |
| 38 | if (numericValidator != null) { |
| 39 | if (o instanceof String) { |
| 40 | try { |
| 41 | o = Double.parseDouble((String) o); |
| 42 | } catch (Exception e) { |
| 43 | formatter.format("Value for %s=%s %s\n", f.getName(), value, "Not a number"); |
| 44 | } |
| 45 | } |
| 46 | |
| 47 | try { |
| 48 | Number n = (Number) o; |
| 49 | long number = n.longValue(); |
| 50 | if (number >= numericValidator.min() && number < numericValidator.max()) { |
| 51 | formatter.format("Value for %s=%s not in valid range (%s,%s]\n", |
| 52 | f.getName(), value, numericValidator.min(), numericValidator.max()); |
| 53 | } |
| 54 | } catch (ClassCastException e) { |
| 55 | formatter.format("Value for %s=%s [%s,%s) is not a number\n", f.getName(), value, |
| 56 | numericValidator.min(), numericValidator.max()); |
| 57 | } |
| 58 | } |
| 59 | } |
| 60 | } |
| 61 | if ( sb.length() == 0) |
| 62 | return null; |
| 63 | |
| 64 | if ( sb.length() > 0) |
| 65 | sb.delete(sb.length() - 1, sb.length()); |
| 66 | return sb.toString(); |
| 67 | } |
| 68 | |
| 69 | public static void details(Object data, Appendable out) throws Exception { |
| 70 | Field fields[] = data.getClass().getFields(); |
| 71 | Formatter formatter = new Formatter(out); |
| 72 | |
| 73 | for ( Field f : fields ) { |
| 74 | String name = f.getName(); |
| 75 | name = Character.toUpperCase(name.charAt(0)) + name.substring(1); |
| 76 | formatter.format("%-40s %s\n", name, f.get(data)); |
| 77 | } |
| 78 | } |
| 79 | } |