View Javadoc
1   /**
2    * Copyright 2005-2015 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.util.Collection;
19  
20  import javax.xml.bind.annotation.XmlAccessType;
21  import javax.xml.bind.annotation.XmlAccessorType;
22  import javax.xml.bind.annotation.XmlAnyElement;
23  import javax.xml.bind.annotation.XmlAttribute;
24  import javax.xml.bind.annotation.XmlElement;
25  import javax.xml.bind.annotation.XmlElements;
26  import javax.xml.bind.annotation.XmlRootElement;
27  import javax.xml.bind.annotation.XmlType;
28  
29  import org.apache.commons.lang3.StringUtils;
30  import org.kuali.rice.core.api.CoreConstants;
31  import org.w3c.dom.Element;
32  
33  /**
34   * An immutable predicate which represents an "WHERE EXISTS" statement.
35   *
36   * This implementation assumes that there is a single field which can be related
37   * between the inner and outer queries.  An equality between those fields is
38   * automatically added to the predicates of the inner query.
39   *
40   * @see PredicateFactory for a convenient way to construct this class.
41   *
42   * @author Kuali Rice Team (rice.collab@kuali.org)
43   * @since Rice 2.4.2
44   *
45   */
46  @XmlRootElement(name = ExistsSubQueryPredicate.Constants.ROOT_ELEMENT_NAME)
47  @XmlAccessorType(XmlAccessType.NONE)
48  @XmlType(name = ExistsSubQueryPredicate.Constants.TYPE_NAME, propOrder = {
49      ExistsSubQueryPredicate.Elements.SUB_QUERY_PREDICATE,
50      CoreConstants.CommonElements.FUTURE_ELEMENTS
51  })
52  public final class ExistsSubQueryPredicate extends AbstractPredicate implements SubQueryPredicate {
53  
54  	private static final long serialVersionUID = 2397296074921454859L;
55  
56      @XmlAttribute(name = Elements.SUB_QUERY_TYPE, required = true)
57  	protected String subQueryType;
58  
59      @XmlElements(value = {
60              @XmlElement(name = AndPredicate.Constants.ROOT_ELEMENT_NAME, type = AndPredicate.class, required = false),
61              @XmlElement(name = EqualPredicate.Constants.ROOT_ELEMENT_NAME, type = EqualPredicate.class, required = false),
62              @XmlElement(name = EqualIgnoreCasePredicate.Constants.ROOT_ELEMENT_NAME, type = EqualIgnoreCasePredicate.class, required = false),
63              @XmlElement(name = ExistsSubQueryPredicate.Constants.ROOT_ELEMENT_NAME, type = ExistsSubQueryPredicate.class, required = false),
64              @XmlElement(name = GreaterThanPredicate.Constants.ROOT_ELEMENT_NAME, type = GreaterThanPredicate.class, required = false),
65              @XmlElement(name = GreaterThanOrEqualPredicate.Constants.ROOT_ELEMENT_NAME, type = GreaterThanOrEqualPredicate.class, required = false),
66              @XmlElement(name = InPredicate.Constants.ROOT_ELEMENT_NAME, type = InPredicate.class, required = false),
67              @XmlElement(name = InIgnoreCasePredicate.Constants.ROOT_ELEMENT_NAME, type = InIgnoreCasePredicate.class, required = false),
68              @XmlElement(name = LessThanPredicate.Constants.ROOT_ELEMENT_NAME, type = LessThanPredicate.class, required = false),
69              @XmlElement(name = LessThanOrEqualPredicate.Constants.ROOT_ELEMENT_NAME, type = LessThanOrEqualPredicate.class, required = false),
70              @XmlElement(name = LikePredicate.Constants.ROOT_ELEMENT_NAME, type = LikePredicate.class, required = false),
71              @XmlElement(name = LikeIgnoreCasePredicate.Constants.ROOT_ELEMENT_NAME, type = LikeIgnoreCasePredicate.class, required = false),
72              @XmlElement(name = NotEqualPredicate.Constants.ROOT_ELEMENT_NAME, type = NotEqualPredicate.class, required = false),
73              @XmlElement(name = NotEqualIgnoreCasePredicate.Constants.ROOT_ELEMENT_NAME, type = NotEqualIgnoreCasePredicate.class, required = false),
74              @XmlElement(name = NotInPredicate.Constants.ROOT_ELEMENT_NAME, type = NotInPredicate.class, required = false),
75              @XmlElement(name = NotInIgnoreCasePredicate.Constants.ROOT_ELEMENT_NAME, type = NotInIgnoreCasePredicate.class, required = false),
76              @XmlElement(name = NotLikeIgnoreCasePredicate.Constants.ROOT_ELEMENT_NAME, type = NotLikeIgnoreCasePredicate.class, required = false),
77              @XmlElement(name = NotLikePredicate.Constants.ROOT_ELEMENT_NAME, type = NotLikePredicate.class, required = false),
78              @XmlElement(name = NotNullPredicate.Constants.ROOT_ELEMENT_NAME, type = NotNullPredicate.class, required = false),
79              @XmlElement(name = NullPredicate.Constants.ROOT_ELEMENT_NAME, type = NullPredicate.class, required = false),
80              @XmlElement(name = OrPredicate.Constants.ROOT_ELEMENT_NAME, type = OrPredicate.class, required = false)
81          })
82  	protected Predicate subQueryPredicate;
83  
84      @XmlAnyElement
85      private final Collection<Element> _futureElements = null;
86  
87  	/**
88       * Should only be invoked by JAXB.
89       */
90      @SuppressWarnings("unused")
91      private ExistsSubQueryPredicate() {
92      }
93  
94      public ExistsSubQueryPredicate(String subQueryType, Predicate subQueryPredicate) {
95          super();
96          if ( StringUtils.isBlank(subQueryType) ) {
97              throw new IllegalArgumentException("subQueryType is required");
98          }
99          this.subQueryType = subQueryType;
100         this.subQueryPredicate = subQueryPredicate;
101     }
102 
103     @Override
104     public String getSubQueryType() {
105         return this.subQueryType;
106     }
107 
108     @Override
109     public Predicate getSubQueryPredicate() {
110         return this.subQueryPredicate;
111     }
112 
113     @Override
114     public String toString() {
115         return new StringBuilder(CriteriaSupportUtils.findDynName(this.getClass().getSimpleName()))
116                 .append("(").append(getSubQueryType())
117                 .append(" WHERE ").append(getSubQueryPredicate())
118                 .append(")").toString();
119     }
120     /**
121      * Defines some internal constants used on this class.
122      */
123     static class Constants {
124         final static String ROOT_ELEMENT_NAME = "existsSubQuery";
125         final static String TYPE_NAME = "ExistsSubQueryType";
126     }
127 
128     /**
129      * A private class which exposes constants which define the XML element
130      * names to use when this object is marshaled to XML.
131      */
132     static class Elements {
133         final static String SUB_QUERY_TYPE = "subQueryType";
134         final static String SUB_QUERY_PREDICATE = "subQueryPredicate";
135     }
136 }