Coverage Report - org.kuali.rice.core.api.criteria.QueryByCriteria
 
Classes in this File Line Coverage Branch Coverage Complexity
QueryByCriteria
0%
0/23
0%
0/12
1.944
QueryByCriteria$1
N/A
N/A
1.944
QueryByCriteria$Builder
0%
0/29
0%
0/14
1.944
QueryByCriteria$Constants
0%
0/1
N/A
1.944
QueryByCriteria$Elements
0%
0/1
N/A
1.944
 
 1  
 /*
 2  
  * Copyright 2011 The Kuali Foundation
 3  
  *
 4  
  * Licensed under the Educational Community License, Version 1.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/ecl1.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 org.kuali.rice.core.api.CoreConstants;
 19  
 import org.kuali.rice.core.api.mo.AbstractDataTransferObject;
 20  
 import org.kuali.rice.core.api.mo.ModelBuilder;
 21  
 import org.w3c.dom.Element;
 22  
 
 23  
 import javax.xml.bind.annotation.XmlAccessType;
 24  
 import javax.xml.bind.annotation.XmlAccessorType;
 25  
 import javax.xml.bind.annotation.XmlAnyElement;
 26  
 import javax.xml.bind.annotation.XmlElement;
 27  
 import javax.xml.bind.annotation.XmlElements;
 28  
 import javax.xml.bind.annotation.XmlRootElement;
 29  
 import javax.xml.bind.annotation.XmlType;
 30  
 import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
 31  
 import java.io.Serializable;
 32  
 import java.util.Arrays;
 33  
 import java.util.Collection;
 34  
 
 35  
 /**
 36  
  * Defines a criteria-based query.  Consists of a {@link Predicate} definition
 37  
  * as well as a set of additional properties which control paging and other
 38  
  * aspects of the results which should be returned from the query.
 39  
  * 
 40  
  * <p>In order to construct a new {@link QueryByCriteria}, the {@link Builder}
 41  
  * should be used.  Use the {@link PredicateFactory} to construct
 42  
  * the predicate for use by the query.
 43  
  * 
 44  
  * <p>This class specifies nothing regarding how the query will be executed.
 45  
  * It is expected that an instance will be constructed and then passed to code
 46  
  * which understands how to execute the desired query.
 47  
  * 
 48  
  * <p>This class is mapped for use by JAXB and can therefore be used by clients
 49  
  * as part of remotable service definitions.
 50  
  * 
 51  
  * @see Predicate
 52  
  * @see PredicateFactory
 53  
  * 
 54  
  * @author Kuali Rice Team (rice.collab@kuali.org)
 55  
  * 
 56  
  */
 57  
 @XmlRootElement(name = QueryByCriteria.Constants.ROOT_ELEMENT_NAME)
 58  
 @XmlAccessorType(XmlAccessType.NONE)
 59  
 @XmlType(name = QueryByCriteria.Constants.TYPE_NAME, propOrder = {
 60  
                 QueryByCriteria.Elements.PREDICATE,
 61  
                 QueryByCriteria.Elements.START_AT_INDEX,
 62  
                 QueryByCriteria.Elements.MAX_RESULTS,
 63  
                 QueryByCriteria.Elements.COUNT_FLAG,
 64  
                 CoreConstants.CommonElements.FUTURE_ELEMENTS })
 65  0
 public final class QueryByCriteria extends AbstractDataTransferObject {
 66  
 
 67  
         private static final long serialVersionUID = 2210627777648920180L;
 68  
 
 69  
     @XmlElements(value = {
 70  
         @XmlElement(name = AndPredicate.Constants.ROOT_ELEMENT_NAME, type = AndPredicate.class, required = false),
 71  
         @XmlElement(name = EqualPredicate.Constants.ROOT_ELEMENT_NAME, type = EqualPredicate.class, required = false),
 72  
         @XmlElement(name = GreaterThanPredicate.Constants.ROOT_ELEMENT_NAME, type = GreaterThanPredicate.class, required = false),
 73  
         @XmlElement(name = GreaterThanOrEqualPredicate.Constants.ROOT_ELEMENT_NAME, type = GreaterThanOrEqualPredicate.class, required = false),
 74  
         @XmlElement(name = InPredicate.Constants.ROOT_ELEMENT_NAME, type = InPredicate.class, required = false),
 75  
         @XmlElement(name = LessThanPredicate.Constants.ROOT_ELEMENT_NAME, type = LessThanPredicate.class, required = false),
 76  
         @XmlElement(name = LessThanOrEqualPredicate.Constants.ROOT_ELEMENT_NAME, type = LessThanOrEqualPredicate.class, required = false),
 77  
         @XmlElement(name = LikePredicate.Constants.ROOT_ELEMENT_NAME, type = LikePredicate.class, required = false),
 78  
         @XmlElement(name = NotEqualPredicate.Constants.ROOT_ELEMENT_NAME, type = NotEqualPredicate.class, required = false),
 79  
         @XmlElement(name = NotInPredicate.Constants.ROOT_ELEMENT_NAME, type = NotInPredicate.class, required = false),
 80  
         @XmlElement(name = NotLikePredicate.Constants.ROOT_ELEMENT_NAME, type = NotLikePredicate.class, required = false),
 81  
         @XmlElement(name = NotNullPredicate.Constants.ROOT_ELEMENT_NAME, type = NotNullPredicate.class, required = false),
 82  
         @XmlElement(name = NullPredicate.Constants.ROOT_ELEMENT_NAME, type = NullPredicate.class, required = false),
 83  
         @XmlElement(name = OrPredicate.Constants.ROOT_ELEMENT_NAME, type = OrPredicate.class, required = false)
 84  
     })
 85  
         private final Predicate predicate;
 86  
         
 87  
         @XmlElement(name = Elements.START_AT_INDEX, required = false)
 88  
         private final Integer startAtIndex;
 89  
                 
 90  
         @XmlElement(name = Elements.MAX_RESULTS, required = false)
 91  
         private final Integer maxResults;
 92  
         
 93  
         @XmlJavaTypeAdapter(CountFlag.Adapter.class)
 94  
         @XmlElement(name = Elements.COUNT_FLAG, required = true)
 95  
         private final String countFlag;
 96  
 
 97  0
         @SuppressWarnings("unused")
 98  
         @XmlAnyElement
 99  
         private final Collection<Element> _futureElements = null;
 100  
 
 101  0
         private QueryByCriteria() {
 102  0
                 this.predicate = null;
 103  0
                 this.startAtIndex = null;
 104  0
                 this.maxResults = null;
 105  0
                 this.countFlag = null;
 106  0
         }
 107  
 
 108  0
         private QueryByCriteria(Builder builder) {
 109  0
                 final Predicate[] preds = builder.predicates;
 110  0
         if (preds != null && preds.length > 1) {
 111  
             //implicit "and"
 112  0
             this.predicate = PredicateFactory.and(builder.predicates);
 113  0
         } else if (preds != null && preds.length == 1) {
 114  0
             this.predicate = builder.predicates[0];
 115  
         } else {
 116  0
             this.predicate = null;
 117  
         }
 118  
 
 119  0
                 this.startAtIndex = builder.getStartAtIndex();
 120  0
                 this.maxResults = builder.getMaxResults();
 121  0
                 this.countFlag = builder.getCountFlag() == null ? null : builder.getCountFlag().getFlag();
 122  0
         }
 123  
 
 124  
         /**
 125  
          * Returns the {@link Predicate} which will be used to execute the query.
 126  
          * 
 127  
          * @return can be null if no predicate was specified
 128  
          */
 129  
         public Predicate getPredicate() {
 130  0
                 return this.predicate;
 131  
         }
 132  
 
 133  
         /**
 134  
          * Returns the optional zero-based "start" index for rows returned.  When
 135  
          * this query is executed, this property should be read to determine the
 136  
          * first row which should be returned.  If the given index is beyond the
 137  
          * end of the result set, then the resulting query should effectively
 138  
          * return no rows (as opposed to producing an index-based out of bounds
 139  
          * error).  If the value is null, then the results should start with the
 140  
          * first row returned from the query.
 141  
          *
 142  
      * <p>
 143  
      * Will never be less than 0
 144  
      *
 145  
          * @return the starting row index requested by this query, or null if
 146  
          * the results should start at the beginning of the result set
 147  
          */
 148  
         public Integer getStartAtIndex() {
 149  0
                 return this.startAtIndex;
 150  
         }
 151  
 
 152  
         /**
 153  
          * Returns the maximum number of results that this query is requesting
 154  
          * to receive.  If null, then the query should return all rows, or as
 155  
          * many as it can.  If the number request is larger than the number of
 156  
      * results then all results are returned.
 157  
          *
 158  
      * <p>
 159  
      * Will never be less than 0
 160  
      *
 161  
          * @return the maximum number of results to return from the query
 162  
          */
 163  
         public Integer getMaxResults() {
 164  0
                 return this.maxResults;
 165  
         }
 166  
 
 167  
         /**
 168  
          * Indicates whether or not a total row count should be returned with the
 169  
          * query.  See {@link CountFlag} for more information on what each of these
 170  
          * flags means.  This will never return null and defaults to
 171  
          * {@link CountFlag#NONE}.
 172  
          * 
 173  
          * @return the flag specifying whether or not a total row count should be
 174  
          * produced by the query
 175  
          */
 176  
         public CountFlag getCountFlag() {
 177  0
                 return this.countFlag == null ? null : CountFlag.valueOf(this.countFlag);
 178  
         }
 179  
 
 180  0
         public static final class Builder implements ModelBuilder, Serializable {
 181  
 
 182  
                 private Predicate[] predicates;
 183  
                 private Integer startAtIndex;
 184  
                 private Integer maxResults;
 185  
                 private CountFlag countFlag;
 186  
 
 187  0
                 private Builder() {
 188  0
                         this.countFlag = CountFlag.NONE;
 189  0
                 }
 190  
 
 191  
                 public static Builder create() {
 192  0
             return new Builder();
 193  
                 }
 194  
 
 195  
                 public Integer getStartAtIndex() {
 196  0
             return this.startAtIndex;
 197  
                 }
 198  
 
 199  
                 public void setStartAtIndex(Integer startAtIndex) {
 200  0
             if (startAtIndex != null && startAtIndex < 0) {
 201  0
                 throw new IllegalArgumentException("startAtIndex < 0");
 202  
             }
 203  
 
 204  0
             this.startAtIndex = startAtIndex;
 205  0
                 }
 206  
 
 207  
                 public Integer getMaxResults() {
 208  0
                         return this.maxResults;
 209  
                 }
 210  
 
 211  
                 public void setMaxResults(Integer maxResults) {
 212  0
                         if (maxResults != null && maxResults < 0) {
 213  0
                 throw new IllegalArgumentException("maxResults < 0");
 214  
             }
 215  
 
 216  0
             this.maxResults = maxResults;
 217  0
                 }
 218  
 
 219  
                 public CountFlag getCountFlag() {
 220  0
                         return this.countFlag;
 221  
                 }
 222  
 
 223  
                 public void setCountFlag(CountFlag countFlag) {
 224  0
                         if (countFlag == null) {
 225  0
                 throw new IllegalArgumentException("countFlag was null");
 226  
             }
 227  
 
 228  0
             this.countFlag = countFlag;
 229  0
                 }
 230  
 
 231  
         /**
 232  
          * will return an array of the predicates.  may return null if no predicates were set.
 233  
          * @return the predicates
 234  
          */
 235  
                 public Predicate[] getPredicates() {
 236  0
                         if (this.predicates == null) {
 237  0
                 return null;
 238  
             }
 239  
 
 240  
                         //defensive copies on array
 241  0
             return Arrays.copyOf(predicates, predicates.length);
 242  
                 }
 243  
 
 244  
         /**
 245  
          * Sets the predicates. If multiple predicates are specified then they are wrapped
 246  
          * in an "and" predicate. If a null predicate is specified then there will be no
 247  
          * constraints on the query.
 248  
          * @param predicates the predicates to set.
 249  
          */
 250  
         public void setPredicates(Predicate... predicates) {
 251  
             //defensive copies on array
 252  0
             this.predicates = predicates != null ? Arrays.copyOf(predicates, predicates.length) : null;
 253  0
                 }
 254  
 
 255  
         @Override
 256  
         public QueryByCriteria build() {
 257  0
             return new QueryByCriteria(this);
 258  
         }
 259  
 
 260  
         /** convenience method to create an immutable criteria from one or more predicates. */
 261  
         public static QueryByCriteria fromPredicates(Predicate... predicates) {
 262  0
             final Builder b = Builder.create();
 263  0
             b.setPredicates(predicates);
 264  0
             return b.build();
 265  
         }
 266  
     }
 267  
 
 268  
         /**
 269  
          * Defines some internal constants used on this class.
 270  
          */
 271  0
         static class Constants {
 272  
                 final static String ROOT_ELEMENT_NAME = "queryByCriteria";
 273  
                 final static String TYPE_NAME = "QueryByCriteriaType";
 274  
         }
 275  
 
 276  
         /**
 277  
          * A private class which exposes constants which define the XML element
 278  
          * names to use when this object is marshaled to XML.
 279  
          */
 280  0
         static class Elements {
 281  
                 final static String PREDICATE = "predicate";
 282  
                 final static String START_AT_INDEX = "startAtIndex";
 283  
                 final static String MAX_RESULTS = "maxResults";
 284  
                 final static String COUNT_FLAG = "countFlag";
 285  
         }
 286  
 
 287  
 }