/* **************************************************************************

 * $Novell: GetLDAPBackupRestore.java,v 1.3 2005/01/18 13:19:31 $

 *

 * Copyright (C) 1999, 2000, 2001 Novell, Inc. All Rights Reserved.

 * 

 * THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND

 * TREATIES. USE AND REDISTRIBUTION OF THIS WORK IS SUBJECT TO THE LICENSE

 * AGREEMENT ACCOMPANYING THE SOFTWARE DEVELOPMENT KIT (SDK) THAT CONTAINS

 * THIS WORK. PURSUANT TO THE SDK LICENSE AGREEMENT, NOVELL HEREBY GRANTS TO

 * DEVELOPER A ROYALTY-FREE, NON-EXCLUSIVE LICENSE TO INCLUDE NOVELL'S SAMPLE

 * CODE IN ITS PRODUCT. NOVELL GRANTS DEVELOPER WORLDWIDE DISTRIBUTION RIGHTS

 * TO MARKET, DISTRIBUTE, OR SELL NOVELL'S SAMPLE CODE AS A COMPONENT OF

 * DEVELOPER'S PRODUCTS. NOVELL SHALL HAVE NO OBLIGATIONS TO DEVELOPER OR

 * DEVELOPER'S CUSTOMERS WITH RESPECT TO THIS CODE. 

 ***************************************************************************/

import java.io.UnsupportedEncodingException;

import java.util.Vector;



import com.novell.ldap.LDAPConnection;

import com.novell.ldap.LDAPException;

import com.novell.ldap.LDAPExtendedOperation;

import com.novell.ldap.LDAPExtendedResponse;

import com.novell.ldap.LDAPLocalException;

import com.novell.ldap.extensions.LDAPBackupRequest;

import com.novell.ldap.extensions.LDAPBackupResponse;

import com.novell.ldap.extensions.LDAPRestoreRequest;



/**

 *  The following sample demonstrates how to do Object based backup and restore 

 *  on a LDAP server using LDAP extensions.

 *

 */

public class GetLDAPBackupRestore {



	/**

	 *  Default constructor

	 */

	public GetLDAPBackupRestore() {

		super();

	}



	public static void main(String[] args) {

		if (!(args.length == 5 || args.length == 6 || args.length == 7)) {

            System.err.println("Usage: java GetLDAPBackupRestore <host Name> "

                              + "<port number> <login dn> <password>\n "

                              + " <object DN> [encrypted password (optional)]" +

                              		" [state Info (optional)]");

            System.err.println("\nFor Non encrypted objects::");

            System.err.println("--------------------------");

            System.err.println("	Example: java GetLDAPBackupRestore Acme.com 389 "

                              + "\"cn=Admin,o=Acme\" secret\n "

                              + "\"cn=TestUser,o=Acme\"");

            System.err.println("\nFor Encrypted objects::");

            System.err.println("----------------------");

            System.err.println("	Example: java GetLDAPBackupRestore Acme.com 389 "

                              + "\"cn=Admin,o=Acme\" secret\n "

                              + "\"cn=TestUser,o=Acme\" testpassword");

            System.exit(1);

        }



		int ldapVersion = LDAPConnection.LDAP_V3;

		String ldapHost = args[0];

		int ldapPort = Integer.parseInt(args[1]);

		String loginDN = args[2];

		String password = args[3];

		String objectDN = args[4];

		String encPasswd = null; 

		String stateInfo = null; 

		if(args.length == 6 && args[5] != null)

		{

			encPasswd = args[5];

		}

		if(args.length == 7 && args[6] != null)

		{

			stateInfo = args[6];

		}

		//Create a LDAPConnection object

		LDAPConnection ld = new LDAPConnection();



		try {

			// connect to the server

			ld.connect(ldapHost, ldapPort);

			// bind to the server

			ld.bind(ldapVersion, loginDN, password.getBytes("UTF8"));

			System.out.println("\nLogin succeeded");

			System.out.println("\n Object DN =" + objectDN);

			

			//Call backup method

			Vector testData;

			if(encPasswd == null)

				testData = backup(ld, objectDN, null, stateInfo);

			else

				testData = backup(ld, objectDN, encPasswd.getBytes("UTF8"), 

						stateInfo);

			

			//Call restore method

			if(encPasswd == null)

				restore(ld, objectDN, null, testData);

			else

				restore(ld, objectDN, encPasswd.getBytes("UTF8"), testData);



			/* Done, so disconnect */

			if (ld.isConnected())

				ld.disconnect();

		} catch (LDAPException e) {

			System.out.println("Error: " + e.toString());

		} catch (UnsupportedEncodingException e) {

			System.out.println("Error: " + e.toString());

		}



	}



