Coverage Report - org.kuali.rice.core.api.criteria.CriteriaSupportUtils
 
Classes in this File Line Coverage Branch Coverage Complexity
CriteriaSupportUtils
74%
78/105
75%
62/82
7.818
CriteriaSupportUtils$PropertyConstants
0%
0/1
N/A
7.818
 
 1  
 /**
 2  
  * Copyright 2005-2011 The Kuali Foundation
 3  
  *
 4  
  * Licensed under the Educational Community License, Version 2.0 (the "License");
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  *
 8  
  * http://www.opensource.org/licenses/ecl2.php
 9  
  *
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  
  * See the License for the specific language governing permissions and
 14  
  * limitations under the License.
 15  
  */
 16  
 package org.kuali.rice.core.api.criteria;
 17  
 
 18  
 import java.lang.reflect.Field;
 19  
 import java.lang.reflect.Method;
 20  
 import java.math.BigDecimal;
 21  
 import java.math.BigInteger;
 22  
 import java.util.ArrayList;
 23  
 import java.util.Calendar;
 24  
 import java.util.Collections;
 25  
 import java.util.Date;
 26  
 import java.util.HashSet;
 27  
 import java.util.List;
 28  
 import java.util.Set;
 29  
 import java.util.concurrent.atomic.AtomicInteger;
 30  
 import java.util.concurrent.atomic.AtomicLong;
 31  
 
 32  
 import javax.xml.bind.annotation.XmlElement;
 33  
 import javax.xml.bind.annotation.XmlElements;
 34  
 
 35  
 import org.apache.commons.lang.StringUtils;
 36  
 import org.joda.time.DateTime;
 37  
 
 38  
 /**
 39  
  * A class which includes various utilities and constants for use within the criteria API.
 40  
  * This class is intended to be for internal use only within the criteria API.
 41  
  * 
 42  
  * @author Kuali Rice Team (rice.collab@kuali.org)
 43  
  */
 44  
 final class CriteriaSupportUtils {
 45  
         
 46  0
         private CriteriaSupportUtils () {}
 47  
         
 48  
     /**
 49  
      * Defines various property constants for internal use within the criteria package.
 50  
      */
 51  0
     static class PropertyConstants {
 52  
             
 53  
             /**
 54  
              * A constant representing the property name for {@link PropertyPathPredicate#getPropertyPath()}
 55  
              */
 56  
         final static String PROPERTY_PATH = "propertyPath";
 57  
         
 58  
             /**
 59  
              * A constant representing the property name for {@link SingleValuedPredicate#getValue()}
 60  
              */
 61  
         final static String VALUE = "value";
 62  
         
 63  
         /**
 64  
          * A constant representing the method name for {@link SingleValuedPredicate#getValue()}
 65  
          */
 66  
         final static String GET_VALUE_METHOD_NAME = "getValue";
 67  
 
 68  
         /**
 69  
              * A constant representing the property name for {@link MultiValuedPredicate#getValues()}
 70  
              */
 71  
         final static String VALUES = "values";
 72  
 
 73  
         /**
 74  
          * A constant representing the method name for {@link MultiValuedPredicate#getValues()}
 75  
          */
 76  
         final static String GET_VALUES_METHOD_NAME = "getValues";
 77  
     }
 78  
 
 79  
     /**
 80  
      * Validates the various properties of a {@link SingleValuedPredicate}.
 81  
      * 
 82  
      * @param valuedPredicateClass the type of the predicate
 83  
      * @param propertyPath the propertyPath which is being configured on the predicate
 84  
      * @param value the value which is being configured on the predicate
 85  
      * 
 86  
      * @throws IllegalArgumentException if the propertPath is null or blank
 87  
      * @throws IllegalArgumentException if the value is null
 88  
      * @throws IllegalArgumentException if the given {@link SingleValuedPredicate} class does not support the {@link CriteriaValue}
 89  
      */
 90  
     static void validateValuedConstruction(Class<? extends SingleValuedPredicate> valuedPredicateClass, String propertyPath, CriteriaValue<?> value) {
 91  117
             if (StringUtils.isBlank(propertyPath)) {
 92  14
                         throw new IllegalArgumentException("Property path cannot be null or blank.");
 93  
                 }
 94  103
                 if (value == null) {
 95  1
                     throw new IllegalArgumentException("CriteriaValue cannot be null.");
 96  
                 }
 97  102
                 if (!CriteriaSupportUtils.supportsCriteriaValue(valuedPredicateClass, value)) {
 98  4
                     throw new IllegalArgumentException(valuedPredicateClass.getSimpleName() + " does not support the given CriteriaValue");
 99  
                 }
 100  98
     }
 101  
 
 102  
         static boolean supportsCriteriaValue(Class<? extends SingleValuedPredicate> simplePredicateClass, CriteriaValue<?> value) {
 103  111
             if (simplePredicateClass == null) {
 104  2
                 throw new IllegalArgumentException("simplePredicateClass was null");
 105  
             }
 106  109
             if (value == null) {
 107  1
                 throw new IllegalArgumentException("valueClass was null");
 108  
             }
 109  108
             XmlElements elementsAnnotation = CriteriaSupportUtils.findXmlElementsAnnotation(simplePredicateClass);
 110  108
             if (elementsAnnotation != null) {
 111  108
                 XmlElement[] elements = elementsAnnotation.value();
 112  214
                 for (XmlElement element : elements) {
 113  209
                     if (value.getClass().equals(element.type())) {
 114  103
                         return true;
 115  
                     }
 116  
                 }
 117  
             }
 118  5
             return false;
 119  
         }
 120  
         
 121  
         private static XmlElements findXmlElementsAnnotation(Class<?> simplePredicateClass) {
 122  108
                 if (simplePredicateClass != null) {
 123  
                         try{
 124  108
                                 Field valueField = simplePredicateClass.getDeclaredField(PropertyConstants.VALUE);
 125  108
                                 XmlElements elementsAnnotation = valueField.getAnnotation(XmlElements.class);
 126  108
                                 if (elementsAnnotation != null) {
 127  108
                                         return elementsAnnotation;
 128  
                                 }
 129  0
                         } catch (NoSuchFieldException e) {
 130  
                                 // ignore, try the method
 131  0
                         }
 132  
                         try {
 133  0
                                 Method valueMethod = simplePredicateClass.getDeclaredMethod(PropertyConstants.GET_VALUE_METHOD_NAME, (Class<?>[])null);
 134  0
                                 XmlElements elementsAnnotation = valueMethod.getAnnotation(XmlElements.class);
 135  0
                                 if (elementsAnnotation == null) {
 136  0
                                         return CriteriaSupportUtils.findXmlElementsAnnotation(simplePredicateClass.getSuperclass());
 137  
                                 }
 138  0
                                 return elementsAnnotation;
 139  0
                         } catch (NoSuchMethodException e) {
 140  0
                                 return CriteriaSupportUtils.findXmlElementsAnnotation(simplePredicateClass.getSuperclass());
 141  
                         }
 142  
                 }
 143  0
                 return null;
 144  
         }
 145  
         
 146  
         static CriteriaValue<?> determineCriteriaValue(Object object) {
 147  99
                 if (object == null) {
 148  8
                         throw new IllegalArgumentException("Given criteria value cannot be null.");
 149  91
                 } else if (object instanceof CharSequence) {
 150  40
                         return new CriteriaStringValue((CharSequence)object);
 151  51
                 } else if (object instanceof DateTime) {
 152  0
             return new CriteriaDateTimeValue((DateTime)object);
 153  51
                 } else if (object instanceof Calendar) {
 154  6
                         return new CriteriaDateTimeValue((Calendar)object);
 155  45
                 } else if (object instanceof Date) {
 156  5
                         return new CriteriaDateTimeValue((Date)object);
 157  40
                 } else if (object instanceof BigInteger) {
 158  0
                         return new CriteriaIntegerValue((BigInteger)object);
 159  40
                 } else if (object instanceof Short) {
 160  1
                         return new CriteriaIntegerValue((Short)object);
 161  39
                 } else if (object instanceof Integer) {
 162  30
                         return new CriteriaIntegerValue((Integer)object);
 163  9
                 } else if (object instanceof AtomicInteger) {
 164  0
                         return new CriteriaIntegerValue((AtomicInteger)object);
 165  9
                 } else if (object instanceof Long) {
 166  1
                         return new CriteriaIntegerValue((Long)object);
 167  8
                 } else if (object instanceof AtomicLong) {
 168  0
                         return new CriteriaIntegerValue((AtomicLong)object);
 169  8
                 } else if (object instanceof BigDecimal) {
 170  8
                         return new CriteriaDecimalValue((BigDecimal)object);
 171  0
                 } else if (object instanceof Float) {
 172  0
                         return new CriteriaDecimalValue((Float)object);
 173  0
                 } else if (object instanceof Double) {
 174  0
                         return new CriteriaDecimalValue((Double)object);
 175  
                 }
 176  0
                 throw new IllegalArgumentException("Failed to translate the given object to a CriteriaValue: " + object);
 177  
         }
 178  
         
 179  
         static Set<CriteriaValue<?>> determineCriteriaValueList(Object[] values) {
 180  17
                 if (values == null) {
 181  2
                         return null;
 182  15
                 } else if (values.length == 0) {
 183  2
                         return Collections.emptySet();
 184  
                 }
 185  13
                 Set<CriteriaValue<?>> criteriaValues = new HashSet<CriteriaValue<?>>();
 186  41
                 for (Object value : values) {
 187  28
                         if (value != null) {
 188  28
                 criteriaValues.add(determineCriteriaValue(value));
 189  
             }
 190  
                 }
 191  13
                 return criteriaValues;
 192  
         }
 193  
 
 194  
     static Set<CriteriaStringValue> createCriteriaStringValueList(CharSequence[] values) {
 195  4
                 if (values == null) {
 196  0
                         return null;
 197  4
                 } else if (values.length == 0) {
 198  0
                         return Collections.emptySet();
 199  
                 }
 200  4
                 Set<CriteriaStringValue> criteriaValues = new HashSet<CriteriaStringValue>();
 201  16
                 for (CharSequence value : values) {
 202  12
                         if (value != null) {
 203  12
                 criteriaValues.add(new CriteriaStringValue(value));
 204  
             }
 205  
                 }
 206  4
                 return criteriaValues;
 207  
         }
 208  
         
 209  
         /**
 210  
      * Validates the incoming list of CriteriaValue to ensure they are valid for a
 211  
      * {@link MultiValuedPredicate}.  To be valid, the following must be true:
 212  
      * 
 213  
      * <ol>
 214  
      *   <li>The list of values must not be null.</li>
 215  
      *   <li>The list of values must not be empty.</li>
 216  
      *   <li>The list of values must all be of the same parameterized {@link CriteriaValue} type.</li>
 217  
      * </ol>
 218  
      */
 219  
     static void validateValuesForMultiValuedPredicate(Set<? extends CriteriaValue<?>> values) {
 220  53
             if (values == null) {
 221  4
                     throw new IllegalArgumentException("Criteria values cannot be null.");
 222  49
             } else if (values.isEmpty()) {
 223  4
                     throw new IllegalArgumentException("Criteria values cannot be empty.");
 224  
             }
 225  45
             Class<?> previousType = null;
 226  45
             for (CriteriaValue<?> value : values) {
 227  125
                     Class<?> currentType = value.getClass();
 228  125
                     if (previousType != null) {
 229  80
                             if (!currentType.equals(previousType)) {
 230  2
                                     throw new IllegalArgumentException("Encountered criteria values which do not match.  One was: " + previousType + " the other was: " + currentType);
 231  
                             }
 232  
                     }
 233  123
                     previousType = currentType;
 234  123
             }
 235  43
     }
 236  
 
 237  
     static String findDynName(String name) {
 238  38
         String correctedName = StringUtils.uncapitalize(name).replace("Predicate", "");
 239  
         //null is a keyword therefore they are called isNull & isNotNull
 240  38
         if (correctedName.equals("null")) {
 241  2
             correctedName = "isNull";
 242  36
         } else if (correctedName.equals("notNull")) {
 243  2
             correctedName = "isNotNull";
 244  
         }
 245  38
         return correctedName;
 246  
     }
 247  
 
 248  
     public static String toString(SingleValuedPredicate p) {
 249  0
         return new StringBuilder(CriteriaSupportUtils.findDynName(p.getClass().getSimpleName())).append("(")
 250  
                 .append(p.getPropertyPath()).append(", ").append(p.getValue().getValue()).append(")").toString();
 251  
     }
 252  
 
 253  
     public static String toString(MultiValuedPredicate p) {
 254  0
         final List<String> values = new ArrayList<String>();
 255  0
         for (CriteriaValue<?> value : p.getValues()) {
 256  0
             values.add(value.getValue().toString());
 257  
         }
 258  
 
 259  0
         return new StringBuilder(CriteriaSupportUtils.findDynName(p.getClass().getSimpleName())).append("(")
 260  
                 .append(p.getPropertyPath()).append(", ").append("[").append(StringUtils.join(values, ", ")).append("]").append(")").toString();
 261  
     }
 262  
 }