@@ -16,6 +16,10 @@ public class TypeCasting {
1616 */
1717 public static Boolean compare (SegmentConditions condition , Object value1 , Object value2 ) {
1818
19+ if (condition .equals (SegmentConditions .MODULO )) {
20+ return compareModulo (String .valueOf (value2 ), value1 );
21+ }
22+
1923 if (isInteger (value1 ) && isInteger (value2 )) {
2024 return compare (condition , toInteger (value1 ), toInteger (value2 ));
2125 } else if (isFloat (value1 ) && isFloat (value2 )) {
@@ -65,7 +69,8 @@ public static Boolean compare(SegmentConditions condition, Comparable value1, Co
6569 */
6670 public static Double toDouble (Object number ) {
6771 try {
68- return number instanceof Double ? ((Double ) number ) : Double .parseDouble ((String ) number );
72+ String asString = String .valueOf (number );
73+ return number instanceof Double ? ((Double ) number ) : Double .parseDouble (asString );
6974 } catch (Exception nfe ) {
7075 return null ;
7176 }
@@ -87,7 +92,7 @@ public static Boolean isDouble(Object number) {
8792 */
8893 public static Float toFloat (Object number ) {
8994 try {
90- return number instanceof Float ? ((Float ) number ) : Float .parseFloat (( String ) number );
95+ return number instanceof Float ? ((Float ) number ) : Float .parseFloat (String . valueOf ( number ) );
9196 } catch (Exception nfe ) {
9297 return null ;
9398 }
@@ -109,7 +114,8 @@ public static Boolean isFloat(Object number) {
109114 */
110115 public static Integer toInteger (Object number ) {
111116 try {
112- return number instanceof Integer ? ((Integer ) number ) : Integer .valueOf ((String ) number );
117+ String asString = String .valueOf (number );
118+ return number instanceof Integer ? ((Integer ) number ) : Integer .valueOf (asString );
113119 } catch (Exception nfe ) {
114120 return null ;
115121 }
@@ -172,4 +178,26 @@ public static ComparableVersion toSemver(Object str) {
172178 public static Boolean isSemver (Object str ) {
173179 return SemanticVersioning .isSemver ((String ) str );
174180 }
181+
182+ /**
183+ * Modulo is a special case as the condition value holds both the divisor and remainder.
184+ * This method compares the conditionValue and the traitValue by dividing the traitValue
185+ * by the divisor and verifying that it correctly equals the remainder.
186+ *
187+ * @param conditionValue conditionValue in the format 'divisor|remainder'
188+ * @param traitValue the value of the matched trait
189+ * @return true if expression evaluates to true, false if unable to evaluate expression or
190+ * it evaluates to false
191+ */
192+ public static Boolean compareModulo (String conditionValue , Object traitValue ) {
193+ try {
194+ String [] divisorAndRemainder = conditionValue .split ("\\ |" );
195+ Float divisor = toFloat (divisorAndRemainder [0 ]);
196+ Float remainder = toFloat (divisorAndRemainder [1 ]);
197+
198+ return toFloat (traitValue ) % divisor == remainder ;
199+ } catch (NumberFormatException | NullPointerException e ) {
200+ return false ; // indicates that one of the values could not be case to Float.
201+ }
202+ }
175203}
0 commit comments