001package com.plivo.api.validators; 002 003import com.plivo.api.exceptions.PlivoValidationException; 004import com.plivo.api.util.Utils; 005 006import java.lang.annotation.Annotation; 007import java.lang.reflect.Field; 008import java.lang.reflect.InvocationTargetException; 009import java.lang.reflect.Method; 010import java.util.regex.Pattern; 011 012public class Validate { 013 014 015 private static final Pattern urlPattern = Pattern.compile("(http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\\(\\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+|None)"); 016 private static final String COLON = ": "; 017 018 019 private static Object fetchValue(Field field, Object request) { 020 // Find the correct method 021 for (Method method: request.getClass().getMethods()) { 022 if (method.getName().equalsIgnoreCase(field.getName()) && field.getType().toString().equals(method.getReturnType().toString())) { 023 try { 024 return method.invoke(request); 025 } catch (IllegalAccessException | InvocationTargetException e) { 026 e.printStackTrace(); 027 } 028 } 029 } 030 return null; 031 } 032 033 private static boolean isNotAmong(String[] options, String element, boolean caseSensitive) { 034 for (String opt: options) { 035 if (!caseSensitive && opt.equalsIgnoreCase(element)) { 036 return false; 037 } else if (opt.equals(element)) { 038 return false; 039 } 040 } 041 return true; 042 } 043 044 private static String composeErrorMessage(String fieldName, String errorMessage) { 045 return fieldName + COLON + errorMessage; 046 } 047 048 public static void check(Object request) throws PlivoValidationException { 049 Field[] fields = request.getClass().getDeclaredFields(); 050 for (Field field: fields) { 051 Object value = fetchValue(field, request); 052 if (value == null) { 053 continue; 054 } 055 Annotation[] annotations = field.getAnnotations(); 056 for (Annotation annotation: annotations) { 057 if (annotation instanceof InRange) { 058 int actualValue = (int) value; 059 if ((((InRange) annotation).min() > actualValue) || (((InRange) annotation).max() < actualValue)) { 060 throw new PlivoValidationException(composeErrorMessage(field.getName(), ((InRange) annotation).message())); 061 } 062 } else if (annotation instanceof OneOf) { 063 String actualValue = (String) value; 064 if (isNotAmong(((OneOf) annotation).options(), actualValue, ((OneOf) annotation).caseSensitive())) { 065 throw new PlivoValidationException(composeErrorMessage(field.getName(), ((OneOf) annotation).message())); 066 } 067 } else if (annotation instanceof UrlValues) { 068 String actualValue = (String) value; 069 if ((!urlPattern.matcher(actualValue).matches() && isNotAmong(((UrlValues) annotation).options(), actualValue, ((UrlValues) annotation).caseSensitive()))) { 070 throw new PlivoValidationException(composeErrorMessage(field.getName(), ((UrlValues) annotation).message())); 071 } 072 } else if (annotation instanceof MultiOf) { 073 if (!(value instanceof String[])) { 074 continue; 075 } 076 String[] actualValue = (String[]) value; 077 for (String val: actualValue) { 078 if (isNotAmong(((MultiOf) annotation).options(), val, ((MultiOf) annotation).caseSensitive())) { 079 throw new PlivoValidationException(composeErrorMessage(field.getName(), ((MultiOf) annotation).message())); 080 } 081 } 082 } else if (annotation instanceof SubAccount) { 083 String actualValue = (String) value; 084 if (!Utils.isSubaccountIdValid(actualValue)) { 085 throw new PlivoValidationException(composeErrorMessage(field.getName(), ((SubAccount) annotation).message())); 086 } 087 } else if (annotation instanceof MultipleValidIntegers) { 088 if( value instanceof Integer) { 089 Integer actualValue = (Integer) value; 090 } else if ( value instanceof String){ 091 String actualValue = (String) value; 092 String []values = actualValue.split("<"); 093 for (int i=0; i<values.length; i++){ 094 try{ 095 Integer.parseInt(values[i]); 096 }catch (NumberFormatException e){ 097 throw new PlivoValidationException(composeErrorMessage(field.getName(), ((MultipleValidIntegers) annotation).message())); 098 } 099 } 100 } else{ 101 throw new PlivoValidationException(composeErrorMessage(field.getName(), ((MultipleValidIntegers) annotation).message())); 102 } 103 } 104 } 105 } 106 } 107}