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.entry.Attribute;
30  import org.apache.directory.api.ldap.model.entry.Modification;
31  import org.apache.directory.api.ldap.model.entry.ModificationOperation;
32  import org.apache.directory.api.ldap.model.entry.Value;
33  import org.apache.directory.api.ldap.model.message.Message;
34  import org.apache.directory.api.ldap.model.message.ModifyRequest;
35  import org.apache.directory.api.util.CollectionUtils;
36  
37  /**
38   * The ModifyRequest factory.
39   *
40   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
41   */
42  public final class ModifyRequestFactory implements Messagefactory
43  {
44      /** The static instance */
45      public static final ModifyRequestFactory INSTANCE = new ModifyRequestFactory();
46  
47      private ModifyRequestFactory()
48      {
49          // Nothing to do
50      }
51  
52  
53      /**
54       * Encode the values, in reverse order
55       * <pre>
56       * 0x04 LL attributeValue
57       * ...
58       * 0x04 LL attributeValue
59       * </pre>
60       *
61       * @param buffer The buffer where to put the PDU
62       * @param values the values to encode
63       */
64      private void encodeValues( Asn1Buffer buffer, Iterator<Value> values )
65      {
66          values = CollectionUtils.reverse( values );
67          while ( values.hasNext() )
68          {
69              Value value = values.next();
70  
71              // The value
72              if ( value.isHumanReadable() )
73              {
74                  BerValue.encodeOctetString( buffer, value.getString() );
75              }
76              else
77              {
78                  BerValue.encodeOctetString( buffer, value.getBytes() );
79              }
80          }
81      }
82  
83      /**
84       * Encode the modifications, starting from the last one.
85       * <pre>
86       * 0x30 LL modification sequence
87       *   0x0A 0x01 operation
88       *   0x30 LL modification
89       *     0x04 LL type
90       *     0x31 LL vals
91       *       0x04 LL attributeValue
92       *       ...
93       *       0x04 LL attributeValue
94       * </pre>
95       *
96       * @param buffer The buffer where to put the PDU
97       * @param modifications the modifications to encode
98       */
99      private void encodeModifications( Asn1Buffer buffer, Iterator<Modification> modifications )
100     {
101         modifications = CollectionUtils.reverse( modifications );
102         while ( modifications.hasNext() )
103         {
104             Modification modification = modifications.next();
105 
106             int start = buffer.getPos();
107 
108             // The Attribute
109             Attribute attribute = modification.getAttribute();
110 
111             // The values, if any
112             if ( modification.getAttribute().size() != 0 )
113             {
114                 encodeValues( buffer, modification.getAttribute().iterator() );
115 
116                 // the value set
117                 BerValue.encodeSet( buffer, start );
118             }
119             else if ( modification.getOperation() != ModificationOperation.INCREMENT_ATTRIBUTE )
120             {
121                 // the value set, if not a INCREMENT operation
122                 BerValue.encodeSet( buffer, start );
123             }
124 
125             // The attribute type
126             BerValue.encodeOctetString( buffer, attribute.getUpId() );
127 
128             // The attribute sequence
129             BerValue.encodeSequence( buffer, start );
130 
131             // The operation
132             BerValue.encodeEnumerated( buffer, modification.getOperation().getValue() );
133 
134             // The modification sequence
135             BerValue.encodeSequence( buffer, start );
136         }
137     }
138 
139     /**
140      * Encode the ModifyRequest message to a PDU.
141      * <br>
142      * ModifyRequest :
143      * <pre>
144      * 0x66 LL
145      *   0x04 LL object
146      *   0x30 LL modifications
147      *     0x30 LL modification sequence
148      *       0x0A 0x01 operation
149      *       0x30 LL modification
150      *         0x04 LL type
151      *         0x31 LL vals
152      *           0x04 LL attributeValue
153      *           ...
154      *           0x04 LL attributeValue
155      *     ...
156      *     0x30 LL modification sequence
157      *       0x0A 0x01 operation
158      *       0x30 LL modification
159      *         0x04 LL type
160      *         0x31 LL vals
161      *           0x04 LL attributeValue
162      *           ...
163      *           0x04 LL attributeValue
164      * </pre>
165      *
166      * @param codec The LdapApiService instance
167      * @param buffer The buffer where to put the PDU
168      * @param message the ModifyRequest to encode
169      */
170     @Override
171     public void encodeReverse( LdapApiService codec, Asn1Buffer buffer, Message message )
172     {
173         int start = buffer.getPos();
174         ModifyRequest modifyRequest = ( ModifyRequest ) message;
175 
176         // The modifications, if any
177         Collection<Modification> modifications = modifyRequest.getModifications();
178 
179         if ( ( modifications != null ) && ( !modifications.isEmpty() ) )
180         {
181             encodeModifications( buffer, modifications.iterator() );
182 
183             // The modifications sequence
184             BerValue.encodeSequence( buffer, start );
185         }
186 
187         // The entry DN
188         BerValue.encodeOctetString( buffer, modifyRequest.getName().getName() );
189 
190         // The ModifyRequest tag
191         BerValue.encodeSequence( buffer, LdapCodecConstants.MODIFY_REQUEST_TAG, start );
192     }
193 }