001 /* 002 * CDDL HEADER START 003 * 004 * The contents of this file are subject to the terms of the 005 * Common Development and Distribution License, Version 1.0 only 006 * (the "License"). You may not use this file except in compliance 007 * with the License. 008 * 009 * You can obtain a copy of the license at 010 * trunk/opends/resource/legal-notices/OpenDS.LICENSE 011 * or https://OpenDS.dev.java.net/OpenDS.LICENSE. 012 * See the License for the specific language governing permissions 013 * and limitations under the License. 014 * 015 * When distributing Covered Code, include this CDDL HEADER in each 016 * file and include the License file at 017 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, 018 * add the following below this CDDL HEADER, with the fields enclosed 019 * by brackets "[]" replaced with your own identifying information: 020 * Portions Copyright [yyyy] [name of copyright owner] 021 * 022 * CDDL HEADER END 023 * 024 * 025 * Copyright 2006-2008 Sun Microsystems, Inc. 026 */ 027 package org.opends.server.replication.protocol; 028 029 import java.io.Serializable; 030 import java.io.UnsupportedEncodingException; 031 import java.util.zip.DataFormatException; 032 033 034 /** 035 * This message is used by LDAP server or by Replication Servers to 036 * update the send window of the remote entities. 037 * 038 * A receiving entity should create such a message with a given credit 039 * when it wants to open the send window of the remote entity. 040 * A LDAP or Replication Server should increase its send window when receiving 041 * such a message. 042 */ 043 public class WindowMessage extends ReplicationMessage implements 044 Serializable 045 { 046 private static final long serialVersionUID = 8442267608764026867L; 047 private final int numAck; 048 049 050 /** 051 * Create a new WindowMessage. 052 * 053 * @param numAck The number of acknowledged messages. 054 * The window will be increase by this credit number. 055 */ 056 public WindowMessage(int numAck) 057 { 058 this.numAck = numAck; 059 } 060 061 /** 062 * Creates a new WindowMessage from its encoded form. 063 * 064 * @param in The byte array containing the encoded form of the 065 * WindowMessage. 066 * @throws DataFormatException If the byte array does not contain a valid 067 * encoded form of the WindowMessage. 068 */ 069 public WindowMessage(byte[] in) throws DataFormatException 070 { 071 /* The WindowMessage is encoded in the form : 072 * <numAck> 073 */ 074 try 075 { 076 /* first byte is the type */ 077 if (in[0] != MSG_TYPE_WINDOW) 078 throw new DataFormatException("input is not a valid Window Message"); 079 int pos = 1; 080 081 /* 082 * read the number of acks contained in this message. 083 * first calculate the length then construct the string 084 */ 085 int length = getNextLength(in, pos); 086 String numAckStr = new String(in, pos, length, "UTF-8"); 087 pos += length +1; 088 numAck = Integer.parseInt(numAckStr); 089 } catch (UnsupportedEncodingException e) 090 { 091 throw new DataFormatException("UTF-8 is not supported by this jvm."); 092 } 093 } 094 095 /** 096 * {@inheritDoc} 097 */ 098 @Override 099 public byte[] getBytes() 100 { 101 /* 102 * WindowMessage contains. 103 * <numAck> 104 */ 105 try { 106 byte[] byteNumAck = String.valueOf(numAck).getBytes("UTF-8"); 107 108 int length = 1 + byteNumAck.length + 1; 109 110 byte[] resultByteArray = new byte[length]; 111 112 /* put the type of the operation */ 113 resultByteArray[0] = MSG_TYPE_WINDOW; 114 int pos = 1; 115 116 pos = addByteArray(byteNumAck, resultByteArray, pos); 117 118 return resultByteArray; 119 } 120 catch (UnsupportedEncodingException e) 121 { 122 return null; 123 } 124 } 125 126 127 /** 128 * Get the number of message acknowledged by the Window Message. 129 * 130 * @return the number of message acknowledged by the Window Message. 131 */ 132 public int getNumAck() 133 { 134 return numAck; 135 } 136 137 }