All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.novell.ldap.util.LDIFWriter Maven / Gradle / Ivy

/* **************************************************************************
 * $OpenLDAP$
 *
 * Copyright (C) 2002 - 2003 Novell, Inc. All Rights Reserved.
 *
 * THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND
 * TREATIES. USE, MODIFICATION, AND REDISTRIBUTION OF THIS WORK IS SUBJECT
 * TO VERSION 2.0.1 OF THE OPENLDAP PUBLIC LICENSE, A COPY OF WHICH IS
 * AVAILABLE AT HTTP://WWW.OPENLDAP.ORG/LICENSE.HTML OR IN THE FILE "LICENSE"
 * IN THE TOP-LEVEL DIRECTORY OF THE DISTRIBUTION. ANY USE OR EXPLOITATION
 * OF THIS WORK OTHER THAN AS AUTHORIZED IN VERSION 2.0.1 OF THE OPENLDAP
 * PUBLIC LICENSE, OR OTHER PRIOR WRITTEN CONSENT FROM NOVELL, COULD SUBJECT
 * THE PERPETRATOR TO CRIMINAL AND CIVIL LIABILITY.
 ******************************************************************************/
package com.novell.ldap.util;

import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.BufferedWriter;
import java.io.BufferedReader;
import java.io.StringReader;
import java.util.Iterator;

import com.novell.ldap.*;
import com.novell.ldap.util.Base64;

