001/* 002 * Copyright 2009-2019 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright (C) 2009-2019 Ping Identity Corporation 007 * 008 * This program is free software; you can redistribute it and/or modify 009 * it under the terms of the GNU General Public License (GPLv2 only) 010 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only) 011 * as published by the Free Software Foundation. 012 * 013 * This program is distributed in the hope that it will be useful, 014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 016 * GNU General Public License for more details. 017 * 018 * You should have received a copy of the GNU General Public License 019 * along with this program; if not, see <http://www.gnu.org/licenses>. 020 */ 021package com.unboundid.ldap.protocol; 022 023 024 025import java.util.ArrayList; 026import java.util.List; 027 028import com.unboundid.asn1.ASN1Element; 029import com.unboundid.asn1.ASN1Enumerated; 030import com.unboundid.asn1.ASN1OctetString; 031import com.unboundid.asn1.ASN1Sequence; 032import com.unboundid.asn1.ASN1StreamReader; 033import com.unboundid.ldap.sdk.LDAPException; 034import com.unboundid.ldap.sdk.LDAPResult; 035import com.unboundid.ldap.sdk.ResultCode; 036import com.unboundid.util.Debug; 037import com.unboundid.util.NotMutable; 038import com.unboundid.util.InternalUseOnly; 039import com.unboundid.util.StaticUtils; 040import com.unboundid.util.ThreadSafety; 041import com.unboundid.util.ThreadSafetyLevel; 042 043import static com.unboundid.ldap.protocol.ProtocolMessages.*; 044 045 046 047/** 048 * This class provides an implementation of a search result done protocol op. 049 */ 050@InternalUseOnly() 051@NotMutable() 052@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 053public final class SearchResultDoneProtocolOp 054 extends GenericResponseProtocolOp 055{ 056 /** 057 * The serial version UID for this serializable class. 058 */ 059 private static final long serialVersionUID = -8246922907244250622L; 060 061 062 063 /** 064 * Creates a new instance of this search result done protocol op with the 065 * provided information. 066 * 067 * @param resultCode The result code for this search result done. 068 * @param matchedDN The matched DN for this search result done, if 069 * any. 070 * @param diagnosticMessage The diagnostic message for this search result 071 * done, if any. 072 * @param referralURLs The list of referral URLs for this search result 073 * done, if any. 074 */ 075 public SearchResultDoneProtocolOp(final int resultCode, 076 final String matchedDN, 077 final String diagnosticMessage, 078 final List<String> referralURLs) 079 { 080 super(LDAPMessage.PROTOCOL_OP_TYPE_SEARCH_RESULT_DONE, resultCode, 081 matchedDN, diagnosticMessage, referralURLs); 082 } 083 084 085 086 /** 087 * Creates a new search result done protocol op from the provided LDAP result 088 * object. 089 * 090 * @param result The LDAP result object to use to create this protocol op. 091 */ 092 public SearchResultDoneProtocolOp(final LDAPResult result) 093 { 094 super(LDAPMessage.PROTOCOL_OP_TYPE_SEARCH_RESULT_DONE, 095 result.getResultCode().intValue(), result.getMatchedDN(), 096 result.getDiagnosticMessage(), 097 StaticUtils.toList(result.getReferralURLs())); 098 } 099 100 101 102 /** 103 * Creates a new search result done protocol op read from the provided ASN.1 104 * stream reader. 105 * 106 * @param reader The ASN.1 stream reader from which to read the search 107 * result done protocol op. 108 * 109 * @throws LDAPException If a problem occurs while reading or parsing the 110 * search result done. 111 */ 112 SearchResultDoneProtocolOp(final ASN1StreamReader reader) 113 throws LDAPException 114 { 115 super(reader); 116 } 117 118 119 120 /** 121 * {@inheritDoc} 122 */ 123 @Override() 124 public ASN1Element encodeProtocolOp() 125 { 126 final ArrayList<ASN1Element> elements = new ArrayList<>(4); 127 elements.add(new ASN1Enumerated(getResultCode())); 128 129 final String matchedDN = getMatchedDN(); 130 if (matchedDN == null) 131 { 132 elements.add(new ASN1OctetString()); 133 } 134 else 135 { 136 elements.add(new ASN1OctetString(matchedDN)); 137 } 138 139 final String diagnosticMessage = getDiagnosticMessage(); 140 if (diagnosticMessage == null) 141 { 142 elements.add(new ASN1OctetString()); 143 } 144 else 145 { 146 elements.add(new ASN1OctetString(diagnosticMessage)); 147 } 148 149 final List<String> referralURLs = getReferralURLs(); 150 if (! referralURLs.isEmpty()) 151 { 152 final ArrayList<ASN1Element> refElements = 153 new ArrayList<>(referralURLs.size()); 154 for (final String r : referralURLs) 155 { 156 refElements.add(new ASN1OctetString(r)); 157 } 158 elements.add(new ASN1Sequence(TYPE_REFERRALS, refElements)); 159 } 160 161 return new ASN1Sequence(LDAPMessage.PROTOCOL_OP_TYPE_SEARCH_RESULT_DONE, 162 elements); 163 } 164 165 166 167 /** 168 * Decodes the provided ASN.1 element as a search result done protocol op. 169 * 170 * @param element The ASN.1 element to be decoded. 171 * 172 * @return The decoded search result done protocol op. 173 * 174 * @throws LDAPException If the provided ASN.1 element cannot be decoded as 175 * a search result done protocol op. 176 */ 177 public static SearchResultDoneProtocolOp decodeProtocolOp( 178 final ASN1Element element) 179 throws LDAPException 180 { 181 try 182 { 183 final ASN1Element[] elements = 184 ASN1Sequence.decodeAsSequence(element).elements(); 185 final int resultCode = 186 ASN1Enumerated.decodeAsEnumerated(elements[0]).intValue(); 187 188 final String matchedDN; 189 final String md = 190 ASN1OctetString.decodeAsOctetString(elements[1]).stringValue(); 191 if (! md.isEmpty()) 192 { 193 matchedDN = md; 194 } 195 else 196 { 197 matchedDN = null; 198 } 199 200 final String diagnosticMessage; 201 final String dm = 202 ASN1OctetString.decodeAsOctetString(elements[2]).stringValue(); 203 if (! dm.isEmpty()) 204 { 205 diagnosticMessage = dm; 206 } 207 else 208 { 209 diagnosticMessage = null; 210 } 211 212 final List<String> referralURLs; 213 if (elements.length == 4) 214 { 215 final ASN1Element[] refElements = 216 ASN1Sequence.decodeAsSequence(elements[3]).elements(); 217 referralURLs = new ArrayList<>(refElements.length); 218 for (final ASN1Element e : refElements) 219 { 220 referralURLs.add( 221 ASN1OctetString.decodeAsOctetString(e).stringValue()); 222 } 223 } 224 else 225 { 226 referralURLs = null; 227 } 228 229 return new SearchResultDoneProtocolOp(resultCode, matchedDN, 230 diagnosticMessage, referralURLs); 231 } 232 catch (final Exception e) 233 { 234 Debug.debugException(e); 235 throw new LDAPException(ResultCode.DECODING_ERROR, 236 ERR_SEARCH_DONE_CANNOT_DECODE.get( 237 StaticUtils.getExceptionMessage(e)), 238 e); 239 } 240 } 241}