| | |
| | | */ |
| | | package org.opends.server.replication.protocol; |
| | | |
| | | import java.io.UnsupportedEncodingException; |
| | | import java.util.List; |
| | | import java.util.zip.DataFormatException; |
| | | |
| | |
| | | * |
| | | * @param op The operation to use for building the message |
| | | */ |
| | | public ModifyMsg(PostOperationModifyOperation op) |
| | | ModifyMsg(PostOperationModifyOperation op) |
| | | { |
| | | super((OperationContext) op.getAttachment(OperationContext.SYNCHROCONTEXT), |
| | | op.getEntryDN()); |
| | |
| | | * |
| | | * @param in The byte[] from which the operation must be read. |
| | | * @throws DataFormatException If the input byte[] is not a valid ModifyMsg |
| | | * @throws UnsupportedEncodingException If UTF8 is not supported by the JVM. |
| | | */ |
| | | public ModifyMsg(byte[] in) throws DataFormatException, |
| | | UnsupportedEncodingException |
| | | ModifyMsg(byte[] in) throws DataFormatException |
| | | { |
| | | // Decode header |
| | | byte[] allowedPduTypes = new byte[2]; |
| | | allowedPduTypes[0] = MSG_TYPE_MODIFY; |
| | | allowedPduTypes[1] = MSG_TYPE_MODIFY_V1; |
| | | int pos = decodeHeader(allowedPduTypes, in); |
| | | final ByteArrayScanner scanner = new ByteArrayScanner(in); |
| | | decodeHeader(scanner, MSG_TYPE_MODIFY, MSG_TYPE_MODIFY_V1); |
| | | |
| | | // protocol version has been read as part of the header |
| | | if (protocolVersion <= 3) |
| | | decodeBody_V123(in, pos); |
| | | { |
| | | decodeBody_V123(scanner); |
| | | } |
| | | else |
| | | decodeBody_V4(in, pos); |
| | | { |
| | | decodeBody_V4(scanner); |
| | | } |
| | | |
| | | if (protocolVersion==ProtocolVersion.getCurrentVersion()) |
| | | { |
| | | bytes = in; |
| | | } |
| | | |
| | | } |
| | | |
| | | /** |
| | | * Creates a new Modify message from a V1 byte[]. |
| | | * |
| | | * @param in The byte[] from which the operation must be read. |
| | | * @throws DataFormatException If the input byte[] is not a valid ModifyMsg |
| | | * @throws UnsupportedEncodingException If UTF8 is not supported by the JVM. |
| | | * |
| | | * @return The created ModifyMsg. |
| | | * @throws DataFormatException If the input byte[] is not a valid ModifyMsg |
| | | */ |
| | | public static ModifyMsg createV1(byte[] in) throws DataFormatException, |
| | | UnsupportedEncodingException |
| | | static ModifyMsg createV1(byte[] in) throws DataFormatException |
| | | { |
| | | ModifyMsg msg = new ModifyMsg(in); |
| | | |
| | |
| | | DN newDN) throws LDAPException, ASN1Exception, DataFormatException |
| | | { |
| | | if (newDN == null) |
| | | { |
| | | newDN = getDN(); |
| | | } |
| | | |
| | | List<RawModification> ldapmods = decodeRawMods(encodedMods); |
| | | |
| | |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public byte[] getBytes_V1() throws UnsupportedEncodingException |
| | | public byte[] getBytes_V1() |
| | | { |
| | | /* encode the header in a byte[] large enough to also contain the mods */ |
| | | byte[] encodedMsg = encodeHeader_V1(MSG_TYPE_MODIFY_V1, encodedMods.length + |
| | | 1); |
| | | |
| | | /* add the mods */ |
| | | int pos = encodedMsg.length - (encodedMods.length + 1); |
| | | addByteArray(encodedMods, encodedMsg, pos); |
| | | |
| | | return encodedMsg; |
| | | final ByteArrayBuilder builder = encodeHeader_V1(MSG_TYPE_MODIFY_V1); |
| | | builder.append(encodedMods); |
| | | return builder.toByteArray(); |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public byte[] getBytes_V23() throws UnsupportedEncodingException |
| | | public byte[] getBytes_V23() |
| | | { |
| | | // Encoding V2 / V3 |
| | | |
| | | /* encode the header in a byte[] large enough to also contain mods */ |
| | | byte[] encodedMsg = encodeHeader(MSG_TYPE_MODIFY, encodedMods.length + 1, |
| | | ProtocolVersion.REPLICATION_PROTOCOL_V3); |
| | | |
| | | /* add the mods */ |
| | | int pos = encodedMsg.length - (encodedMods.length + 1); |
| | | addByteArray(encodedMods, encodedMsg, pos); |
| | | |
| | | return encodedMsg; |
| | | final ByteArrayBuilder builder = |
| | | encodeHeader(MSG_TYPE_MODIFY, ProtocolVersion.REPLICATION_PROTOCOL_V3); |
| | | builder.append(encodedMods); |
| | | return builder.toByteArray(); |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public byte[] getBytes_V45(short reqProtocolVersion) |
| | | throws UnsupportedEncodingException |
| | | public byte[] getBytes_V45(short protocolVersion) |
| | | { |
| | | int bodyLength = 0; |
| | | byte[] byteModsLen = |
| | | String.valueOf(encodedMods.length).getBytes("UTF-8"); |
| | | bodyLength += byteModsLen.length + 1; |
| | | bodyLength += encodedMods.length + 1; |
| | | |
| | | byte[] byteEntryAttrLen = |
| | | String.valueOf(encodedEclIncludes.length).getBytes("UTF-8"); |
| | | bodyLength += byteEntryAttrLen.length + 1; |
| | | bodyLength += encodedEclIncludes.length + 1; |
| | | |
| | | /* encode the header in a byte[] large enough to also contain the mods */ |
| | | byte [] encodedMsg = encodeHeader(MSG_TYPE_MODIFY, bodyLength, |
| | | reqProtocolVersion); |
| | | |
| | | int pos = encodedMsg.length - bodyLength; |
| | | pos = addByteArray(byteModsLen, encodedMsg, pos); |
| | | pos = addByteArray(encodedMods, encodedMsg, pos); |
| | | pos = addByteArray(byteEntryAttrLen, encodedMsg, pos); |
| | | pos = addByteArray(encodedEclIncludes, encodedMsg, pos); |
| | | return encodedMsg; |
| | | final ByteArrayBuilder builder = |
| | | encodeHeader(MSG_TYPE_MODIFY, protocolVersion); |
| | | builder.appendUTF8(encodedMods.length); |
| | | builder.append(encodedMods); |
| | | builder.appendUTF8(encodedEclIncludes.length); |
| | | builder.append(encodedEclIncludes); |
| | | return builder.toByteArray(); |
| | | } |
| | | |
| | | // ============ |
| | | // Msg decoding |
| | | // ============ |
| | | |
| | | private void decodeBody_V123(byte[] in, int pos) |
| | | throws DataFormatException |
| | | private void decodeBody_V123(ByteArrayScanner scanner) |
| | | throws DataFormatException |
| | | { |
| | | // Read and store the mods, in encoded form |
| | | // all the remaining bytes but the terminating 0 */ |
| | | int length = in.length - pos - 1; |
| | | encodedMods = new byte[length]; |
| | | try |
| | | { |
| | | System.arraycopy(in, pos, encodedMods, 0, length); |
| | | } catch (IndexOutOfBoundsException e) |
| | | { |
| | | throw new DataFormatException(e.getMessage()); |
| | | } catch (ArrayStoreException e) |
| | | { |
| | | throw new DataFormatException(e.getMessage()); |
| | | } catch (NullPointerException e) |
| | | { |
| | | throw new DataFormatException(e.getMessage()); |
| | | } |
| | | encodedMods = scanner.remainingBytes(); |
| | | } |
| | | |
| | | private void decodeBody_V4(byte[] in, int pos) |
| | | throws DataFormatException, UnsupportedEncodingException |
| | | private void decodeBody_V4(ByteArrayScanner scanner) |
| | | throws DataFormatException |
| | | { |
| | | // Read mods len |
| | | int length = getNextLength(in, pos); |
| | | int modsLen = Integer.valueOf(new String(in, pos, length,"UTF-8")); |
| | | pos += length + 1; |
| | | final int modsLen = scanner.nextIntUTF8(); |
| | | this.encodedMods = scanner.nextByteArray(modsLen); |
| | | |
| | | // Read/Don't decode mods |
| | | this.encodedMods = new byte[modsLen]; |
| | | try |
| | | { |
| | | System.arraycopy(in, pos, encodedMods, 0, modsLen); |
| | | } catch (IndexOutOfBoundsException e) |
| | | { |
| | | throw new DataFormatException(e.getMessage()); |
| | | } catch (ArrayStoreException e) |
| | | { |
| | | throw new DataFormatException(e.getMessage()); |
| | | } catch (NullPointerException e) |
| | | { |
| | | throw new DataFormatException(e.getMessage()); |
| | | } |
| | | pos += modsLen + 1; |
| | | |
| | | // Read ecl attr len |
| | | length = getNextLength(in, pos); |
| | | int eclAttrLen = Integer.valueOf(new String(in, pos, length,"UTF-8")); |
| | | pos += length + 1; |
| | | |
| | | // Read/Don't decode entry attributes |
| | | encodedEclIncludes = new byte[eclAttrLen]; |
| | | try |
| | | { |
| | | System.arraycopy(in, pos, encodedEclIncludes, 0, eclAttrLen); |
| | | } catch (IndexOutOfBoundsException e) |
| | | { |
| | | throw new DataFormatException(e.getMessage()); |
| | | } catch (ArrayStoreException e) |
| | | { |
| | | throw new DataFormatException(e.getMessage()); |
| | | } catch (NullPointerException e) |
| | | { |
| | | throw new DataFormatException(e.getMessage()); |
| | | } |
| | | final int eclAttrLen = scanner.nextIntUTF8(); |
| | | encodedEclIncludes = scanner.nextByteArray(eclAttrLen); |
| | | } |
| | | } |