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
010     * trunk/opends/resource/legal-notices/OpenDS.LICENSE
011     * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
012     * See the License for the specific language governing permissions
013     * and limitations under the License.
014     *
015     * When distributing Covered Code, include this CDDL HEADER in each
016     * file and include the License file at
017     * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
018     * add the following below this CDDL HEADER, with the fields enclosed
019     * by brackets "[]" replaced with your own identifying information:
020     *      Portions Copyright [yyyy] [name of copyright owner]
021     *
022     * CDDL HEADER END
023     *
024     *
025     *      Copyright 2006-2008 Sun Microsystems, Inc.
026     */
027    package org.opends.server.protocols.ldap;
028    import org.opends.messages.Message;
029    
030    
031    
032    import java.util.ArrayList;
033    import java.util.List;
034    import java.util.Iterator;
035    
036    import org.opends.server.protocols.asn1.ASN1Element;
037    import org.opends.server.protocols.asn1.ASN1OctetString;
038    import org.opends.server.protocols.asn1.ASN1Sequence;
039    import org.opends.server.types.SearchResultReference;
040    import org.opends.server.types.DebugLogLevel;
041    import org.opends.server.types.LDAPException;
042    
043    import static org.opends.server.loggers.debug.DebugLogger.*;
044    import org.opends.server.loggers.debug.DebugTracer;
045    import static org.opends.messages.ProtocolMessages.*;
046    import static org.opends.server.protocols.ldap.LDAPConstants.*;
047    import static org.opends.server.protocols.ldap.LDAPResultCode.*;
048    import static org.opends.server.util.ServerConstants.*;
049    
050    
051    
052    /**
053     * This class defines the structures and methods for an LDAP search result
054     * reference protocol op, which is used to indicate to the client that an
055     * alternate location or server may hold more matching entries.
056     */
057    public class SearchResultReferenceProtocolOp
058           extends ProtocolOp
059    {
060      /**
061       * The tracer object for the debug logger.
062       */
063      private static final DebugTracer TRACER = getTracer();
064    
065      // The set of referral URLs for this search result reference.
066      private List<String> referralURLs;
067    
068    
069    
070      /**
071       * Creates a new search result reference protocol op with the provided set of
072       * referral URLs.
073       *
074       * @param  referralURLs  The set of URLs for this search result reference.
075       */
076      public SearchResultReferenceProtocolOp(List<String> referralURLs)
077      {
078        if (referralURLs == null)
079        {
080          this.referralURLs = new ArrayList<String>();
081        }
082        else
083        {
084          this.referralURLs = referralURLs;
085        }
086      }
087    
088    
089    
090      /**
091       * Creates a new search result reference protocol op from the provided search
092       * result reference object.
093       *
094       * @param  searchReference  The search result reference object to use to
095       *                          create this search result reference protocol op.
096       */
097      public SearchResultReferenceProtocolOp(SearchResultReference searchReference)
098      {
099        referralURLs = searchReference.getReferralURLs();
100        if (referralURLs == null)
101        {
102          referralURLs = new ArrayList<String>();
103        }
104      }
105    
106    
107    
108      /**
109       * Retrieves the set of referral URLs for this search result reference
110       * protocol op.  The returned list may be altered by the caller.
111       *
112       * @return  The set of referral URLs for this search result reference protocol
113       *          op.
114       */
115      public List<String> getReferralURLs()
116      {
117        return referralURLs;
118      }
119    
120    
121    
122      /**
123       * Retrieves the BER type for this protocol op.
124       *
125       * @return  The BER type for this protocol op.
126       */
127      public byte getType()
128      {
129        return OP_TYPE_SEARCH_RESULT_REFERENCE;
130      }
131    
132    
133    
134      /**
135       * Retrieves the name for this protocol op type.
136       *
137       * @return  The name for this protocol op type.
138       */
139      public String getProtocolOpName()
140      {
141        return "Search Result Reference";
142      }
143    
144    
145    
146      /**
147       * Encodes this protocol op to an ASN.1 element suitable for including in an
148       * LDAP message.
149       *
150       * @return  The ASN.1 element containing the encoded protocol op.
151       */
152      public ASN1Element encode()
153      {
154        ArrayList<ASN1Element> elements =
155             new ArrayList<ASN1Element>(referralURLs.size());
156        for (String url : referralURLs)
157        {
158          elements.add(new ASN1OctetString(url));
159        }
160    
161        return new ASN1Sequence(OP_TYPE_SEARCH_RESULT_REFERENCE, elements);
162      }
163    
164    
165    
166      /**
167       * Decodes the provided ASN.1 element as a search result reference protocol
168       * op.
169       *
170       * @param  element  The ASN.1 element to decode.
171       *
172       * @return  The decoded search result reference protocol op.
173       *
174       * @throws  LDAPException  If a problem occurs while decoding the provided
175       *                         ASN.1 element as an LDAP search result reference
176       *                         protocol op.
177       */
178      public static SearchResultReferenceProtocolOp
179                         decodeSearchReference(ASN1Element element)
180             throws LDAPException
181      {
182        ArrayList<ASN1Element> elements;
183        try
184        {
185          elements = element.decodeAsSequence().elements();
186        }
187        catch (Exception e)
188        {
189          if (debugEnabled())
190          {
191            TRACER.debugCaught(DebugLogLevel.ERROR, e);
192          }
193    
194          Message message =
195              ERR_LDAP_SEARCH_REFERENCE_DECODE_SEQUENCE.get(String.valueOf(e));
196          throw new LDAPException(PROTOCOL_ERROR, message, e);
197        }
198    
199    
200        ArrayList<String> referralURLs = new ArrayList<String>(elements.size());
201        try
202        {
203          for (ASN1Element e : elements)
204          {
205            referralURLs.add(e.decodeAsOctetString().stringValue());
206          }
207        }
208        catch (Exception e)
209        {
210          if (debugEnabled())
211          {
212            TRACER.debugCaught(DebugLogLevel.ERROR, e);
213          }
214    
215          Message message =
216              ERR_LDAP_SEARCH_REFERENCE_DECODE_URLS.get(String.valueOf(e));
217          throw new LDAPException(PROTOCOL_ERROR, message, e);
218        }
219    
220    
221        return new SearchResultReferenceProtocolOp(referralURLs);
222      }
223    
224    
225    
226      /**
227       * Appends a string representation of this LDAP protocol op to the provided
228       * buffer.
229       *
230       * @param  buffer  The buffer to which the string should be appended.
231       */
232      public void toString(StringBuilder buffer)
233      {
234        buffer.append("SearchReference(referralURLs={");
235    
236        if (! referralURLs.isEmpty())
237        {
238          Iterator<String> iterator = referralURLs.iterator();
239          buffer.append(iterator.next());
240    
241          while (iterator.hasNext())
242          {
243            buffer.append(", ");
244            buffer.append(iterator.next());
245          }
246        }
247    
248        buffer.append("})");
249      }
250    
251    
252    
253      /**
254       * Appends a multi-line string representation of this LDAP protocol op to the
255       * provided buffer.
256       *
257       * @param  buffer  The buffer to which the information should be appended.
258       * @param  indent  The number of spaces from the margin that the lines should
259       *                 be indented.
260       */
261      public void toString(StringBuilder buffer, int indent)
262      {
263        StringBuilder indentBuf = new StringBuilder(indent);
264        for (int i=0 ; i < indent; i++)
265        {
266          indentBuf.append(' ');
267        }
268    
269        buffer.append(indentBuf);
270        buffer.append("Search Result Reference");
271        buffer.append(EOL);
272    
273        buffer.append(indentBuf);
274        buffer.append("  Referral URLs:");
275        buffer.append(EOL);
276    
277        for (String url : referralURLs)
278        {
279          buffer.append(indentBuf);
280          buffer.append("    ");
281          buffer.append(url);
282          buffer.append(EOL);
283        }
284      }
285    }
286