/**
 * LDIFWriter is used to write LDIF content records or LDIF change records
 * to the OutputStream object.
 *
 * 

The object of the class is used to generate LDIF content record or LDIF * change record lines and write the lines to OUtputStream

*/ public class LDIFWriter implements LDAPWriter { private Boolean requestFile = null; // request file=true private BufferedWriter bufWriter; private String version; /** * Constructs an LDIFWriter object. It allows the setting of the * OutputStreamReader object, and assumes the LDIF version is "1". * The type of file written is determined by the first message written * to the file. * *

If the first message is one of LDAPAddRequest, * LDAPDeleteRequest, LDAPModifyDNRequest, or LDAPModifyRequest the * file will be writen as an LDAP request (change) file.

* *

If the first message written to the file is an LDAPSearchResult object * an LDIF content file will be written.

* *

You are not allowed to mix request data and content data

* * @param out The OutputStream where the LDIF data will be written. * * @throws IOException for errors writing to the stream. */ public LDIFWriter(OutputStream out) throws IOException { this( out, "1", null ); return; } /** * Constructs an LDIFWriter object. It allows the setting of the * OutputStreamReader object, the LDIF version, and the type of LDIF file. * * @param out The OutputStream where the LDIF data will be written. * * @param version The version to set in the LDIF file, must be "1". * * @param request If true sets the out file type to request (change) data, * else the file type will be content. * * @throws IOException */ public LDIFWriter(OutputStream out, String version, boolean request) throws IOException { this( out, version, new Boolean(request)); return; } /** * Constructs an LDIFWriter object. It allows the setting of the * OutputStreamReader object, the LDIF version, and the type of LDIF file. * *

You are not allowed to mix request data and content data

* * @param out The OutputStream where the LDIF data will be written. * * @param version The version to set in the LDIF file, must be "1". * * @param request If true sets the out file type to request (change) data, * else the file type will be content. * * @throws IOException */ private LDIFWriter(OutputStream out, String version, Boolean request) throws IOException { super(); // check LDIF file version if ( version != "1" ) { throw new RuntimeException( "com.novell.ldap.ldif_dsml.LDIFWriter: LDIF version:" + "found: " + version + ", Should be: 1"); } this.version = version; requestFile = request; OutputStreamWriter osw = new OutputStreamWriter(out, "UTF-8"); bufWriter = new BufferedWriter( osw ); writeComments("This LDIF file was generated by the LDIF APIs. " + "of Novell's Java LDAP SDK"); writeVersionLine(); return; } /** * Write an LDAP record into LDIF file as LDAPContent data. * *

You are not allowed to mix request data and content data

* * @param entry LDAPEntry object * * @throws IOException if an I/O error occurs. * * @see com.novell.ldap.LDAPEntry */ public void writeEntry(LDAPEntry entry) throws IOException { writeEntry(entry, new LDAPControl[]{}); return; } /** * Write an LDAP record into LDIF file as LDAPContent data. * *

You are not allowed to mix request data and content data

* * @param entry LDAPEntry object * * @param controls Controls that were returned with this entry * * @throws IOException if an I/O error occurs. * * @see com.novell.ldap.LDAPEntry */ public void writeEntry(LDAPEntry entry, LDAPControl[] controls) throws IOException { requestFile = Boolean.FALSE; // This is a content file writeAddRequest(entry, controls); bufWriter.newLine(); return; } /** * Write an LDAP record into LDIF file. A request or change operation may * be objects of type LDAPAddRequest, LDAPDeleteRequest, * LDAPModifyDNRequest, or LDAPModifyRequest. * To write LDIF Content you must use an LDAPSearchResult object. * *

You are not allowed to mix request data and content data

* * @param request LDAPMessage object * * @throws IOException if an I/O error occurs. * * @see com.novell.ldap.LDAPSearchResults * @see com.novell.ldap.LDAPAddRequest * @see com.novell.ldap.LDAPDeleteRequest * @see com.novell.ldap.LDAPModifyDNRequest * @see com.novell.ldap.LDAPModifyRequest */ public void writeMessage(LDAPMessage request) throws IOException { LDAPControl[] controls = request.getControls(); // check for valid type switch( request.getType()) { case LDAPMessage.SEARCH_RESPONSE: if( requestFile == null) { requestFile = Boolean.FALSE; } if( isRequest()) { throw new RuntimeException("Attempting to write content " + " in a request stream"); } break; case LDAPMessage.ADD_REQUEST: case LDAPMessage.DEL_REQUEST: case LDAPMessage.MODIFY_RDN_REQUEST: case LDAPMessage.MODIFY_REQUEST: if( requestFile == null) { requestFile = Boolean.TRUE; } if( ! isRequest()) { throw new RuntimeException("Attempting to write request " + " in a content stream"); } break; default: throw new RuntimeException("Unsupported request type: " + request.toString()); } switch( request.getType()) { case LDAPMessage.SEARCH_RESPONSE: // LDAP Search Result Entry, write entry to outputStream LDAPSearchResult sreq = (LDAPSearchResult)request; writeAddRequest(sreq.getEntry(), controls); break; case LDAPMessage.ADD_REQUEST: // LDAPAdd request, write entry to outputStream LDAPAddRequest areq = (LDAPAddRequest)request; writeAddRequest(areq.getEntry(), controls); break; case LDAPMessage.DEL_REQUEST: // LDAPDelete request, write dn to outputStream LDAPDeleteRequest dreq = (LDAPDeleteRequest)request; writeDeleteRequest( dreq.getDN(), controls ); break; case LDAPMessage.MODIFY_RDN_REQUEST: // LDAPModDN request, write request data to outputStream LDAPModifyDNRequest rreq = (LDAPModifyDNRequest)request; // write to outputStream writeModifyDNRequest( rreq.getDN(), rreq.getNewRDN(), rreq.getDeleteOldRDN(), rreq.getParentDN(), controls ); break; case LDAPMessage.MODIFY_REQUEST: // LDAPModify request, write modifications to outputStream LDAPModifyRequest mreq = (LDAPModifyRequest)request; // write to outputStream writeModifyRequest( mreq.getDN(), mreq.getModifications(), controls ); break; } // write an empty line to separate records bufWriter.newLine(); return; } /** * Write a comment line into the LDIF OutputStream. * *

an '#' char is added to the front of each line to indicate that * the line is a comment line. If a line contains more than 78 * chars, it will be split into multiple lines each of which starts * with '#'

* * @param line The comment lines to be written to the OutputStream * * @throws IOException if an I/O error occurs. */ public void writeComments (String line) throws IOException { BufferedReader in = new BufferedReader(new StringReader( line)); String rline; while( (rline = in.readLine()) != null) { bufWriter.write("# ", 0, 2); bufWriter.write(rline, 0, rline.length()); bufWriter.newLine(); } return; } /** * Writes an exception as a comment in LDIF. * @param e Exception to be written. */ public void writeError(Exception e) throws IOException { this.writeComments(e.toString()); } /** * Gets the version of the LDIF data associated with the input stream * * @return the version number */ public String getVersion() { return version; } /** * Returns true if request data ist associated with the input stream, * or false if content data. * * @return true if input stream contains request data. */ public boolean isRequest() { return requestFile.booleanValue(); } /** * Check if the input byte array object is safe to make a String. * *

Check if the input byte array contains any un-printable value

* * @param bytes The byte array object to be checked. * * @return boolean object to incidate that the byte array * object is safe or not */ public boolean isPrintable( byte[] bytes ) { if (bytes == null) { throw new RuntimeException( "com.novell.ldap.ldif_dsml.LDIFWriter: null pointer"); } else if (bytes.length > 0) { for (int i=0; i 0x7e ) { return false; } } } return true; } /** * Write the version line of LDIF file into the OutputStream. * *

Two extra lines will be written to separate version line * with the rest of lines in LDIF file

* * @throws IOException if an I/O error occurs. */ private void writeVersionLine () throws IOException { // LDIF file is currently using 'version 1' String versionLine = new String("version: " + getVersion()); bufWriter.write( versionLine, 0, versionLine.length()); // write an empty line to separate the version line // with the rest of the contents in LDIF file bufWriter.newLine(); bufWriter.newLine(); return; } /** * Write a line into the OutputStream. * *

If the line contains more than 80 chars, it will be splited into * multiple lines each of which starts with a space ( ASCII ' ') except * the first one.

* * @param line The line to be written to the OutputStream * * @throws IOException if an I/O error occurs. */ private void writeLine(String line) throws IOException { int len = line.length(); if ( (line != null) && (len != 0)) { if (len <= 76) { // write short line bufWriter.write(line, 0, len); } else { int pos = 0; // break up long line // write the first 80 chars to outputStream (no blank at front) bufWriter.write(line, pos, 76); pos += 76; // remove the chars that already been written out bufWriter.newLine(); while((len - pos) > 75) { // write continuation line bufWriter.write(" ", 0, 1); bufWriter.write(line, pos, 75); // remove the chars that already been written out pos += 75; // start a new line bufWriter.newLine(); } // write the remaining part of the lien out bufWriter.write(" ", 0, 1); bufWriter.write(line, pos, len - pos); } // write an empty line bufWriter.newLine(); } } /** * Used to generate LDIF content record or LDIF change/add record lines. * *

Turn LDAPEntry object and LDAPControl[] object into LDIF record * lines

* * @param entry LDAPREntry object * @param ctrls LDAPControl object */ private void writeAddRequest( LDAPEntry entry, LDAPControl[] ctrls ) throws IOException { // write dn line(s) writeDN(entry.getDN()); if (isRequest()) { // add control line(s) if ( ctrls != null ) { writeControls( ctrls ); } // add change type line writeLine("changetype: add"); } // write attribute line(s) LDAPAttributeSet attrSet = entry.getAttributeSet(); Iterator allAttrs = attrSet.iterator(); while(allAttrs.hasNext()) { LDAPAttribute attr = (LDAPAttribute)allAttrs.next(); String attrName = attr.getName(); byte[][] values = attr.getByteValueArray(); if( values != null) { for (int i=0; iTurn entry DN, LDAPModification[] object, and LDAPControl[] object * into LDIF LDIF record fields and then turn record fields into LDIF * change/modify record lines

* * @param dn String object representing entry DN * @param mods LDAPModification array object * @param ctrls LDAPControl array object * * @see LDAPModification * @see LDAPControl */ private void writeModifyRequest( String dn, LDAPModification[] mods, LDAPControl[] ctrls ) throws IOException { int i, modOp, len = mods.length; String attrName; byte[][] attrValue; LDAPAttribute attr; // Write the dn field writeDN(dn); // write controls if there is any if ( ctrls != null ) { writeControls( ctrls ); } // save change type writeLine("changetype: modify"); // save attribute names and values for ( i = 0; i < len; i++ ) { modOp = mods[i].getOp(); attr = mods[i].getAttribute(); attrName = attr.getName(); attrValue = attr.getByteValueArray(); switch ( modOp ) { case LDAPModification.ADD: writeLine("add: "+ attrName); break; case LDAPModification.DELETE: writeLine("delete: "+ attrName); break; case LDAPModification.REPLACE: writeLine("replace: "+ attrName); break; default: } // add attribute names and values to record fields for(int j = 0;j < attrValue.length;j++) writeAttribute(attrName, attrValue[j]); // add separators between different modify operations writeLine("-"); } return; } /** * Used to generate LDIF change/moddn record lines. * *

Turn entry DN and moddn information into LDIF change/modify * record lines

* * @param dn String object representing entry DN * @param newRDN The NewRDN for the ModDN request * @param deleteOldRDN the deleteOldRDN flag * @param newSuperior the new Superior DN for a move, or null if rename * @param ctrls LDAPControl array object */ private void writeModifyDNRequest( String dn, String newRDN, boolean deleteOldRDN, String newSuperior, LDAPControl[] ctrls ) throws IOException { // Write the dn field writeDN(dn); // write controls if there is any if ( ctrls != null ) { writeControls( ctrls ); } // save change type writeLine("changetype: moddn"); // save new RDN writeLine( Base64.isLDIFSafe(newRDN)? "newrdn: " + newRDN: "newrdn:: " + Base64.encode(newRDN)); // save deleteOldRDN writeLine("deleteoldrdn:" + deleteOldRDN); // save newSuperior if ( newSuperior != null) { writeLine( Base64.isLDIFSafe(newSuperior)? "newsuperior: " + newSuperior: "newsuperior:: " + Base64.encode(newSuperior)); } return; } /** * Used to generate LDIF change/delete record lines. * *

Turn entry DN, controls * and change type into LDIF change/delete record fields and then turn * record fields into LDIF moddn record lines

* * @param dn String object representing entry DN * @param ctrls LDAPControl array object * * @see LDAPControl */ private void writeDeleteRequest( String dn, LDAPControl[] ctrls ) throws IOException { // write dn line(s) writeDN(dn); // write control line(s) if ( ctrls != null ) { writeControls( ctrls ); } // write change type writeLine("changetype: delete"); return; } /** * Write the DN to the outputStream. If the DN characters are unsafe, * the DN is encoded. * * @param dn the DN to write */ private void writeDN(String dn) throws IOException { writeLine(Base64.isLDIFSafe(dn)? "dn: "+dn: "dn:: "+ Base64.encode(dn)); return; } /** * Write control line(s). * * @param ctrls LDAPControl array object */ private void writeControls(LDAPControl[] ctrls) throws IOException { for ( int i = 0; i < ctrls.length; i++ ) { // get control value byte[] cVal = ctrls[i].getValue(); // write control value writeLine( (cVal != null && cVal.length > 0)? "control: " + ctrls[i].getID() + " " + ctrls[i].isCritical() + ":: " + Base64.encode(cVal): "control: " + ctrls[i].getID() + " " + ctrls[i].isCritical() ); } return; } /** * Write attribute name and value into outputStream. * *

Check if attrVal starts with NUL, LF, CR, ' ', ':', or '<' * or contains any NUL, LF, or CR, and then write it out

*/ private void writeAttribute(String attrName, String attrVal) throws IOException { if (attrVal != null) { writeLine( Base64.isLDIFSafe(attrVal)? attrName + ": " + attrVal : attrName + ":: " + Base64.encode(attrVal) ); } return; } /** * Write attribute name and value into outputStream. * *

Check if attribute value contains NON-SAFE-INIT-CHAR or * NON-SAFE-CHAR. if it does, it needs to be base64 encoded and then * write it out

*/ private void writeAttribute(String attrName, byte[] attrVal) throws IOException { if (attrVal != null) { writeLine( (Base64.isLDIFSafe(attrVal) && isPrintable(attrVal))? attrName + ": " + new String(attrVal, "UTF-8"): attrName + ":: " + Base64.encode(attrVal) ); } return; } /** * Write all remaining data to the output stream */ public void finish() throws IOException { bufWriter.flush(); return; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy