001/* 002 * CDDL HEADER START 003 * 004 * The contents of this file are subject to the terms of the 005 * Common Development and Distribution License, Version 1.0 only 006 * (the "License"). You may not use this file except in compliance 007 * with the License. 008 * 009 * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt 010 * or http://forgerock.org/license/CDDLv1.0.html. 011 * See the License for the specific language governing permissions 012 * and limitations under the License. 013 * 014 * When distributing Covered Code, include this CDDL HEADER in each 015 * file and include the License file at legal-notices/CDDLv1_0.txt. 016 * If applicable, add the following below this CDDL HEADER, with the 017 * fields enclosed by brackets "[]" replaced with your own identifying 018 * information: 019 * Portions Copyright [yyyy] [name of copyright owner] 020 * 021 * CDDL HEADER END 022 * 023 * 024 * Copyright 2006-2008 Sun Microsystems, Inc. 025 * Portions Copyright 2013-2015 ForgeRock AS 026 */ 027package org.opends.server.protocols.internal; 028 029import java.util.LinkedList; 030import java.util.List; 031import java.util.Set; 032 033import org.forgerock.opendj.ldap.DereferenceAliasesPolicy; 034import org.forgerock.opendj.ldap.SearchScope; 035import org.opends.server.api.ClientConnection; 036import org.opends.server.core.SearchOperationBasis; 037import org.opends.server.types.*; 038 039/** 040 * This class defines a subclass of the core search operation that is 041 * to be used for internal searches. The primary difference between 042 * this class and the core search operation is that the search entries 043 * and references will be queued in memory rather than sent to a 044 * client since there is no real client. 045 */ 046@org.opends.server.types.PublicAPI( 047 stability=org.opends.server.types.StabilityLevel.UNCOMMITTED, 048 mayInstantiate=true, 049 mayExtend=false, 050 mayInvoke=true) 051public final class InternalSearchOperation 052 extends SearchOperationBasis 053{ 054 /** The internal search listener for this search, if one was provided. */ 055 private InternalSearchListener searchListener; 056 057 /** The set of matching entries returned for this search. */ 058 private LinkedList<SearchResultEntry> entryList; 059 060 /** The set of search references returned for this search. */ 061 private List<SearchResultReference> referenceList; 062 063 /** 064 * Creates a new internal search operation with the provided information. 065 * 066 * @param internalConnection 067 * The internal client connection with which this internal search 068 * operation is associated. 069 * @param operationID 070 * The operation ID for this internal search. 071 * @param messageID 072 * The message ID for this internal search. 073 * @param request 074 * The search request 075 */ 076 public InternalSearchOperation(ClientConnection internalConnection, long operationID, int messageID, 077 SearchRequest request) 078 { 079 this(internalConnection, operationID, messageID, request, null); 080 } 081 082 /** 083 * Creates a new internal search operation with the provided information. 084 * 085 * @param internalConnection The internal client connection with 086 * which this internal search operation 087 * is associated. 088 * @param operationID The operation ID for this internal 089 * search. 090 * @param messageID The message ID for this internal 091 * search. 092 * @param request The search request 093 * @param searchListener The internal search listener that 094 * should be used to process the 095 * results, or <CODE>null</CODE> if 096 * they should be collected internally. 097 */ 098 public InternalSearchOperation(ClientConnection internalConnection, long operationID, int messageID, 099 SearchRequest request, InternalSearchListener searchListener) 100 { 101 this(internalConnection, operationID, messageID, 102 request.getControls(), 103 request.getName(), request.getScope(), 104 request.getDereferenceAliasesPolicy(), 105 request.getSizeLimit(), request.getTimeLimit(), request.isTypesOnly(), 106 request.getFilter(), request.getAttributes(), 107 searchListener); 108 } 109 110 private InternalSearchOperation( 111 ClientConnection internalConnection, 112 long operationID, int messageID, 113 List<Control> requestControls, DN baseDN, 114 SearchScope scope, DereferenceAliasesPolicy derefPolicy, 115 int sizeLimit, int timeLimit, boolean typesOnly, 116 SearchFilter filter, Set<String> attributes, 117 InternalSearchListener searchListener) 118 { 119 super(internalConnection, operationID, messageID, requestControls, 120 baseDN, scope, derefPolicy, sizeLimit, timeLimit, 121 typesOnly, filter, attributes); 122 123 124 125 126 if (searchListener == null) 127 { 128 this.searchListener = null; 129 this.entryList = new LinkedList<>(); 130 this.referenceList = new LinkedList<>(); 131 } 132 else 133 { 134 this.searchListener = searchListener; 135 this.entryList = null; 136 this.referenceList = null; 137 } 138 139 setInternalOperation(true); 140 } 141 142 /** 143 * Retrieves the set of search result entries returned for this 144 * search. 145 * 146 * @return The set of search result entries returned for this 147 * search, or <CODE>null</CODE> if a custom internal search 148 * listener is to be used. 149 */ 150 public LinkedList<SearchResultEntry> getSearchEntries() 151 { 152 return entryList; 153 } 154 155 156 157 /** 158 * Provides the provided search result entry to the internal search 159 * listener if one was provided, or stores it in an internal list 160 * otherwise. 161 * 162 * @param searchEntry The search result entry returned for this 163 * search. 164 * 165 * @throws DirectoryException If a problem occurs while processing 166 * the provided entry and the search 167 * should be terminated. 168 */ 169 @org.opends.server.types.PublicAPI( 170 stability=org.opends.server.types.StabilityLevel.PRIVATE, 171 mayInstantiate=false, 172 mayExtend=false, 173 mayInvoke=false) 174 public void addSearchEntry(SearchResultEntry searchEntry) 175 throws DirectoryException 176 { 177 if (searchListener == null) 178 { 179 entryList.add(searchEntry); 180 } 181 else 182 { 183 searchListener.handleInternalSearchEntry(this, searchEntry); 184 } 185 } 186 187 188 189 /** 190 * Retrieves the set of search result references returned for this 191 * search. 192 * 193 * @return The set of search result references returned for this 194 * search, or <CODE>null</CODE> if a custom internal search 195 * listener is to be used. 196 */ 197 public List<SearchResultReference> getSearchReferences() 198 { 199 return referenceList; 200 } 201 202 203 204 /** 205 * Provides the provided search result reference to the internal 206 * search listener if one was provided, or stores it in an internal 207 * list otherwise. 208 * 209 * @param searchReference The search result reference returned for 210 * this search. 211 * 212 * @throws DirectoryException If a problem occurs while processing 213 * the provided reference and the 214 * search should be terminated. 215 */ 216 @org.opends.server.types.PublicAPI( 217 stability=org.opends.server.types.StabilityLevel.PRIVATE, 218 mayInstantiate=false, 219 mayExtend=false, 220 mayInvoke=false) 221 public void addSearchReference( 222 SearchResultReference searchReference) 223 throws DirectoryException 224 { 225 if (searchListener == null) 226 { 227 referenceList.add(searchReference); 228 } 229 else 230 { 231 searchListener.handleInternalSearchReference(this, 232 searchReference); 233 } 234 } 235 236 237 238 /** 239 * Sends the provided search result entry to the client. 240 * 241 * @param searchEntry The search result entry to be sent to the 242 * client. 243 * 244 * @throws DirectoryException If a problem occurs while attempting 245 * to send the entry to the client and 246 * the search should be terminated. 247 */ 248 @org.opends.server.types.PublicAPI( 249 stability=org.opends.server.types.StabilityLevel.PRIVATE, 250 mayInstantiate=false, 251 mayExtend=false, 252 mayInvoke=false) 253 @Override 254 public void sendSearchEntry(SearchResultEntry searchEntry) 255 throws DirectoryException 256 { 257 addSearchEntry(searchEntry); 258 } 259 260 261 262 /** 263 * Sends the provided search result reference to the client. 264 * 265 * @param searchReference The search result reference to be sent 266 * to the client. 267 * 268 * @return {@code true} if the client is able to accept referrals, 269 * or {@code false} if the client cannot handle referrals 270 * and no more attempts should be made to send them for the 271 * associated search operation. 272 * 273 * @throws DirectoryException If a problem occurs while attempting 274 * to send the reference to the client 275 * and the search should be terminated. 276 */ 277 @org.opends.server.types.PublicAPI( 278 stability=org.opends.server.types.StabilityLevel.PRIVATE, 279 mayInstantiate=false, 280 mayExtend=false, 281 mayInvoke=false) 282 @Override 283 public boolean sendSearchReference( 284 SearchResultReference searchReference) 285 throws DirectoryException 286 { 287 addSearchReference(searchReference); 288 return true; 289 } 290} 291