View Javadoc
1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    *  
10   *    http://www.apache.org/licenses/LICENSE-2.0
11   *  
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License. 
18   *  
19   */
20  package org.apache.directory.api.ldap.codec.decorators;
21  
22  
23  import java.nio.BufferOverflowException;
24  import java.nio.ByteBuffer;
25  
26  import org.apache.directory.api.asn1.EncoderException;
27  import org.apache.directory.api.asn1.ber.tlv.BerValue;
28  import org.apache.directory.api.asn1.ber.tlv.TLV;
29  import org.apache.directory.api.i18n.I18n;
30  import org.apache.directory.api.ldap.codec.api.LdapApiService;
31  import org.apache.directory.api.ldap.codec.api.LdapCodecConstants;
32  import org.apache.directory.api.ldap.codec.api.LdapEncoder;
33  import org.apache.directory.api.ldap.codec.api.MessageDecorator;
34  import org.apache.directory.api.ldap.model.message.Referral;
35  import org.apache.directory.api.ldap.model.message.SearchResultReference;
36  
37  
38  /**
39   * A decorator for the SearchResultReference message
40   *
41   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
42   */
43  public class SearchResultReferenceDecorator extends MessageDecorator<SearchResultReference>
44      implements SearchResultReference
45  {
46      /** The search result reference length */
47      private int searchResultReferenceLength;
48  
49  
50      /**
51       * Makes a SearchResultReference encodable.
52       *
53       * @param codec The LDAP service instance
54       * @param decoratedMessage the decorated SearchResultReference
55       */
56      public SearchResultReferenceDecorator( LdapApiService codec, SearchResultReference decoratedMessage )
57      {
58          super( codec, decoratedMessage );
59      }
60  
61  
62      //-------------------------------------------------------------------------
63      // The SearchResultReference methods
64      //-------------------------------------------------------------------------
65  
66      /**
67       * {@inheritDoc}
68       */
69      @Override
70      public Referral getReferral()
71      {
72          return getDecorated().getReferral();
73      }
74  
75  
76      /**
77       * {@inheritDoc}
78       */
79      @Override
80      public void setReferral( Referral referral )
81      {
82          getDecorated().setReferral( referral );
83      }
84  
85  
86      //-------------------------------------------------------------------------
87      // The Decorator methods
88      //-------------------------------------------------------------------------
89  
90      /**
91       * Compute the SearchResultReference length
92       * <br>
93       * SearchResultReference :
94       * <pre>
95       * 0x73 L1
96       *  |
97       *  +--&gt; 0x04 L2 reference
98       *  +--&gt; 0x04 L3 reference
99       *  +--&gt; ...
100      *  +--&gt; 0x04 Li reference
101      *  +--&gt; ...
102      *  +--&gt; 0x04 Ln reference
103      * 
104      * L1 = n*Length(0x04) + sum(Length(Li)) + sum(Length(reference[i]))
105      * 
106      * Length(SearchResultReference) = Length(0x73 + Length(L1) + L1
107      * </pre>
108      * 
109      * @return The encoded length
110      */
111     @Override
112     public int computeLength()
113     {
114         searchResultReferenceLength = 0;
115 
116         // We may have more than one reference.
117         Referral referral = getReferral();
118 
119         int referralLength = LdapEncoder.computeReferralLength( referral );
120 
121         if ( referralLength != 0 )
122         {
123             setReferral( referral );
124 
125             searchResultReferenceLength = referralLength;
126         }
127 
128         return 1 + TLV.getNbBytes( searchResultReferenceLength ) + searchResultReferenceLength;
129     }
130 
131 
132     /**
133      * Encode the SearchResultReference message to a PDU.
134      * <br>
135      * SearchResultReference :
136      * <pre>
137      * 0x73 LL
138      *   0x04 LL reference
139      *   [0x04 LL reference]*
140      * </pre>
141      * 
142      * @param buffer The buffer where to put the PDU
143      * @return The PDU.
144      */
145     @Override
146     public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException
147     {
148         SearchResultReference searchResultReference = getDecorated();
149         try
150         {
151             // The SearchResultReference Tag
152             buffer.put( LdapCodecConstants.SEARCH_RESULT_REFERENCE_TAG );
153             buffer.put( TLV.getBytes( searchResultReferenceLength ) );
154 
155             // The referrals, if any
156             Referral referral = searchResultReference.getReferral();
157 
158             if ( referral != null )
159             {
160                 // Each referral
161                 for ( byte[] ldapUrlBytes : referral.getLdapUrlsBytes() )
162                 {
163                     // Encode the current referral
164                     BerValue.encode( buffer, ldapUrlBytes );
165                 }
166             }
167         }
168         catch ( BufferOverflowException boe )
169         {
170             throw new EncoderException( I18n.err( I18n.ERR_04005 ), boe );
171         }
172 
173         return buffer;
174     }
175 }