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   *    https://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.factory;
21  
22  import java.util.Collection;
23  import java.util.Iterator;
24  
25  import org.apache.directory.api.asn1.ber.tlv.BerValue;
26  import org.apache.directory.api.asn1.util.Asn1Buffer;
27  import org.apache.directory.api.ldap.codec.api.LdapApiService;
28  import org.apache.directory.api.ldap.codec.api.LdapCodecConstants;
29  import org.apache.directory.api.ldap.model.message.LdapResult;
30  import org.apache.directory.api.ldap.model.message.Message;
31  import org.apache.directory.api.ldap.model.message.Referral;
32  import org.apache.directory.api.ldap.model.message.ResultResponse;
33  
34  /**
35   * The Response factory.
36   *
37   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
38   */
39  public abstract class ResponseFactory implements Messagefactory
40  {
41      // A default success bytes sequence
42      private static final byte[] DEFAULT_SUCCESS = new byte[]
43          { 0x0A, 0x01, 0x00, 0x04, 0x00, 0x04, 0x00 };
44  
45      private static final byte[] EMPTY_MATCHED_DN = new byte[]
46          { 0x04, 0x00 };
47  
48      /**
49       * Creates a new instance of ResponseFactory.
50       */
51      protected ResponseFactory()
52      {
53          // Nothing to do
54      }
55  
56  
57      /**
58       * Encode referral's URLs recursively
59       *
60       * @param buffer The buffer that will contain the encoded urls
61       * @param urls The urls to encode
62       */
63      protected void encodeReferralUrls( Asn1Buffer buffer, Iterator<String> urls )
64      {
65          if ( urls.hasNext() )
66          {
67              String url = urls.next();
68  
69              encodeReferralUrls( buffer, urls );
70  
71              BerValue.encodeOctetString( buffer, url );
72          }
73      }
74  
75  
76      /**
77       * Encode the LdapResult element
78       * <br>
79       * LdapResult :
80       * <pre>
81       *   0x0A 01 resultCode (0..80)
82       *   0x04 L1 matchedDN (L1 = Length(matchedDN))
83       *   0x04 L2 errorMessage (L2 = Length(errorMessage))
84       *   [0x83 L3] referrals
85       *     |
86       *     +--&gt; 0x04 L4 referral
87       *     +--&gt; 0x04 L5 referral
88       *     +--&gt; ...
89       *     +--&gt; 0x04 Li referral
90       *     +--&gt; ...
91       *     +--&gt; 0x04 Ln referral
92       * </pre>
93       *
94       * @param buffer The buffer where to put the PDU
95       * @param ldapResult The LdapResult instance
96       */
97      protected void encodeLdapResultReverse( Asn1Buffer buffer, LdapResult ldapResult )
98      {
99          if ( ldapResult.isDefaultSuccess() )
100         {
101             // The length of a default success PDU : 0xA0 0x01 0x00 0x04 0x00 0x04 0x00
102             buffer.put( DEFAULT_SUCCESS );
103 
104             return;
105         }
106 
107         // Referrals, if any
108         Referral referral = ldapResult.getReferral();
109 
110         if ( referral != null )
111         {
112             int start = buffer.getPos();
113             Collection<String> urls = referral.getLdapUrls();
114 
115             if ( urls != null )
116             {
117                 encodeReferralUrls( buffer, urls.iterator() );
118             }
119 
120             // The referral tag
121             BerValue.encodeSequence( buffer, ( byte ) LdapCodecConstants.LDAP_RESULT_REFERRAL_SEQUENCE_TAG, start );
122         }
123 
124         // The errorMessage
125         BerValue.encodeOctetString( buffer, ldapResult.getDiagnosticMessage() );
126 
127         // The matchedDN
128         if ( ldapResult.getMatchedDn() != null )
129         {
130             BerValue.encodeOctetString( buffer, ldapResult.getMatchedDn().getName() );
131         }
132         else
133         {
134             buffer.put( EMPTY_MATCHED_DN );
135         }
136 
137         // The result code
138         BerValue.encodeEnumerated( buffer, ldapResult.getResultCode().getValue() );
139     }
140 
141 
142     /**
143      * Encode the Response message to a PDU.
144      * <br>
145      * Response :
146      * <pre>
147      * 0x&lt;tag&gt; L1
148      *  |
149      *  +--&gt; LdapResult
150      * </pre>
151      *
152      * @param codec The LdapApiService instance
153      * @param buffer The buffer where to put the PDU
154      * @param tag The message tag
155      * @param message the Response to encode
156      */
157     protected void encodeReverse( LdapApiService codec, Asn1Buffer buffer, byte tag, Message message )
158     {
159         int start = buffer.getPos();
160 
161         // The LDAPResult part
162         encodeLdapResultReverse( buffer, ( ( ResultResponse ) message ).getLdapResult() );
163 
164         // The BindResponse Tag
165         BerValue.encodeSequence( buffer, tag, start );
166     }
167 }