/*
* S. Bahloul & R. Ouazana
* Copyright (C) 2003 LINAGORA
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.linagora.ldap.extended;
import java.io.Serializable;
import javax.naming.NamingException;
import javax.naming.SizeLimitExceededException;
import javax.naming.ldap.ExtendedRequest;
import javax.naming.ldap.ExtendedResponse;
/**
* A class conforming to the ExtendedRequest that implements the
* test modify extended operation.
*
* @see javax.naming.ldap.ExtendedRequest
*/
public class TestModifyLdapOperationRequest implements ExtendedRequest, Serializable {
/** The OID of the test modify extended operation */
public static final String LDAP_EXOP_TEST_MODIFY = "1.3.6.1.4.1.13129.1.5.1";
/** The BER tag for */
public static final byte LDAP_TAG_EXOP_TEST_MODIFY_ATTRIBUTE = (byte) 0x80;
/** The BER tag for */
public static final byte LDAP_TAG_EXOP_TEST_MODIFY_AUTHOR = (byte) 0x81;
/** The BER tag for */
public static final byte LDAP_TAG_EXOP_TEST_MODIFY_TARGET = (byte) 0x82;
/** The BER tag for */
public static final byte LDAP_TAG_EXOP_TEST_MODIFY_ISOK = (byte) 0x80;
private static byte LDAP_TAG_SEQUENCE_START = (byte) 0x30;
private static byte LDAP_TAG_VALID_VALUE = (byte) 0xFF;
/** The size of ber_len_t */
public static final byte SIZE_OF_BER_LEN_T = (byte) 4;
/**
* Décode la berValue pour en tirer la donnée.
* Le premier octet correspond au début d'une séquence.
* Le second à la longueur du message.
* Le troisième au nom de l'attribut.
* Le quatrième à la longueur de l'attribut.
* Le cinquième est la valeur.
* On vérifie donc que
* le premier octet vaut bien 0x30 et que
* le troisième octet vaut bien LDAP_TAG_EXOP_TEST_MODIFY_ISOK
* @param berValue
* @param offset
* @param length
* @return true si ce cinquième byte vaut 1
*/
public static boolean getOk(byte[] berValue, int offset, int length) {
if ((berValue[0] == (byte) LDAP_TAG_SEQUENCE_START) &&
(berValue[2] == LDAP_TAG_EXOP_TEST_MODIFY_ISOK)) {
return berValue[4] == (byte) LDAP_TAG_VALID_VALUE;
} else {
return false;
}
}
/** The attribute to test to */
private String mAttr;
/** The dn we want to test with */
private String mDnAuthor;
/** The dn we want to test to */
private String mDnTarget;
/**
* Creates a new TestModifyRequest
instance.
* @param dn the dn of the author
* @param dn the dn of the target whose attribute is to test
* @param attr the attribute to test
* @exception NullPointerException if dn or password is null
* @exception SizeLimitExceededException when the dn or password
* is too long
*/
public TestModifyLdapOperationRequest(String dnAuthor, String dnTarget, String attr)
throws NullPointerException, SizeLimitExceededException {
if (dnAuthor == null || dnTarget == null) {
throw new NullPointerException("DN's cannot be null");
}
if (attr == null) {
throw new NullPointerException("Attribute cannot be null");
}
mDnAuthor = dnAuthor;
mDnTarget = dnTarget;
mAttr = attr;
}
/**
* Creates the extended response. With OpenLDAP, the extended
* operation for test modification doesn't create a
* response so we just return null here.
*
* @param id the OID of the response
* @param berValue the BER encoded value of the response
* @param offset the offset
* @param length the length of the response
* @return returns null as the modify password operation doesn't
* generate a response.
* @exception NamingException if an error occurs
*/
public ExtendedResponse createExtendedResponse(String id, byte[] berValue, int offset, int length) throws NamingException {
return new TestModifyLdapOperationResponse(id, berValue, getOk(berValue, offset, length));
}
/**
* Get the BER encoded value for this operation.
* This value contains the following bytes :
*
* Sequence tag (1) + sequence length (variable) + dnAuthor tag (1) +
* dnAuthor length (1) + dnAuthor (variable) + dnTarget tag (1) +
* dnTarget length (1) + dnTarget (variable) + attribute tag (1) +
* attribute length (1) + attribute (variable)
*
*
* @param mDnAuthor
* @param mDnTarget
* @param mAttr
* @return a bytearray containing the BER sequence.
*/
public static byte[] getEncodedValue(String mDnAuthor, String mDnTarget, String mAttr) {
try {
int dataToWriteIndex;
// Création de tableaux d'écriture
byte[] headersToWrite = new byte[] {
LDAP_TAG_EXOP_TEST_MODIFY_ATTRIBUTE,
LDAP_TAG_EXOP_TEST_MODIFY_AUTHOR,
LDAP_TAG_EXOP_TEST_MODIFY_TARGET
};
byte[][] dataToWrite = new byte[][] {
getBytesArray(mAttr),
getBytesArray(mDnAuthor),
getBytesArray(mDnTarget)
};
// valeur temporaire de la longueur de cette longueur
int tempLenlen;
int length;
int len = 6;
// Calcul de la longueur en tenant compte de la longueur des longueurs des différents éléments
for(dataToWriteIndex=0; dataToWriteIndex>= 8;
}
// writing the array of bytes
for (int j = SIZE_OF_BER_LEN_T - (lenlen - 1) - 1; j <= SIZE_OF_BER_LEN_T - 1; j++)
encoded[i++] = tmp[j];
}
return i;
}
/**
* @param dnAuthorLength
*/
private static void checkLength(String string, int length) throws SizeLimitExceededException {
if (length <= 0) {
throw new SizeLimitExceededException("value cannot be 0 length : "+string);
}
if (length > 0xFF) {
throw new SizeLimitExceededException("value cannot be larger then 255 characters : "+string);
}
}
/**
* @param byteHeader
* @param attr
* @return
*/
private static int fillArrayAndMoveForward(byte[] arrayToFill, byte byteHeader, byte[] arrayToAdd, int i) throws SizeLimitExceededException {
arrayToFill[i++] = byteHeader;
int length = arrayToAdd.length;
i = writeLenAndMoveForward(arrayToFill, getLenlen(length), length, i);
System.arraycopy(arrayToAdd, 0, arrayToFill, i, arrayToAdd.length);
i += arrayToAdd.length;
return i;
}
/**
* @param dnAuthor
* @return
*/
private static byte[] getBytesArray(String value) throws SizeLimitExceededException {
getLength(value);
return value.getBytes();
}
/**
* Returns the ID of this extended operation.
*
* @return a String with the OID of this operation
*/
public String getID() {
return LDAP_EXOP_TEST_MODIFY;
}
/**
* @param dnAuthor
* @return
*/
private static int getLength(String string) throws SizeLimitExceededException {
int length = string.length();
checkLength(string, length);
return length;
}
/**
* @param len
* @return length of len if len > 128, 0 else
*/
private static int getLenlen(int len) throws SizeLimitExceededException {
int mask, i;
if (len < 128)
return 0;
// Computing number of bytes in len
for (i = SIZE_OF_BER_LEN_T - 1; i > 0; i--) {
mask = (0xff << (i * 8));
if ((len & mask) != 0)
break;
}
// Error if more than 4 bytes
if (++i > 4) {
throw new SizeLimitExceededException("The total length is too high");
}
// Return number of bytes
return i;
}
/**
* @see javax.naming.ldap.ExtendedRequest#getEncodedValue()
*/
public byte[] getEncodedValue() {
return getEncodedValue(mDnAuthor, mDnTarget, mAttr);
}
}