mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

gbellato
12.23.2006 f0f4caa7b330807252d8a86d8ff499e16f9ddd33
opendj-sdk/opends/src/server/org/opends/server/synchronization/ModifyMsg.java
@@ -27,7 +27,6 @@
package org.opends.server.synchronization;
import static org.opends.server.synchronization.SynchMessages.SYNCHRONIZATION;
import static org.opends.server.protocols.ldap.LDAPConstants.*;
import org.opends.server.core.ModifyOperation;
import org.opends.server.core.Operation;
@@ -45,6 +44,7 @@
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.DataFormatException;
/**
 * Message used to send Modify information.
@@ -52,8 +52,9 @@
public class ModifyMsg extends UpdateMessage
{
  private static final long serialVersionUID = -4905520652801395185L;
  private String dn;
  private byte[] encodedMods;
  private String dn = null;
  private byte[] encodedMods = null;
  private byte[] encodedMsg = null;
  /**
   * Creates a new Modify message from a ModifyOperation.
@@ -85,41 +86,149 @@
   * Creates a new Modify message from a byte[].
   *
   * @param in The byte[] from which the operation must be read.
   * @throws Exception The input byte[] is not a valid modifyMsg
   * @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 Exception
  public ModifyMsg(byte[] in) throws DataFormatException,
                                     UnsupportedEncodingException
  {
    /* first byte is the type */
    if (in[0] != OP_TYPE_MODIFY_REQUEST)
      throw new Exception("byte[] is not a valid modify msg");
    encodedMsg = in;
    decodeChangeNumber(in);
  }
  private void decodeChangeNumber(byte[] in) throws DataFormatException,
                                             UnsupportedEncodingException
  {
    /* read the changeNumber */
    int pos = 1;
    int length = getNextLength(encodedMsg, pos);
    String changenumberStr = new String(encodedMsg, pos, length, "UTF-8");
    pos += length +1;
    changeNumber = new ChangeNumber(changenumberStr);
  }
  /**
   * Get the byte array representation of this Message.
   *
   * @return The byte array representation of this Message.
   */
  @Override
  public byte[] getBytes()
  {
    if (encodedMsg == null)
    {
      try
      {
        encode();
      } catch (UnsupportedEncodingException e)
      {
        // should never happens : TODO : log some error
        return null;
      }
    }
    return encodedMsg;
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public Operation createOperation(InternalClientConnection connection)
                   throws LDAPException, ASN1Exception, DataFormatException
  {
    if (encodedMods == null)
    {
      decode();
    }
    ArrayList<LDAPModification> ldapmods;
    ArrayList<ASN1Element> mods = null;
    mods = ASN1Element.decodeElements(encodedMods);
    ldapmods = new ArrayList<LDAPModification>(mods.size());
    for (ASN1Element elem : mods)
      ldapmods.add(LDAPModification.decode(elem));
    ModifyOperation mod = new ModifyOperation(connection,
                               InternalClientConnection.nextOperationID(),
                               InternalClientConnection.nextMessageID(), null,
                               new ASN1OctetString(dn), ldapmods);
    mod.setAttachment(SYNCHRONIZATION, getChangeNumber());
    return mod;
  }
  /**
   * Encode the Msg information into a byte array.
   *
   * @throws UnsupportedEncodingException If utf8 is not suported.
   */
  private void encode() throws UnsupportedEncodingException
  {
    byte[] byteDn = dn.getBytes("UTF-8");
    byte[] changeNumberByte =
      this.getChangeNumber().toString().getBytes("UTF-8");
    /* The Modify message is stored in the form :
     * <operation type>changenumber><dn><<mods>
     * the length of result byte array is therefore :
     *   1 + dn length + 1 + 24 + mods length
     */
    int length = 1 + changeNumberByte.length + 1 + byteDn.length + 1
                 + encodedMods.length + 1;
    encodedMsg = new byte[length];
    /* put the type of the operation */
    encodedMsg[0] = MSG_TYPE_MODIFY_REQUEST;
    int pos = 1;
    /* read the dn
     * first calculate the length then construct the string
     */
    int length = 0;
    int offset = pos;
    while (in[pos++] != 0)
    {
      if (pos > in.length)
        throw new Exception("byte[] is not a valid modify msg");
      length++;
    }
    dn = new String(in, offset, length, "UTF-8");
    /* put the ChangeNumber */
    pos = addByteArray(changeNumberByte, encodedMsg, pos);
    /* read the changeNumber
     * it is always 24 characters long
     */
    String changenumberStr = new  String(in, pos, 24, "UTF-8");
    changeNumber = new ChangeNumber(changenumberStr);
    pos +=24;
    /* put the DN and a terminating 0 */
    pos = addByteArray(byteDn, encodedMsg, pos);
    /* Read the mods : all the remaining bytes */
    encodedMods = new byte[in.length-pos];
    int i =0;
    while (pos<in.length)
    /* put the mods */
    pos = addByteArray(encodedMods, encodedMsg, pos);
  }
  /**
   * Decode the encodedMsg into mods and dn.
   *
   * @throws DataFormatException when the encodedMsg is no a valid modify.
   */
  private void decode() throws DataFormatException
  {
    /* first byte is the type */
    if (encodedMsg[0] != MSG_TYPE_MODIFY_REQUEST)
      throw new DataFormatException("byte[] is not a valid modify msg");
    try
    {
      encodedMods[i++] = in[pos++];
      /* read the changeNumber */
      int pos = 1;
      int length = getNextLength(encodedMsg, pos);
      String changenumberStr = new String(encodedMsg, pos, length, "UTF-8");
      pos += length +1;
      changeNumber = new ChangeNumber(changenumberStr);
      /* read the dn */
      length = getNextLength(encodedMsg, pos);
      dn = new String(encodedMsg, pos, length, "UTF-8");
      pos += length +1;
      /* Read the mods : all the remaining bytes but the terminating 0 */
      encodedMods = new byte[encodedMsg.length-pos-1];
      int i =0;
      while (pos<encodedMsg.length-1)
      {
        encodedMods[i++] = encodedMsg[pos++];
      }
    } catch (UnsupportedEncodingException e)
    {
      throw new DataFormatException("UTF-8 is not supported by this jvm.");
    }
  }
@@ -149,87 +258,6 @@
  }
  /**
   * Create an operation from this Modify message.
   *
   * @param connection The connection to use when creating the operation.
   * @return The created operation.
   * @throws LDAPException In case of ldap decoding exception.
   * @throws ASN1Exception In case of ASN1 decoding exception.
   */
  @Override
  public Operation createOperation(InternalClientConnection connection)
                   throws LDAPException, ASN1Exception
  {
    ArrayList<LDAPModification> ldapmods;
    ArrayList<ASN1Element> mods = null;
    mods = ASN1Element.decodeElements(encodedMods);
    ldapmods = new ArrayList<LDAPModification>(mods.size());
    for (ASN1Element elem : mods)
      ldapmods.add(LDAPModification.decode(elem));
    ModifyOperation mod = new ModifyOperation(connection,
                               InternalClientConnection.nextOperationID(),
                               InternalClientConnection.nextMessageID(), null,
                               new ASN1OctetString(dn), ldapmods);
    mod.setAttachment(SYNCHRONIZATION, getChangeNumber());
    return mod;
  }
  /**
   * Get the byte array representation of this Message.
   *
   * @return The byte array representation of this Message.
   */
  @Override
  public byte[] getByte()
  {
    byte[] byteDn;
    try
    {
      byteDn = dn.getBytes("UTF-8");
      /* The Modify message is stored in the form :
       * <operation type><dn><changenumber><mods>
       * the length of result byte array is therefore :
       *   1 + dn length + 1 + 24 + mods length
       */
      int length = 1 + byteDn.length + 1  + 24 + encodedMods.length;
      byte[] resultByteArray = new byte[length];
      int pos = 1;
      /* put the type of the operation */
      resultByteArray[0] = OP_TYPE_MODIFY_REQUEST;
      /* put the DN and a terminating 0 */
      for (int i = 0; i< byteDn.length; i++,pos++)
      {
        resultByteArray[pos] = byteDn[i];
      }
      resultByteArray[pos++] = 0;
      /* put the ChangeNumber */
      byte[] changeNumberByte =
                      this.getChangeNumber().toString().getBytes("UTF-8");
      for (int i=0; i<24; i++,pos++)
      {
        resultByteArray[pos] = changeNumberByte[i];
      }
      /* put the mods */
      for (int i=0; i<encodedMods.length; i++,pos++)
      {
        resultByteArray[pos] = encodedMods[i];
      }
      return resultByteArray;
    } catch (UnsupportedEncodingException e)
    {
      // should never happens : TODO : log some error
    }
    return null;
  }
  /**
   * {@inheritDoc}
   */
  @Override