	/**

	 *

	 * Constructs an extended operation object for getting data about any Object

	 * and make a call to ld.extendedOperation to get the response <br>

	 *

	 * @param ld 			LDAPConnection handle

	 * <br>

	 * @param objectDN 		The DN of the object to be backed up

	 * <br>

	 * @param stateInfo (Optional) The state information of the object to backup. 

	 * This parameter is a String which contains combination of modification 

	 * timestamp and revision number of object being backed up. The format 

	 * of both modification time stamp and revision should pertain to eDirectoty

	 * standard format of taking modification timestamp and revision.

	 * Separator being used between these two is a '+' character.<br> 

	 * This is an Optional parameter. So pass null if you if don't have any

	 * state information data

	 * <br>

	 * @return testData A Vector containing BufferLength and ParsedString 

	 * to be used in restore call

	 */

	public static Vector backup(LDAPConnection ld, String objectDN,

			byte[] passwd, String stateInfo) {

		int intInfo;

		String strInfo;

		byte[] returnedBuffer; //Actual data blob returned as byte[]

		Vector testData = new Vector(4);

		testData.add(0, new Integer(-1)); //Mark the rc default as failed backup

		try {

			LDAPExtendedOperation request = new LDAPBackupRequest(objectDN,

					passwd, stateInfo);



			//		System.out.println("\nBackup request succeeded");

			LDAPExtendedResponse response = ld.extendedOperation(request);



			//		System.out.println("\nBackup response succeeded");

			int result = response.getResultCode();

			testData.remove(0);

			testData.add(0, new Integer(result));

			if ((result == LDAPException.SUCCESS)

					&& (response instanceof LDAPBackupResponse)) {

				

				System.out.println("Backup Info:");



				strInfo = ((LDAPBackupResponse) response).getStatusInfo();

				System.out.println("    Status Info: " + strInfo);



				intInfo = ((LDAPBackupResponse) response).getBufferLength();

				System.out.println("    Buffer length: " + intInfo);

				testData.add(new Integer(intInfo));



				strInfo = ((LDAPBackupResponse) response).getChunkSizesString();

				System.out.println("    Chunk sizes: " + strInfo);

				testData.add(strInfo);	

				

				

				returnedBuffer = ((LDAPBackupResponse) response).getReturnedBuffer();

//				System.out.println("    Data: " + returnedBuffer);

				testData.add(returnedBuffer);



				System.out.println("\nbackup information succeeded\n");

				

			} else {

				System.out.println("Could not backup the information.\n");

				throw new LDAPException(response.getErrorMessage(), response

						.getResultCode(), (String) null);

			}

			



		} catch (LDAPException e) {

			System.out.println("Error: " + e.toString());

		}

		return testData;

	}

	

	/**

	 *

	 * Constructs an extended operation object for restoring data of retreived 

	 * Object and make a call to ld.extendedOperation to get the response <br>

	 *

	 * @param ld 			LDAPConnection handle

	 * <br>

	 * @param objectDN 		The DN of the backed up object

	 * <br>

	 * @param testData    The Vector containing BufferLength and ParsedString 

	 * got in call to backup request

	 */

	public static void restore(LDAPConnection ld, String objectDN, 

			byte[] passwd, Vector testData) {

		int intInfo;

		String strInfo;

		

		try {

			if(((Integer)testData.get(0)).intValue() != 0){

				System.out.println("Note: The test program did not proceed " +

						"with restore since backup was not proper");

				System.exit(0);

			}

				

			LDAPExtendedOperation request = new LDAPRestoreRequest(

					objectDN, passwd,

					((Integer)testData.get(1)).intValue(),

					(String)testData.get(2),

					(byte[])testData.get(3));



			LDAPExtendedResponse response = ld.extendedOperation(request);

			

			if ( response.getResultCode() == LDAPException.SUCCESS )

			    System.out.println("Restore Request succeeded\n");

			else {

			    System.out.println("Restore Request Failed");

			    throw new LDAPException( response.getErrorMessage(),

			                             response.getResultCode(),

			                             (String)null);

			}

				

		} catch (LDAPException e) {

			System.out.println("Error: " + e.toString());

		}

		

	}

}