001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied. See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 *
019 */
020 package org.apache.directory.shared.ldap.codec.modifyDn;
021
022
023 import java.nio.BufferOverflowException;
024 import java.nio.ByteBuffer;
025
026 import org.apache.directory.shared.asn1.ber.tlv.TLV;
027 import org.apache.directory.shared.asn1.ber.tlv.Value;
028 import org.apache.directory.shared.asn1.codec.EncoderException;
029 import org.apache.directory.shared.ldap.codec.LdapConstants;
030 import org.apache.directory.shared.ldap.codec.LdapMessageCodec;
031 import org.apache.directory.shared.ldap.name.LdapDN;
032 import org.apache.directory.shared.ldap.name.Rdn;
033 import org.apache.directory.shared.ldap.util.StringTools;
034
035
036 /**
037 * A ModifyDNRequest Message. Its syntax is :
038 * ModifyDNRequest ::= [APPLICATION 12] SEQUENCE {
039 * entry LDAPDN,
040 * newrdn RelativeLDAPDN,
041 * deleteoldrdn BOOLEAN,
042 * newSuperior [0] LDAPDN OPTIONAL }
043 *
044 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
045 * @version $Rev: 764131 $, $Date: 2009-04-11 03:03:00 +0200 (Sam, 11 avr 2009) $,
046 */
047 public class ModifyDNRequestCodec extends LdapMessageCodec
048 {
049 // ~ Instance fields
050 // ----------------------------------------------------------------------------
051
052 /** The DN to be modified. */
053 private LdapDN entry;
054
055 /** The new RDN to be added to the RDN or to the new superior, if present */
056 private Rdn newRDN;
057
058 /** If the previous RDN is to be deleted, this flag will be set to true */
059 private boolean deleteOldRDN;
060
061 /** The optional superior, which will be concatened to the newRdn */
062 private LdapDN newSuperior;
063
064 /** The modify DN request length */
065 private int modifyDNRequestLength;
066
067
068 // ~ Constructors
069 // -------------------------------------------------------------------------------
070
071 /**
072 * Creates a new ModifyDNRequest object.
073 */
074 public ModifyDNRequestCodec()
075 {
076 super();
077 }
078
079
080 // ~ Methods
081 // ------------------------------------------------------------------------------------
082
083 /**
084 * Get the message type
085 *
086 * @return Returns the type.
087 */
088 public int getMessageType()
089 {
090 return LdapConstants.MODIFYDN_REQUEST;
091 }
092
093
094 /**
095 * Get the modification's DN
096 *
097 * @return Returns the entry.
098 */
099 public LdapDN getEntry()
100 {
101 return entry;
102 }
103
104
105 /**
106 * Set the modification DN.
107 *
108 * @param entry The entry to set.
109 */
110 public void setEntry( LdapDN entry )
111 {
112 this.entry = entry;
113 }
114
115
116 /**
117 * Tells if the old RDN is to be deleted
118 *
119 * @return Returns the deleteOldRDN.
120 */
121 public boolean isDeleteOldRDN()
122 {
123 return deleteOldRDN;
124 }
125
126
127 /**
128 * Set the flag to delete the old RDN
129 *
130 * @param deleteOldRDN The deleteOldRDN to set.
131 */
132 public void setDeleteOldRDN( boolean deleteOldRDN )
133 {
134 this.deleteOldRDN = deleteOldRDN;
135 }
136
137
138 /**
139 * Get the new RDN
140 *
141 * @return Returns the newRDN.
142 */
143 public Rdn getNewRDN()
144 {
145 return newRDN;
146 }
147
148
149 /**
150 * Set the new RDN
151 *
152 * @param newRDN The newRDN to set.
153 */
154 public void setNewRDN( Rdn newRDN )
155 {
156 this.newRDN = newRDN;
157 }
158
159
160 /**
161 * Get the newSuperior
162 *
163 * @return Returns the newSuperior.
164 */
165 public LdapDN getNewSuperior()
166 {
167 return newSuperior;
168 }
169
170
171 /**
172 * Set the new superior
173 *
174 * @param newSuperior The newSuperior to set.
175 */
176 public void setNewSuperior( LdapDN newSuperior )
177 {
178 this.newSuperior = newSuperior;
179 }
180
181
182 /**
183 * Compute the ModifyDNRequest length
184 *
185 * ModifyDNRequest :
186 *
187 * 0x6C L1
188 * |
189 * +--> 0x04 L2 entry
190 * +--> 0x04 L3 newRDN
191 * +--> 0x01 0x01 (true/false) deleteOldRDN (3 bytes)
192 * [+--> 0x80 L4 newSuperior ]
193 *
194 * L2 = Length(0x04) + Length(Length(entry)) + Length(entry)
195 * L3 = Length(0x04) + Length(Length(newRDN)) + Length(newRDN)
196 * L4 = Length(0x80) + Length(Length(newSuperior)) + Length(newSuperior)
197 * L1 = L2 + L3 + 3 [+ L4]
198 *
199 * Length(ModifyDNRequest) = Length(0x6C) + Length(L1) + L1
200 *
201 * @return The PDU's length of a ModifyDN Request
202 */
203 public int computeLength()
204 {
205 int newRdnlength = StringTools.getBytesUtf8( newRDN.toString() ).length;
206 modifyDNRequestLength = 1 + TLV.getNbBytes( LdapDN.getNbBytes( entry ) ) + LdapDN.getNbBytes( entry ) + 1
207 + TLV.getNbBytes( newRdnlength ) + newRdnlength + 1 + 1 + 1; // deleteOldRDN
208
209 if ( newSuperior != null )
210 {
211 modifyDNRequestLength += 1 + TLV.getNbBytes( LdapDN.getNbBytes( newSuperior ) )
212 + LdapDN.getNbBytes( newSuperior );
213 }
214
215 return 1 + TLV.getNbBytes( modifyDNRequestLength ) + modifyDNRequestLength;
216 }
217
218
219 /**
220 * Encode the ModifyDNRequest message to a PDU.
221 *
222 * ModifyDNRequest :
223 *
224 * 0x6C LL
225 * 0x04 LL entry
226 * 0x04 LL newRDN
227 * 0x01 0x01 deleteOldRDN
228 * [0x80 LL newSuperior]
229 *
230 * @param buffer The buffer where to put the PDU
231 * @return The PDU.
232 */
233 public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException
234 {
235 if ( buffer == null )
236 {
237 throw new EncoderException( "Cannot put a PDU in a null buffer !" );
238 }
239
240 try
241 {
242 // The ModifyDNRequest Tag
243 buffer.put( LdapConstants.MODIFY_DN_REQUEST_TAG );
244 buffer.put( TLV.getBytes( modifyDNRequestLength ) );
245
246 // The entry
247
248 Value.encode( buffer, LdapDN.getBytes( entry ) );
249
250 // The newRDN
251 Value.encode( buffer, newRDN.toString() );
252
253 // The flag deleteOldRdn
254 Value.encode( buffer, deleteOldRDN );
255
256 // The new superior, if any
257 if ( newSuperior != null )
258 {
259 // Encode the reference
260 buffer.put( ( byte ) LdapConstants.MODIFY_DN_REQUEST_NEW_SUPERIOR_TAG );
261
262 int newSuperiorLength = LdapDN.getNbBytes( newSuperior );
263
264 buffer.put( TLV.getBytes( newSuperiorLength ) );
265
266 if ( newSuperiorLength != 0 )
267 {
268 buffer.put( LdapDN.getBytes( newSuperior ) );
269 }
270 }
271 }
272 catch ( BufferOverflowException boe )
273 {
274 throw new EncoderException( "The PDU buffer size is too small !" );
275 }
276
277 return buffer;
278 }
279
280
281 /**
282 * Get a String representation of a ModifyDNRequest
283 *
284 * @return A ModifyDNRequest String
285 */
286 public String toString()
287 {
288
289 StringBuffer sb = new StringBuffer();
290
291 sb.append( " ModifyDN Response\n" );
292 sb.append( " Entry : '" ).append( entry ).append( "'\n" );
293 sb.append( " New RDN : '" ).append( newRDN ).append( "'\n" );
294 sb.append( " Delete old RDN : " ).append( deleteOldRDN ).append( "\n" );
295
296 if ( newSuperior != null )
297 {
298 sb.append( " New superior : '" ).append( newSuperior ).append( "'\n" );
299 }
300
301 return sb.toString();
302 }
303 }