001 /**
002 * Copyright 2005-2014 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package org.kuali.rice.kew.api.document.search;
017
018 import org.apache.commons.collections.CollectionUtils;
019 import org.kuali.rice.core.api.CoreConstants;
020 import org.kuali.rice.core.api.mo.AbstractDataTransferObject;
021 import org.kuali.rice.core.api.mo.ModelBuilder;
022 import org.kuali.rice.core.api.mo.ModelObjectUtils;
023 import org.w3c.dom.Element;
024
025 import javax.xml.bind.annotation.XmlAccessType;
026 import javax.xml.bind.annotation.XmlAccessorType;
027 import javax.xml.bind.annotation.XmlAnyElement;
028 import javax.xml.bind.annotation.XmlElement;
029 import javax.xml.bind.annotation.XmlElementWrapper;
030 import javax.xml.bind.annotation.XmlRootElement;
031 import javax.xml.bind.annotation.XmlType;
032 import java.io.Serializable;
033 import java.util.ArrayList;
034 import java.util.Collection;
035 import java.util.List;
036
037 /**
038 * An immutable data transfer object implementation of the {@link DocumentSearchResultsContract}. Instances of this
039 * class should be constructed using the nested {@link Builder} class.
040 *
041 * @author Kuali Rice Team (rice.collab@kuali.org)
042 */
043 @XmlRootElement(name = DocumentSearchResults.Constants.ROOT_ELEMENT_NAME)
044 @XmlAccessorType(XmlAccessType.NONE)
045 @XmlType(name = DocumentSearchResults.Constants.TYPE_NAME, propOrder = {
046 DocumentSearchResults.Elements.SEARCH_RESULTS,
047 DocumentSearchResults.Elements.CRITERIA,
048 DocumentSearchResults.Elements.CRITERIA_MODIFIED,
049 DocumentSearchResults.Elements.OVER_THRESHOLD,
050 DocumentSearchResults.Elements.NUMBER_OF_SECURITY_FILTERED_RESULTS,
051 CoreConstants.CommonElements.FUTURE_ELEMENTS
052 })
053 public final class DocumentSearchResults extends AbstractDataTransferObject implements DocumentSearchResultsContract {
054
055 @XmlElementWrapper(name = Elements.SEARCH_RESULTS, required = true)
056 @XmlElement(name = Elements.SEARCH_RESULT, required = false)
057 private final List<DocumentSearchResult> searchResults;
058
059 @XmlElement(name = Elements.CRITERIA, required = true)
060 private final DocumentSearchCriteria criteria;
061
062 @XmlElement(name = Elements.CRITERIA_MODIFIED, required = true)
063 private final boolean criteriaModified;
064
065 @XmlElement(name = Elements.OVER_THRESHOLD, required = true)
066 private final boolean overThreshold;
067
068 @XmlElement(name = Elements.NUMBER_OF_SECURITY_FILTERED_RESULTS, required = true)
069 private final int numberOfSecurityFilteredResults;
070
071 @SuppressWarnings("unused")
072 @XmlAnyElement
073 private final Collection<Element> _futureElements = null;
074
075 /**
076 * Private constructor used only by JAXB.
077 */
078 @SuppressWarnings("unused")
079 private DocumentSearchResults() {
080 this.searchResults = null;
081 this.criteria = null;
082 this.criteriaModified = false;
083 this.overThreshold = false;
084 this.numberOfSecurityFilteredResults = 0;
085 }
086
087 private DocumentSearchResults(Builder builder) {
088 this.searchResults = ModelObjectUtils.buildImmutableCopy(builder.getSearchResults());
089 this.criteria = builder.getCriteria().build();
090 this.criteriaModified = builder.isCriteriaModified();
091 this.overThreshold = builder.isOverThreshold();
092 this.numberOfSecurityFilteredResults = builder.getNumberOfSecurityFilteredResults();
093 }
094
095 @Override
096 public List<DocumentSearchResult> getSearchResults() {
097 return this.searchResults;
098 }
099
100 @Override
101 public DocumentSearchCriteria getCriteria() {
102 return this.criteria;
103 }
104
105 @Override
106 public boolean isCriteriaModified() {
107 return this.criteriaModified;
108 }
109
110 @Override
111 public boolean isOverThreshold() {
112 return this.overThreshold;
113 }
114
115 @Override
116 public int getNumberOfSecurityFilteredResults() {
117 return this.numberOfSecurityFilteredResults;
118 }
119
120 /**
121 * A builder which can be used to construct {@link DocumentSearchResults} instances. Enforces the constraints of
122 * the {@link DocumentSearchResultsContract}.
123 */
124 public final static class Builder implements Serializable, ModelBuilder, DocumentSearchResultsContract {
125
126 private List<DocumentSearchResult.Builder> searchResults;
127 private DocumentSearchCriteria.Builder criteria;
128 private boolean criteriaModified;
129 private boolean overThreshold;
130 private int numberOfSecurityFilteredResults;
131
132 private Builder(DocumentSearchCriteria.Builder criteria) {
133 setSearchResults(new ArrayList<DocumentSearchResult.Builder>());
134 setCriteria(criteria);
135 setCriteriaModified(false);
136 setOverThreshold(false);
137 setNumberOfSecurityFilteredResults(0);
138
139 }
140
141 /**
142 * Create a builder for the document search result and initialize it with the given document search criteria
143 * builder. Additionally initializes {@code criteriaModified} to "false", {@code overThreshold} to "false",
144 * and {@code numberOfSecurityFilteredResults} to 0.
145 *
146 * @param criteria the document search criteria builder with which to initialize the returned builder instance
147 *
148 * @return a builder instance initialized with the given document search criteria builder
149 *
150 * @throws IllegalArgumentException if the given document search criteria builder is null
151 */
152 public static Builder create(DocumentSearchCriteria.Builder criteria) {
153 return new Builder(criteria);
154 }
155
156 /**
157 * Creates a new builder instance initialized with copies of the properties from the given contract.
158 *
159 * @param contract the contract from which to copy properties
160 *
161 * @return a builder instance initialized with properties from the given contract
162 *
163 * @throws IllegalArgumentException if the given contract is null
164 */
165 public static Builder create(DocumentSearchResultsContract contract) {
166 if (contract == null) {
167 throw new IllegalArgumentException("contract was null");
168 }
169 Builder builder = create(DocumentSearchCriteria.Builder.create(contract.getCriteria()));
170 if (!CollectionUtils.isEmpty(contract.getSearchResults())) {
171 for (DocumentSearchResultContract searchResultContract : contract.getSearchResults()) {
172 builder.getSearchResults().add(DocumentSearchResult.Builder.create(searchResultContract));
173 }
174 }
175 builder.setCriteriaModified(contract.isCriteriaModified());
176 builder.setOverThreshold(contract.isOverThreshold());
177 builder.setNumberOfSecurityFilteredResults(contract.getNumberOfSecurityFilteredResults());
178 return builder;
179 }
180
181 public DocumentSearchResults build() {
182 return new DocumentSearchResults(this);
183 }
184
185 @Override
186 public List<DocumentSearchResult.Builder> getSearchResults() {
187 return this.searchResults;
188 }
189
190 @Override
191 public DocumentSearchCriteria.Builder getCriteria() {
192 return this.criteria;
193 }
194
195 @Override
196 public boolean isCriteriaModified() {
197 return this.criteriaModified;
198 }
199
200 @Override
201 public boolean isOverThreshold() {
202 return this.overThreshold;
203 }
204
205 @Override
206 public int getNumberOfSecurityFilteredResults() {
207 return this.numberOfSecurityFilteredResults;
208 }
209
210 public void setSearchResults(List<DocumentSearchResult.Builder> searchResults) {
211 this.searchResults = searchResults;
212 }
213
214 /**
215 * Sets the criteria builder on this builder to the given value.
216 *
217 * @param criteria the criteria builder to set, must not be null
218 *
219 * @throws IllegalArgumentException if criteria is null
220 */
221 public void setCriteria(DocumentSearchCriteria.Builder criteria) {
222 if (criteria == null) {
223 throw new IllegalArgumentException("criteria was null");
224 }
225 this.criteria = criteria;
226 }
227
228 public void setCriteriaModified(boolean criteriaModified) {
229 this.criteriaModified = criteriaModified;
230 }
231
232 public void setOverThreshold(boolean overThreshold) {
233 this.overThreshold = overThreshold;
234 }
235
236 public void setNumberOfSecurityFilteredResults(int numberOfSecurityFilteredResults) {
237 this.numberOfSecurityFilteredResults = numberOfSecurityFilteredResults;
238 }
239
240 }
241
242 /**
243 * Defines some internal constants used on this class.
244 */
245 static class Constants {
246 final static String ROOT_ELEMENT_NAME = "documentSearchResults";
247 final static String TYPE_NAME = "DocumentSearchResultsType";
248 }
249
250 /**
251 * A private class which exposes constants which define the XML element names to use when this object is marshalled to XML.
252 */
253 static class Elements {
254 final static String SEARCH_RESULTS = "searchResults";
255 final static String SEARCH_RESULT = "searchResult";
256 final static String CRITERIA = "criteria";
257 final static String CRITERIA_MODIFIED = "criteriaModified";
258 final static String OVER_THRESHOLD = "overThreshold";
259 final static String NUMBER_OF_SECURITY_FILTERED_RESULTS = "numberOfSecurityFilteredResults";
260 }
261
262 }