001 /*
002 * Copyright 2009-2016 UnboundID Corp.
003 * All Rights Reserved.
004 */
005 /*
006 * Copyright (C) 2009-2016 UnboundID Corp.
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 */
021 package com.unboundid.ldap.protocol;
022
023
024
025 import java.util.ArrayList;
026 import java.util.Collections;
027 import java.util.Iterator;
028 import java.util.List;
029
030 import com.unboundid.asn1.ASN1Buffer;
031 import com.unboundid.asn1.ASN1BufferSequence;
032 import com.unboundid.asn1.ASN1Element;
033 import com.unboundid.asn1.ASN1OctetString;
034 import com.unboundid.asn1.ASN1Sequence;
035 import com.unboundid.asn1.ASN1StreamReader;
036 import com.unboundid.asn1.ASN1StreamReaderSequence;
037 import com.unboundid.ldap.sdk.Control;
038 import com.unboundid.ldap.sdk.LDAPException;
039 import com.unboundid.ldap.sdk.ResultCode;
040 import com.unboundid.ldap.sdk.SearchResultReference;
041 import com.unboundid.util.InternalUseOnly;
042
043 import static com.unboundid.ldap.protocol.ProtocolMessages.*;
044 import static com.unboundid.util.Debug.*;
045 import static com.unboundid.util.StaticUtils.*;
046
047
048
049 /**
050 * This class provides an implementation of an LDAP search result reference
051 * protocol op.
052 */
053 @InternalUseOnly()
054 public final class SearchResultReferenceProtocolOp
055 implements ProtocolOp
056 {
057 /**
058 * The serial version UID for this serializable class.
059 */
060 private static final long serialVersionUID = -1526778443581862609L;
061
062
063
064 // The list of referral URLs for this search result reference.
065 private final List<String> referralURLs;
066
067
068
069 /**
070 * Creates a new search result reference protocol op with the provided
071 * information.
072 *
073 * @param referralURLs The list of referral URLs for this search result
074 * reference.
075 */
076 public SearchResultReferenceProtocolOp(final List<String> referralURLs)
077 {
078 this.referralURLs = Collections.unmodifiableList(referralURLs);
079 }
080
081
082
083 /**
084 * Creates a new search result reference protocol op from the provided search
085 * result reference.
086 *
087 * @param reference The search result reference to use to create this
088 * protocol op.
089 */
090 public SearchResultReferenceProtocolOp(final SearchResultReference reference)
091 {
092 referralURLs = toList(reference.getReferralURLs());
093 }
094
095
096
097 /**
098 * Creates a new search result reference protocol op read from the provided
099 * ASN.1 stream reader.
100 *
101 * @param reader The ASN.1 stream reader from which to read the search
102 * result reference protocol op.
103 *
104 * @throws LDAPException If a problem occurs while reading or parsing the
105 * search result reference.
106 */
107 SearchResultReferenceProtocolOp(final ASN1StreamReader reader)
108 throws LDAPException
109 {
110 try
111 {
112 final ArrayList<String> refs = new ArrayList<String>(5);
113 final ASN1StreamReaderSequence refSequence = reader.beginSequence();
114 while (refSequence.hasMoreElements())
115 {
116 refs.add(reader.readString());
117 }
118
119 referralURLs = Collections.unmodifiableList(refs);
120 }
121 catch (Exception e)
122 {
123 debugException(e);
124
125 throw new LDAPException(ResultCode.DECODING_ERROR,
126 ERR_SEARCH_REFERENCE_CANNOT_DECODE.get(getExceptionMessage(e)), e);
127 }
128 }
129
130
131
132 /**
133 * Retrieves the list of referral URLs for this search result reference.
134 *
135 * @return The list of referral URLs for this search result reference.
136 */
137 public List<String> getReferralURLs()
138 {
139 return referralURLs;
140 }
141
142
143
144 /**
145 * {@inheritDoc}
146 */
147 public byte getProtocolOpType()
148 {
149 return LDAPMessage.PROTOCOL_OP_TYPE_SEARCH_RESULT_REFERENCE;
150 }
151
152
153
154 /**
155 * {@inheritDoc}
156 */
157 public ASN1Element encodeProtocolOp()
158 {
159 final ArrayList<ASN1Element> urlElements =
160 new ArrayList<ASN1Element>(referralURLs.size());
161 for (final String url : referralURLs)
162 {
163 urlElements.add(new ASN1OctetString(url));
164 }
165
166 return new ASN1Sequence(
167 LDAPMessage.PROTOCOL_OP_TYPE_SEARCH_RESULT_REFERENCE,
168 urlElements);
169 }
170
171
172
173 /**
174 * Decodes the provided ASN.1 element as a search result reference protocol
175 * op.
176 *
177 * @param element The ASN.1 element to be decoded.
178 *
179 * @return The decoded search result reference protocol op.
180 *
181 * @throws LDAPException If the provided ASN.1 element cannot be decoded as
182 * a search result reference protocol op.
183 */
184 public static SearchResultReferenceProtocolOp decodeProtocolOp(
185 final ASN1Element element)
186 throws LDAPException
187 {
188 try
189 {
190 final ASN1Element[] urlElements =
191 ASN1Sequence.decodeAsSequence(element).elements();
192 final ArrayList<String> referralURLs =
193 new ArrayList<String>(urlElements.length);
194 for (final ASN1Element e : urlElements)
195 {
196 referralURLs.add(ASN1OctetString.decodeAsOctetString(e).stringValue());
197 }
198
199 return new SearchResultReferenceProtocolOp(referralURLs);
200 }
201 catch (final Exception e)
202 {
203 debugException(e);
204 throw new LDAPException(ResultCode.DECODING_ERROR,
205 ERR_SEARCH_REFERENCE_CANNOT_DECODE.get(getExceptionMessage(e)),
206 e);
207 }
208 }
209
210
211
212 /**
213 * {@inheritDoc}
214 */
215 public void writeTo(final ASN1Buffer buffer)
216 {
217 final ASN1BufferSequence opSequence = buffer.beginSequence(
218 LDAPMessage.PROTOCOL_OP_TYPE_SEARCH_RESULT_REFERENCE);
219 for (final String s : referralURLs)
220 {
221 buffer.addOctetString(s);
222 }
223 opSequence.end();
224 }
225
226
227
228 /**
229 * Creates a search result reference from this protocol op.
230 *
231 * @param controls The set of controls to include in the search result
232 * reference. It may be empty or {@code null} if no
233 * controls should be included.
234 *
235 * @return The search result reference that was created.
236 */
237 public SearchResultReference toSearchResultReference(
238 final Control... controls)
239 {
240 final String[] referralArray = new String[referralURLs.size()];
241 referralURLs.toArray(referralArray);
242
243 return new SearchResultReference(referralArray, controls);
244 }
245
246
247
248 /**
249 * Retrieves a string representation of this protocol op.
250 *
251 * @return A string representation of this protocol op.
252 */
253 @Override()
254 public String toString()
255 {
256 final StringBuilder buffer = new StringBuilder();
257 toString(buffer);
258 return buffer.toString();
259 }
260
261
262
263 /**
264 * {@inheritDoc}
265 */
266 public void toString(final StringBuilder buffer)
267 {
268 buffer.append("SearchResultReferenceProtocolOp(referralURLs={");
269
270 final Iterator<String> iterator = referralURLs.iterator();
271 while (iterator.hasNext())
272 {
273 buffer.append('\'');
274 buffer.append(iterator.next());
275 buffer.append('\'');
276 if (iterator.hasNext())
277 {
278 buffer.append(',');
279 }
280 }
281
282 buffer.append("})");
283 }
284 }