| | |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2006-2009 Sun Microsystems, Inc. |
| | | * Copyright 2006-2010 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.replication.protocol; |
| | | |
| | |
| | | import java.io.UnsupportedEncodingException; |
| | | import java.util.zip.DataFormatException; |
| | | |
| | | import org.opends.server.controls.SubtreeDeleteControl; |
| | | import org.opends.server.core.DeleteOperationBasis; |
| | | import org.opends.server.protocols.internal.InternalClientConnection; |
| | | import org.opends.server.replication.common.ChangeNumber; |
| | |
| | | */ |
| | | public class DeleteMsg extends LDAPUpdateMsg |
| | | { |
| | | String initiatorsName; |
| | | private String initiatorsName; |
| | | |
| | | // whether the DEL operation is a subtree DEL |
| | | private boolean isSubtreeDelete = false; |
| | | |
| | | /** |
| | | * Creates a new delete message. |
| | |
| | | { |
| | | super((OperationContext) operation.getAttachment(SYNCHROCONTEXT), |
| | | operation.getRawEntryDN().toString()); |
| | | try |
| | | { |
| | | if (operation.getRequestControl(SubtreeDeleteControl.DECODER) != null) |
| | | isSubtreeDelete = true; |
| | | } |
| | | catch(Exception e) |
| | | {} |
| | | |
| | | } |
| | | |
| | | /** |
| | | * Creates a new delete message. |
| | | * |
| | | * @param dn The dn with which the message must be created. |
| | | * @param dn The dn with which the message must be created. |
| | | * @param changeNumber The change number with which the message must be |
| | | * created. |
| | | * @param uid The unique id with which the message must be created. |
| | | * @param uid The unique id with which the message must be created. |
| | | */ |
| | | public DeleteMsg(String dn, ChangeNumber changeNumber, String uid) |
| | | { |
| | |
| | | // protocol version has been read as part of the header |
| | | if (protocolVersion >= 4) |
| | | decodeBody_V4(in, pos); |
| | | else |
| | | { |
| | | // Keep the previous protocol version behavior - when we don't know the |
| | | // truth, we assume 'subtree' |
| | | isSubtreeDelete = true; |
| | | } |
| | | } |
| | | |
| | | |
| | |
| | | InternalClientConnection.nextOperationID(), |
| | | InternalClientConnection.nextMessageID(), null, |
| | | ByteString.valueOf(newDn)); |
| | | |
| | | if (isSubtreeDelete) |
| | | del.addRequestControl(new SubtreeDeleteControl(false)); |
| | | |
| | | DeleteContext ctx = new DeleteContext(getChangeNumber(), getUniqueId()); |
| | | del.setAttachment(SYNCHROCONTEXT, ctx); |
| | | return del; |
| | |
| | | { |
| | | bodyLength++; |
| | | } |
| | | // subtree flag |
| | | bodyLength++; |
| | | |
| | | /* encode the header in a byte[] large enough to also contain the mods */ |
| | | byte [] encodedMsg = encodeHeader(MSG_TYPE_DELETE, bodyLength, |
| | |
| | | encodedMsg[pos++] = 0; |
| | | pos = addByteArray(byteEntryAttrLen, encodedMsg, pos); |
| | | pos = addByteArray(encodedEclIncludes, encodedMsg, pos); |
| | | |
| | | encodedMsg[pos++] = (isSubtreeDelete ? (byte) 1 : (byte) 0); |
| | | |
| | | return encodedMsg; |
| | | } |
| | | |
| | |
| | | private void decodeBody_V4(byte[] in, int pos) |
| | | throws DataFormatException, UnsupportedEncodingException |
| | | { |
| | | // Read ecl attr len |
| | | int length = getNextLength(in, pos); |
| | | if (length != 0) |
| | | { |
| | |
| | | initiatorsName = null; |
| | | pos += 1; |
| | | } |
| | | |
| | | // Read ecl attr len |
| | | length = getNextLength(in, pos); |
| | | int eclAttrLen = Integer.valueOf(new String(in, pos, length,"UTF-8")); |
| | | // Skip the length |
| | | pos += length + 1; |
| | | |
| | | // Read/Don't decode entry attributes |
| | | encodedEclIncludes = new byte[eclAttrLen]; |
| | | try |
| | | { |
| | | // Copy ecl attr |
| | | System.arraycopy(in, pos, encodedEclIncludes, 0, eclAttrLen); |
| | | // Skip the attrs |
| | | pos += eclAttrLen +1; |
| | | } catch (IndexOutOfBoundsException e) |
| | | { |
| | | throw new DataFormatException(e.getMessage()); |
| | |
| | | { |
| | | throw new DataFormatException(e.getMessage()); |
| | | } |
| | | |
| | | // subtree flag |
| | | isSubtreeDelete = (in[pos] == 1); |
| | | |
| | | } |
| | | |
| | | /** |
| | |
| | | return initiatorsName; |
| | | } |
| | | |
| | | /** |
| | | * Set the subtree flag. |
| | | * @param subtreeDelete the subtree flag. |
| | | */ |
| | | public void setSubtreeDelete(boolean subtreeDelete) |
| | | { |
| | | this.isSubtreeDelete = subtreeDelete; |
| | | } |
| | | |
| | | /** |
| | | * Get the subtree flag. |
| | | * @return the subtree flag. |
| | | */ |
| | | public boolean isSubtreeDelete() |
| | | { |
| | | return this.isSubtreeDelete; |
| | | } |
| | | } |