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

gbellato
01.04.2006 b5acb25ee2ad9bf8b166b9de1a34e6aab6ea23b7
opends/src/server/org/opends/server/synchronization/UpdateMessage.java
@@ -27,8 +27,13 @@
package org.opends.server.synchronization;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.util.zip.DataFormatException;
import org.opends.server.core.AddOperation;
import org.opends.server.core.DeleteOperation;
import org.opends.server.core.ModifyDNOperation;
import org.opends.server.core.ModifyOperation;
import org.opends.server.core.Operation;
import org.opends.server.protocols.asn1.ASN1Exception;
import org.opends.server.protocols.internal.InternalClientConnection;
@@ -45,7 +50,12 @@
  /**
   * The ChangeNumber of this update.
   */
  protected ChangeNumber changeNumber;
  private ChangeNumber changeNumber;
  /**
   * The DN on which the update was originally done.
   */
  private String dn = null;
  /**
   * True when the update must use assured replication.
@@ -53,6 +63,83 @@
  private boolean assuredFlag = false;
  /**
   * The UniqueId of the entry that was updated.
   */
  private String UniqueId;
  /**
   * Creates a new UpdateMessage with the given informations.
   *
   * @param ctx The Synchronization Context of the operation for which the
   *            update message must be created,.
   * @param dn The dn of the entry on which the change
   *           that caused the creation of this object happened
   */
  public UpdateMessage(OperationContext ctx, String dn)
  {
    this.changeNumber = ctx.getChangeNumber();
    this.UniqueId = ctx.getEntryUid();
    this.dn = dn;
  }
  /**
   * Creates a new UpdateMessage from an ecoded byte array.
   *
   * @param in The encoded byte array containind the UpdateMessage.
   * @throws DataFormatException if the encoded byte array is not valid.
   * @throws UnsupportedEncodingException if UTF-8 is not supprted.
   */
  public UpdateMessage(byte[] in) throws DataFormatException,
                                         UnsupportedEncodingException
  {
    /* read the changeNumber */
    int pos = 1;
    int length = getNextLength(in, pos);
    String changenumberStr = new String(in, pos, length, "UTF-8");
    this.changeNumber = new ChangeNumber(changenumberStr);
  }
  /**
   * Generates an Update Message which the provided information.
   *
   * @param op The operation fo which the message must be created.
   * @param isAssured flag indicating if the operation is an assured operation.
   * @return The generated message.
   */
  public static UpdateMessage generateMsg(Operation op, boolean isAssured)
  {
    UpdateMessage msg = null;
    switch (op.getOperationType())
    {
    case MODIFY :
      msg = new ModifyMsg((ModifyOperation) op);
      if (isAssured)
        msg.setAssured();
      break;
    case ADD:
      msg = new AddMsg((AddOperation) op);
      if (isAssured)
        msg.setAssured();
      break;
    case DELETE :
      msg = new DeleteMsg((DeleteOperation) op);
      if (isAssured)
        msg.setAssured();
      break;
    case MODIFY_DN :
      msg = new ModifyDNMsg((ModifyDNOperation) op);
      if (isAssured)
        msg.setAssured();
      break;
    }
    return msg;
  }
  /**
   * Get the ChangeNumber from the message.
   * @return the ChangeNumber
   */
@@ -62,6 +149,35 @@
  }
  /**
   * Get the DN on which the operation happened.
   *
   * @return The DN on which the operations happened.
   */
  public String getDn()
  {
    return dn;
  }
  /**
   * Set the DN.
   * @param dn The dn that must now be used for this message.
   */
  public void setDn(String dn)
  {
    this.dn = dn;
  }
  /**
   * Get the Unique Identifier of the entry on which the operation happened.
   *
   * @return The Unique Identifier of the entry on which the operation happened.
   */
  public String getUniqueId()
  {
    return UniqueId;
  }
  /**
   * Get a boolean indicating if the Update must be processed as an
   * Asynchronous or as an assured synchronization.
   *
@@ -117,10 +233,115 @@
   * @throws  ASN1Exception In case of ASN1 decoding exception.
   * @throws DataFormatException In case of bad msg format.
   */
  public abstract Operation createOperation(InternalClientConnection conn)
  public Operation createOperation(InternalClientConnection conn)
         throws LDAPException, ASN1Exception, DataFormatException
  {
    return createOperation(conn, dn);
  }
  /**
   * Create and Operation from the message using the provided DN.
   *
   * @param   conn connection to use when creating the message.
   * @param   newDn the DN 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.
   * @throws DataFormatException In case of bad msg format.
   */
  public abstract Operation createOperation(InternalClientConnection conn,
                                            String newDn)
         throws LDAPException, ASN1Exception, DataFormatException;
  /**
   * Encode the common header for all the UpdateMessage.
   *
   * @param type the type of UpdateMessage to encode.
   * @param additionalLength additional length needed to encode the remaining
   *                         part of the UpdateMessage.
   * @return a byte array containing the common header and enough space to
   *         encode the reamining bytes of the UpdateMessage as was specified
   *         by the additionalLength.
   *         (byte array length = common header length + additionalLength)
   * @throws UnsupportedEncodingException if UTF-8 is not supported.
   */
  public byte[] encodeHeader(byte type, int additionalLength)
    throws UnsupportedEncodingException
  {
    byte[] byteDn = dn.getBytes("UTF-8");
    byte[] changeNumberByte =
      this.getChangeNumber().toString().getBytes("UTF-8");
    byte[] byteEntryuuid = getUniqueId().getBytes("UTF-8");
    /* The message header is stored in the form :
     * <operation type>changenumber><dn><entryuuid><change>
     * the length of result byte array is therefore :
     *   1 + dn length + 1 + 24 + additional_length
     */
    int length = 1 + changeNumberByte.length + 1 + byteDn.length + 1
                 + byteEntryuuid.length + 1 + additionalLength;
    byte[] encodedMsg = new byte[length];
    /* put the type of the operation */
    encodedMsg[0] = type;
    int pos = 1;
    /* put the ChangeNumber */
    pos = addByteArray(changeNumberByte, encodedMsg, pos);
    /* put the DN and a terminating 0 */
    pos = addByteArray(byteDn, encodedMsg, pos);
    /* put the entry uuid and a terminating 0 */
    pos = addByteArray(byteEntryuuid, encodedMsg, pos);
    return encodedMsg;
  }
  /**
   * Decode the Header part of this Update Message, and check its type.
   *
   * @param type The type of this Update Message.
   * @param encodedMsg the encoded form of the UpdateMessage.
   * @return the position at which the remaining part of the message starts.
   * @throws DataFormatException if the encodedMsg does not contain a valid
   *         common header.
   */
  public int decodeHeader(byte type, byte [] encodedMsg)
                          throws DataFormatException
  {
    /* first byte is the type */
    if (encodedMsg[0] != type)
      throw new DataFormatException("byte[] is not a valid msg");
    try
    {
      /* 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 entryuuid */
      length = getNextLength(encodedMsg, pos);
      UniqueId = new String(encodedMsg, pos, length, "UTF-8");
      pos += length + 1;
      return pos;
    } catch (UnsupportedEncodingException e)
    {
      throw new DataFormatException("UTF-8 is not supported by this jvm.");
    }
  }
  /**
   * {@inheritDoc}
   */