001/** 002 * Copyright 2005-2016 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 */ 016package org.kuali.rice.kew.api.document.search; 017 018import org.apache.commons.collections.CollectionUtils; 019import org.kuali.rice.core.api.CoreConstants; 020import org.kuali.rice.core.api.mo.AbstractDataTransferObject; 021import org.kuali.rice.core.api.mo.ModelBuilder; 022import org.kuali.rice.core.api.mo.ModelObjectUtils; 023import org.w3c.dom.Element; 024 025import javax.xml.bind.annotation.XmlAccessType; 026import javax.xml.bind.annotation.XmlAccessorType; 027import javax.xml.bind.annotation.XmlAnyElement; 028import javax.xml.bind.annotation.XmlElement; 029import javax.xml.bind.annotation.XmlElementWrapper; 030import javax.xml.bind.annotation.XmlRootElement; 031import javax.xml.bind.annotation.XmlType; 032import java.io.Serializable; 033import java.util.ArrayList; 034import java.util.Collection; 035import 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}) 053public 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}