所需jar包ldap.jar、 jldap-4.3-source.jar

  http://www.java2s.com/Code/Jar/l/Downloadldapjar.htm

浏览器输入http://maven.aliyun.com/nexus进入后搜索jldap,找到com.novell.ldap 这里我用的是4.3版本,点击source下载

 

https://www.novell.com/documentation/developer/samplecode/jldap_sample/
打开浏览器输入以上地址,Ldif2Ldap.java并找到LDIFReader.java.这个类就是用来读取ldif文件并添加到ldap目录服务中,再将ldap.jar放入项目中。
  • 方法一:
    使用Ldif2Ldap.java,传入相应的参数(<文件名称> <IP> <登录名> <密码>)就可以将ldif文件导入到ldap目录服务中。但这里需要注意ldif文件的格式,否则回报

    com.novell.ldap.ldif_dsml.LDIFReader:  version: found 。。。

    因为这里采用的是Novell 导入需要LDIF 1格式的文件,以下是LDIF 1文件的基本规则:
      

    • 第一个非注释行必须是版本号:1.
    • 版本号后面跟有一个或多个记录。
    • 每个记录由多个字段组成,一行一个字段。
    • 各行使用换行符或回车符/换行符对分隔。
    • 各记录由一个或多个空行分隔。
    • 存在两种不同类型的 LDIF 记录:内容记录和更改记录。对 LDIF 文件可以包含的记录数目没有限制,但它们必须属于同一类型。在同一个 LDIF 文件中不能既有内容记录又有更改记录。
    • 以井字符 (#) 开头的行是注释行,在处理 LDIF 文件时将被忽略。
    version:1
    dn:: Yz3kuK3ljY7kurrmsJHlhbHlkozlm70=
    changetype:add
    objectClass: top
    objectClass: country
    c:: 5Lit5Y2O5Lq65rCR5YWx5ZKM5Zu9 dn:: bz3lm5vlt50sIGM95Lit5Y2O5Lq65rCR5YWx5ZKM5Zu9
    changetype:add
    objectClass: top
    objectClass: organization
    o:: 5Zub5bed dn:: bz3miJDpg70sbz3lm5vlt50sIGM95Lit5Y2O5Lq65rCR5YWx5ZKM5Zu9
    changetype:add
    objectClass: top
    objectClass: organization
    o:: 5oiQ6YO9
    • 注:dn:安全 UTF-8 相对判别名 dn::Base64 编码的相对判别名

    运行后,打开浏览器输入以下地址

    https://www.netiq.com/communities/cool-solutions/cool_tools/gawors-excellent-ldap-browsereditor-v282/

    下载LDAP Browser\Editor v2.8.2后双击lbe.jar,连接ldap后,就可以发现数据已成功的添加进去了

  • 方法二:

使用Ldif2Ldap.java,传入相应的参数(<文件名称> <IP> <登录名> <密码>)就可以将ldif文件导入到ldap目录服务中。

int  version = 1;
int ldapPort = LDAPConnection.DEFAULT_PORT;
int ldapVersion = LDAPConnection.LDAP_V3;
String fileName = args[0];
String ldapHost = args[1];
String loginDN = args[2];
String password = args[3];
LDIFReader reader = null;
LDAPEntry entry;
LDAPMessage msg, retMsg;
LdifImport readerTest = new LdifImport();
LDAPConnection lc = new LDAPConnection();
File file = new File(fileName);
if(!file.exists()){
logger.error("要读取的文件不存在");
return false;
}
try {
FileInputStream fis = new FileInputStream(new File(fileName));
reader = new LDIFReader(fis, version);
} catch (Exception e) {
logger.error("读取 " + fileName +"文件失败");
return false;
}

这里LDIFReader类在方法一中调用的是ldap.jar中的类,考虑到ldif文件的格式,我在这里打算更改LDIFReader类中的源代码,在 jldap-4.3-source.jar 的工具包中,复制并修改。

更改后的LDIFReader.java

package com.cn.ccc.ggg.ldap.core.common;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import com.novell.ldap.LDAPAttribute;
import com.novell.ldap.LDAPAttributeSet;
import com.novell.ldap.LDAPControl;
import com.novell.ldap.LDAPEntry;
import com.novell.ldap.LDAPException;
import com.novell.ldap.LDAPLocalException;
import com.novell.ldap.LDAPMessage;
import com.novell.ldap.LDAPModification;
import com.novell.ldap.LDAPSearchResult;
import com.novell.ldap.LDAPAddRequest;
import com.novell.ldap.LDAPDeleteRequest;
import com.novell.ldap.LDAPModifyDNRequest;
import com.novell.ldap.LDAPModifyRequest;
import com.novell.ldap.util.Base64;
import com.novell.ldap.util.LDAPReader; /**
* 处理inputStream对象以读取LDIF文件的类
*
* <p>该calss从LDIF文件读取LDAP条目和LDAP请求</p>
*
* <p>构造函数使用默认大小值8,192来创建 缓冲字符输入流并假定大小很大足以容纳下一个字段的dn字段和第一行当前正在阅读的LDIF文件中的第一条记录</p>
*
* <p>构造函数使用'1'作为默认的LDIF文件版本</p>
*/
public class LDIFReader implements LDAPReader { private boolean requestFile=true; // request file=true
private String version; // LDIF file version
private int reqType; // int rep. of name
private int lNumber; // line number
private int dnlNumber; // dn line number
private int fNumber = 0; // number of fields
private byte[] bytes= new byte[0]; // for any byte value
private boolean control = false; // is control field
private String entryDN; // entry dn
private String[] modInfo; // for moddn
private ArrayList rFields = new ArrayList(); // record fields
private ArrayList cList = new ArrayList(); // control list
private BufferedReader bufReader;
private LDAPControl[] controls = null; // req controls
private LDAPEntry currentEntry = null;
private LDAPModification[] mods;
private LDAPMessage currentRequest = null; /**
* 通过初始化LDIF_VERSION,isRequest构造LDIFReader对象,
     * InputStreamReader和BufferedReader
*
* @param in The InputStream object to be processed by LDIFReader
*/
public LDIFReader( InputStream in )
throws IOException, LDAPLocalException
{
this( in, 1, 8192 );
return;
} /**
* 通过初始化LDIF_VERSION,isRequest构造LDIFReader对象,
     * InputStreamReader和BufferedReader
*
* @param in The Inputstream object to be processed by LDIFReader
* @param version The version currently used in the LDIF file
*/
public LDIFReader( InputStream in, int version )
throws IOException, LDAPLocalException
{
this( in, version, 8192 );
return;
}
/**
* 通过初始化LDIF_VERSION,isRequest构造LDIFReader对象,
     * InputStreamReader和BufferedReader
*
* @param in The Inputstream object to be processed by LDIFReader
* @param version The version currently used in the LDIF file
* @param bufSize The size used to create a buffering character-input
* stream. The defaule value is 8,192.
*/
public LDIFReader(InputStream in, int version, int bufSize)
throws IOException, LDAPLocalException
{ super(); String line = null; if ( version != 1 ) { // check LDIF file version
throw new RuntimeException("com.novell.ldap.ldif_dsml.LDIFReader:"
+ "found: " + version + ", Should be: 1");
} setVersion( version );
InputStreamReader isr = new InputStreamReader(in, "US-ASCII");
bufReader = new BufferedReader(isr); //为了确定它是否是LDIF内容文件或LDIF更改
//文件,dn字段的第一行和旁边的有意义的行
// dn字段被读入内存。 //在版本行之前跳过前面的空行和注释行
/* while( (line = bufReader.readLine())!= null &&
(line.length() == 0 || line.startsWith("#")) ) {
this.lNumber++;
} //已经到达文件的末尾 if ( line == null ) {
throw new LDAPLocalException(
"com.novell.ldap.ldif_dsml.LDIFReader:"
+ " The file contains no LDIF info",
LDAPException.LOCAL_ERROR);
} //需要增加行号
this.lNumber++; // 1 //第一个有效行(版本行)。 检查版本行 if (line.startsWith("version:")) {
this.version = line.substring("version:".length()).trim();
if ( !this.version.equals( "1") ) {
throw new LDAPLocalException(
"com.novell.ldap.ldif_dsml.LDIFReader: "
+ "version: found '" + version + "' (on line "
+ this.lNumber + " of the file), should be '1'",
LDAPException.LOCAL_ERROR);
}
}else { // 第一行有效行不是版本行
throw new LDAPLocalException("com.novell.ldap.ldif_dsml.LDIFReader:"
+ " Version line must be the first meaningful line(on line " +
this.lNumber + " of the file)",
LDAPException.LOCAL_ERROR);
}
*/ // 跳过版本行和之间的空行和注释行
// LDIF的第一个记录中的dn字段的第一行
// 文件,读取第一条记录的dn字段的第一行
do {
//标记第一个dn行,所以我们以后可以回到这里
bufReader.mark( bufSize );
line=bufReader.readLine(); if ( line == null) { // end of file
throw new LDAPLocalException( "com.novell.ldap.ldif_dsml."
+ "LDIFReader: the LDIF file only contains version line.",
LDAPException.LOCAL_ERROR);
}
this.lNumber++;
} while((line.length()== 0) || line.startsWith("#")); //稍后会检查dn字段; 现在忽略了其余的一行
// dn字段,并在dn字段后面读取有效行
while ( (line = bufReader.readLine()) != null ) { // ! a part of dn field ! a comment line
if ( !line.startsWith(" ") && !line.startsWith("#") ) {
//到第一个记录的结尾
if ( line.length() == 0 ) {
//空行 这个记录只有dn字段
throw new LDAPLocalException("com.novell.ldap.ldif_dsml."
+ "LDIFReader: the first record only has dn field(line "
+ this.lNumber + " of the file)",
LDAPException.LOCAL_ERROR);
}
//刚刚读取的行应该是开头的行
//'control', 'changetype', 属性名
break;
}
} if ( line == null) { // end of file
throw new LDAPLocalException("com.novell.ldap.ldif_dsml."
+ "LDIFReader: the first record only has dn field(line "
+ this.lNumber + " of the file)",
LDAPException.LOCAL_ERROR);
} if(line.startsWith("changetype")||line.startsWith("control")){
setRequest(true); // LDIF使用LDAP操作请求更改文件
}
else {
setRequest(false); // 带有LDAP条目的LDIF内容文件
} setRequest(true); //返回到LDIF文件的第一个记录的开头
//稍后读取可以从第一条记录开始
bufReader.reset(); //
this.lNumber--;
return;
} /**
* 获取与输入流相关联的LDIF数据的版本
*
* @return the version number
*/
public String getVersion()
{
return version;
} /**
* 获取与输入流相关联的LDIF数据的版本
*
* @param value the version number
*/
private void setVersion(int value)
{
version = String.valueOf(value);
return;
} /**
* 如果请求数据与输入流相关联,则返回true,
     * 或如果内容数据为false。
*
* @return true if input stream contains request data.
*/
public boolean isRequest()
{
return requestFile;
} /**
* 设置正在读取的文件的请求类型,如果请求数据为true
     * 或如果内容数据为false。
*
* @param type sets the type of file to content or request data.
*/
private void setRequest( boolean type)
{
requestFile = type;
return;
} /**
* 从LDIF请求(更改)文件或内容文件读取LDAP请求。.
*
* @return LDAPMessage specified by the record
*/
public LDAPMessage readMessage()
throws IOException, LDAPException
{
readRecordFields(); // 读取记录字段
if ( this.rFields == null ) { // 文件结尾
return null;
}
toRecordProperties(); // 设置记录属性 if (!isRequest()) {
return new LDAPSearchResult(currentEntry, null);
} switch( this.reqType ) {
case LDAPMessage.SEARCH_RESPONSE :
this.currentRequest = new LDAPAddRequest(currentEntry, controls);
break;
case LDAPMessage.ADD_REQUEST :
this.currentRequest = new LDAPAddRequest(currentEntry, controls);
break;
case LDAPMessage.DEL_REQUEST :
this.currentRequest = new LDAPDeleteRequest(this.entryDN, controls);
break;
case LDAPMessage.MODIFY_RDN_REQUEST :
boolean delOldRdn; if ( Integer.parseInt(this.modInfo[1]) == 1 ) {
delOldRdn = true;
} else {
delOldRdn = false;
} if((modInfo[2].length())==0 ) {
this.currentRequest = new LDAPModifyDNRequest( this.entryDN,
this.modInfo[0], null, delOldRdn, controls);
} else {
this.currentRequest = new LDAPModifyDNRequest(this.entryDN,
this.modInfo[0], modInfo[2], delOldRdn, controls);
}
break;
case LDAPMessage.MODIFY_REQUEST :
this.currentRequest =
new LDAPModifyRequest(this.entryDN, mods, controls);
break;
default:
} return this.currentRequest;
} /**
* 读取当前记录中的所有行,将记录行转换为
     * 记录字段,并修剪记录字段中的多余空格。
*/
private void readRecordFields()
throws IOException, LDAPException
{ String line;
StringBuffer bLine = new StringBuffer(80); // clean rFields
this.rFields.clear(); //跳过空和注释行并读取第一个dn
//行记录
while( (line = bufReader.readLine())!= null &&
(line.length() == 0 || line.startsWith("#")) ) {
this.lNumber++;
} this.lNumber++;
this.dnlNumber = this.lNumber; if (line == null) { // 文件结尾
this.rFields = null;
}
else {
//检查dn行是否以'dn:'开头
if (!line.startsWith("dn:")) {
throw new LDAPLocalException("com.novell.ldap.ldif_dsml." +
"LDIFReacer: Any record should start with 'dn:'(on line "
+ this.lNumber + " of the file).",
LDAPException.LOCAL_ERROR);
} //保存第一个dn行
bLine.append(line); //读取除注释行之外的记录的其他行。
//读取停止在用于分隔的空行
//当前记录与下一个
while ((line = bufReader.readLine())!=null && line.length()!=0 ) {
if ( !line.startsWith("#") ) { //跳过注释行
if ( line.startsWith(" ") ) { //续行?
// trim off leading ' ' and append it to previous line
bLine.append(line.substring(1, line.length()));
}
else { // 新的一行
// handle pewvious field
bLine = trimField(bLine); // trime上一个字段
if(!this.control) { // 如果不是,保存它
this.rFields.add(bLine); // 一个控制字段
}
//处理新行
bLine = new StringBuffer(80);// create a new buffer
bLine.append(line); // to hold new line
}
}
this.lNumber++;
}
//修剪并保存最后一个字段
bLine = trimField(bLine);
this.rFields.add(bLine); this.lNumber++; // 增加行号
this.fNumber = this.rFields.size(); // 获取字段数
}
return;
} /**
* 设置记录属性。
* <p>对于LDIF内容记录,创建由此记录指定的LDAPEntry</p>
*
* <p>对于LDIF更改记录,根据请求类型,将创建LDAPEntry,modInfo或LDAPModifiction数组以及与请求相关联的控件</p>
*/
private void toRecordProperties()
throws IOException, LDAPException
{ int index;
String req; // set entry DN
StringBuffer dnField = (StringBuffer)this.rFields.get(0);
if (dnField.charAt(3) != ':') {
// commom string value
this.entryDN = dnField.substring( 3, dnField.length());
}
else {
// base64 encoded
this.bytes = Base64.decode(dnField, 4, dnField.length());
try {
this.entryDN = new String(this.bytes, "UTF-8");
} catch( UnsupportedEncodingException ue) {
throw new RuntimeException(
"UTF-8 String encoding not supported by JVM");
}
} if ( !isRequest() ) { // 是一个内容LDIF文件
toLDAPEntry();
} else { // 是一个更改LDIF文件
index = 10; // length of 'changetype'
// ctField - changetype field
StringBuffer ctField = (StringBuffer)this.rFields.get(1); this.reqType = LDAPMessage.ADD_REQUEST;
toLDAPEntry(); /*if(!ctField.substring(0, index).equalsIgnoreCase("changetype")) {
throw new LDAPLocalException("com.novell.ldap.ldif_dsml."
+"LDIFReader: malformed changetype field in record starting"
+ " on line " + this.dnlNumber + " of the file).",
LDAPException.LOCAL_ERROR);
}
// 获取类型: 'add', 'delete','moddn', 'modrdn', or 'modify'
req = ctField.substring(index+1); // 设置请求类型
if ( req.equalsIgnoreCase("add") ) {
this.reqType = LDAPMessage.ADD_REQUEST;
toLDAPEntry();
}
else if ( req.equalsIgnoreCase("delete") ) {
this.reqType = LDAPMessage.DEL_REQUEST;
}
else if ( req.equalsIgnoreCase("modrdn") ) {
this.reqType = LDAPMessage.MODIFY_RDN_REQUEST;
toModInfo();
}
else if ( req.equalsIgnoreCase("moddn") ) {
this.reqType = LDAPMessage.MODIFY_RDN_REQUEST;
toModInfo();
}
else if ( req.equalsIgnoreCase("modify") ) {
this.reqType = LDAPMessage.MODIFY_REQUEST;
toLDAPModifications();
}
else {
throw new LDAPLocalException("com.novell.ldap.ldif_dsml."
+ "LDIFReader: unsupported request type '" + req
+ "' specified in changetype filed of the record starting "
+ "on line " + this.dnlNumber + " of the file.",
LDAPException.LOCAL_ERROR);
}*/ if (this.cList.size() > 0) {
this.controls = new LDAPControl[this.cList.size()];
}
}
return;
} /**
* 处理LDIF记录字段以生成LDAPEntry。
*/
private void toLDAPEntry()
throws LDAPLocalException
{
int i, index, fieldIndex;
String attrName = null;
StringBuffer currentField;
LDAPAttributeSet attrSet = new LDAPAttributeSet(); if ( !isRequest() ) { // 跳过 dn 字段
fieldIndex = 1;
}
else { // 跳过dn,control和changetype字段
fieldIndex = 2;
} for (i=fieldIndex; i<this.fNumber; i++) {
currentField = (StringBuffer)this.rFields.get(i);
// ':' 分离属性名称和属性值
index = IndexOf(currentField, ':');
if (index == -1) { // ':' not found
throw new LDAPLocalException("com.novell.ldap.ldif_dsml."
+ "LDIFReader: missing ':' after attribute name in record "
+ "starting on line " + this.dnlNumber +" of the file.",
LDAPException.LOCAL_ERROR);
} // 获取属性名称
attrName = currentField.substring(0,index);
// 如果属性名称不存在,则添加
if ( attrSet.getAttribute(attrName) == null ) {
// add it to attrSet with no value
attrSet.add(new LDAPAttribute(attrName));
} if(currentField.length() > index+1){
// 将属性值添加到属性中
if (currentField.charAt(index+1)==':') {
// base64编码的属性值
attrSet.getAttribute(attrName).addBase64Value(currentField. substring(index+2));
} else if (currentField.charAt(index+1)=='<'){
// 文件URL属性值
attrSet.getAttribute(attrName).addBase64Value(currentField. substring(index+2));
} else {
// 字符串值
String vals=currentField.substring(index+1).trim();
attrSet.getAttribute(attrName).addValue(vals);
// attrSet.getAttribute(attrName).addValue(currentField.
// substring(index+1));
}
} else if(currentField.length() == index+1){
String vals=new String("");
attrSet.getAttribute(attrName).addValue(vals);
} }
// 构造currentEntry
this.currentEntry = new LDAPEntry(this.entryDN, attrSet);
return;
} /**
* 构建包含moddn信息的String数组对象。
*/
private void toModInfo() throws LDAPLocalException { int index = 6; // length of "newrdn"
int fieldIndex = 2; // reference newrdn field
this.modInfo = new String[3];
StringBuffer currentField = (StringBuffer)this.rFields.get(fieldIndex); if( ! currentField.substring(0, index+1).equalsIgnoreCase("newrdn:")) {
throw new LDAPLocalException("com.novell.ldap.ldif_dsml.LDIFReader:"
+ " malformed newrdn field in record starting on line "
+ this.dnlNumber + " of the file.", LDAPException.LOCAL_ERROR);
} // get newrdn
if ( currentField.charAt(index+1) != ':') {
// common string value
this.modInfo[0] = currentField.substring(index+1);
}
else {
// decode newrdn
this.bytes = Base64.decode( currentField, index+2,
currentField.length());
try {
this.modInfo[0] = new String(this.bytes, "UTF-8");
} catch( UnsupportedEncodingException ue) {
throw new RuntimeException(
"UTF-8 String encoding not supported by JVM");
}
} fieldIndex++; // reference deleteOleRDN field
index = 13; // length of "deleteoldrdn"
currentField = (StringBuffer)this.rFields.get(fieldIndex); if( ! currentField.substring(0, index).equalsIgnoreCase(
"deleteoldrdn:") ) {
throw new LDAPLocalException("com.novell.ldap.ldif_dsml.LDIFReader:"
+ " malformed deleteoldrdn field in record starting on line "
+ this.dnlNumber + " of the file.", LDAPException.LOCAL_ERROR);
} char c = currentField.charAt(index);
if (c == '1') {
this.modInfo[1] = new String("1");
}
else if (c == '0'){
this.modInfo[1] = new String("0");
}
else {
throw new LDAPLocalException("com.novell.ldap.ldif_dsml.LDIFReader:"
+ " value for deleteoldrdn field should '0' or '1', found '" + c
+ "' in the record starting on line " + this.dnlNumber
+ " of the file.", LDAPException.LOCAL_ERROR);
} fieldIndex++; // reference newsuperior field if (fieldIndex == this.fNumber) { // no newsuperior spefified
this.modInfo[2] = new String("");
}
else { // there is a newsuperior
currentField = (StringBuffer)this.rFields.get(fieldIndex);
index = 12; // length of "newsuperior:"
if( ! currentField.substring(0, index).equalsIgnoreCase(
"newsuperior:")) {
throw new LDAPLocalException("com.novell.ldap.ldif_dsml."
+ "LDIFReader: malformed newsuperior field in the record "
+ "starting on line " + this.dnlNumber + " of the file.",
LDAPException.LOCAL_ERROR);
} if ( currentField.charAt(index) != ':') {
// commom string value
this.modInfo[2] = currentField.substring(index);
}
else {
// base64 encoded value
this.bytes = Base64.decode( currentField, index+1,
currentField.length());
this.modInfo[2] = new String(this.bytes);;
}
}
return;
} /**
* 基于LDIF修改记录的内容构建LDAPModification数组。
*/
private void toLDAPModifications()throws LDAPLocalException{ int i, index;
int fieldIndex = 2; // 跳过 dn, control, and changetype 字段
String attrName, opName;
LDAPAttribute attr = null;
ArrayList modList = new ArrayList(); if (!(this.rFields.get(this.fNumber-1)).toString().
equalsIgnoreCase("-") ) {
throw new LDAPLocalException("com.novell.ldap.ldif_dsml."
+ "LDIFReader: modify record not ends with '-' in the record"
+ " starting on line " + this.dnlNumber + " of the file.",
LDAPException.LOCAL_ERROR);
} // 填充LDAPModification数组对象
for (i=fieldIndex; i<this.fNumber; i++) {
// 找到":"分开mod操作和attr名称
index = IndexOf((StringBuffer)this.rFields.get(i), ':');
if (index == -1) { // ':' not found
throw new LDAPLocalException("com.novell.ldap.ldif_dsml."
+ "LDIFReader: malformed opName:attrName field in the record"
+ " starting on line " + this.dnlNumber + " of the file.",
LDAPException.LOCAL_ERROR);
} StringBuffer nextField = (StringBuffer)this.rFields.get(i);
opName= nextField.substring(0, index);
attrName= nextField.substring(index+1); i++; // 指向attrName:attrValue字段
nextField = (StringBuffer)this.rFields.get(i); // 构建每个LDAPModification对象并将其添加到modList
if (nextField.charAt(0)!='-') {
// 至少有一个 属性名称:属性值 字段
for ( ; nextField.charAt(0)!='-';
i++, nextField = (StringBuffer)this.rFields.get(i)) {
// 下标分离属性名称和属性值
if ((index=IndexOf(nextField, ':')) == -1) {
throw new LDAPLocalException("com.novell.ldap."
+ "ldif_dsml.LDIFReader : no ':' found in attrName:"
+ "attrValue field in the record starting on line "
+ this.dnlNumber + " of the file.",
LDAPException.LOCAL_ERROR);
}
else {
// 比较opName:attrName和 attrName:attrValue字段
String aName = nextField.substring(0, index);
if (!aName.equalsIgnoreCase(attrName)) {
throw new LDAPLocalException("com.novell.ldap."
+ "ldif_dsml.LDIFReader : found attribute name '"
+ aName + "', should be '" + attrName
+ "' in attrName:attrValue field in the record "
+ "starting on line " + this.dnlNumber
+ " of the file.", LDAPException.LOCAL_ERROR);
} // create attr and add value to it
attr = new LDAPAttribute(attrName);
if (nextField.charAt(index+1)==':') {
// base64 encoded attribute value
attr.addBase64Value(nextField.substring(index+2));
}
else if (nextField.charAt(index+1)=='<'){
// file URL attribute value
attr.addBase64Value(nextField.substring(index+2));
}
else {
// string value
attr.addValue(nextField.substring(index+1));
} if ( opName.equalsIgnoreCase("add") ) {
modList.add( new LDAPModification(
LDAPModification.ADD, attr));
}
else if ( opName.equalsIgnoreCase("delete") ) {
modList.add( new LDAPModification(
LDAPModification.DELETE, attr));
}
else if ( opName.equalsIgnoreCase("replace") ) {
modList.add( new LDAPModification(
LDAPModification.REPLACE, attr));
}
else {
throw new LDAPLocalException("com.novell.ldap."
+ "ldif_dsml.LDIFReader : Not supported modify "
+ " request (" + opName + ") specified in "
+ "record starting on line " + this.dnlNumber
+ " of the file.", LDAPException.LOCAL_ERROR);
}
}
}
} else {
// there is no attribute value specified; this could be
// true for 'delete' and 'replace' modify operation
attr = new LDAPAttribute(attrName); if ( opName.equalsIgnoreCase("delete") ) {
modList.add( new LDAPModification(
LDAPModification.DELETE, attr));
}
else if ( opName.equalsIgnoreCase("replace") ) {
modList.add( new LDAPModification(
LDAPModification.REPLACE, attr));
}
else {
throw new LDAPLocalException("com.novell.ldap.ldif_dsml."
+ "LDIFReader: For '" + opName + "', no value "
+ "specified for atribute '" + attrName
+ "' in the record starting on line "
+ this.dnlNumber + " of the file.",
LDAPException.LOCAL_ERROR);
}
}
}
this.mods = new LDAPModification[modList.size()];
this.mods = (LDAPModification[])modList.toArray(this.mods);
return;
} /**
* 返回指定字符首次出现的StringBuffer对象内的索引。
*
* @param bl The StringBuffer object
* @param ch The character to look for in the StringBuffer object
*
* @return The index of the first occurence of the character in the
* StringBuffer object, or -1 if the character does not occur.
*/
private int IndexOf(StringBuffer bl, int ch)
{ if (bl != null ) {
for (int i=0;i<bl.length(); i++) {
if(bl.charAt(i) == ch) {
return i;
}
}
}
return -1;
} /**
* <tt>去空字段<tt> 修剪一个字段中的多余空格。
*/
private StringBuffer trimField( StringBuffer line)
throws LDAPLocalException
{
int c, lastChar = 0, charIndex = 0;
char t;
char[] newChars;
boolean isEncoded=false, isURL=false, criticality = false;
String oid = null; if ((line == null)||((c=IndexOf(line,':'))==-1)) {
// not all fields contain ':'
return line;
} // elminate any trailing spaces
lastChar = line.length() - 1;
while( line.charAt(lastChar) == ' ') {
lastChar--;
} // create newChars
newChars = new char[lastChar+1]; if( (c > 6) && (line.substring(0,c).equals("control"))) {
// this is a control field
this.control = true;
c++; // skip past ':'
// eliminate any spaces after ':'
while( (c <= lastChar) && (line.charAt(c) == ' ')) {
c++;
}
}
else {
// not a control field. it's 'dn',
//'changetype', or 'attrName' field
this.control = false; // copy field name and ':', eg. 'dn:', 'changetype:', or 'attrName:'
line.getChars(0, c+1, newChars, 0);
// skip over copied chars
charIndex += c + 1;
// c points to char right after first ':'
c++;
} if(!this.control) {
// // not a control field. check if '::' or ':<'
if( c <= lastChar) {
t = line.charAt(c);
if( t == ':') {
newChars[charIndex++] = ':'; // save the ':' to
c++; // point to value
}
else if( t == '<') {
newChars[charIndex++] = '<'; // save the '<' to
c++; // point to value
}
} // for case like attr: <value>
boolean nonfile=false;
String fredir= line.substring(c);
if(fredir.length()>0 && fredir.charAt(0) != '<'){
String cstr=fredir.trim();
if(cstr.length()>0 && cstr.charAt(0) == '<'){
nonfile=true;
}
} // eliminate any space(s) after ':' or '<'
while( (c <= lastChar) && (line.charAt(c) == ' ')) {
c++;
} // for case like attr: <value>
if(nonfile==true){
c--;
} if( c <= lastChar) { // thers is a value specified
// copy field value
line.getChars(c, lastChar+1, newChars, charIndex); charIndex += lastChar - c + 1;
// create a new StringBuffer object with capacity of lastChar
StringBuffer newBuf = new StringBuffer(lastChar);
// copy the filed represented by newChars
newBuf.append( newChars, 0, charIndex);
// return the trimed field
return newBuf;
}
else if ( line.length() == c){
StringBuffer newBuf= new StringBuffer();
line.getChars(c, lastChar+1, newChars, charIndex);
charIndex += lastChar - c + 1;
newBuf.append( newChars, 0, charIndex);
return newBuf;
} else { // there is no value specified
throw new LDAPLocalException("com.novell.ldap.ldif_dsml."
+ "LDIFReader: a field contains no value after ':'. the "
+ "field is in the record starting on line "
+ this.dnlNumber + " of the file.",
LDAPException.LOCAL_ERROR);
}
}
else { // a control field
// process values for control. a control field may looks like
// 1. control: 1.2.3.4 true: control value
// 2. control: 1.2.3.4: control value
// 3. control: 1.2.3.4
// extra spaces are possible between oid, criticality, and value.
// oid is a must, while criticalitty and value can be absent. // get control oid
int b = c;
while(c <= lastChar) {
// an oid consists of dots and digits
t = line.charAt(c);
if( (t == '.') || (Character.isDigit(t))) {
c++;
continue;
}
break;
} if( b == c) { // control with no oid
throw new LDAPLocalException("com.novell.ldap.ldif_dsml."
+ "LDIFReader: Control with no oid in the record "
+ "starting on line " + this.dnlNumber
+ " of the file.", LDAPException.LOCAL_ERROR);
}
else { // control has iod, get local copy of oid
char[] chars = new char[c-b];
line.getChars(b, c, chars, 0);
oid = new String(chars);
} if ( c > lastChar) {
// control only has an oid. create LDAPControl object
// with oid, 'false' and empty byte array
LDAPControl ctrl = new LDAPControl(oid, false, new byte[0]);
// add it to cList
this.cList.add(ctrl);
return null; // return value has no use
} // get control criticality
t = line.charAt(c);
if( t == ' ') {
// see a space, skip over any spaces
while( (c <= lastChar) && (line.charAt(c) == ' ')) {
c++;
}
}
// what we see now? 'true', 'false', or ':' ?
if(((c + 3) <= lastChar)&&(line.substring(c,c+4).equals("true"))) {
// found 'true'
c += 4;
criticality = true;
}
else if(((c+4)<=lastChar)&&(line.substring(c,c+5).equals("false"))){
// found 'false'
c += 5;
criticality = false;
} if (c > lastChar) { // to the end of the control field
// create LDAPControl object with oid,
// criticality, and empty byte array
LDAPControl ctrl=new LDAPControl(oid, criticality, new byte[0]);
// add it to cList
this.cList.add(ctrl);
return null;
} if ((t=line.charAt(c)) != ':') {
throw new LDAPLocalException("com.novell.ldap.ldif_dsml."
+ "LDIFReader: Unexcepted char '" + t + "'. Expecting "
+ "to see ':' in the record starting on line "
+ this.dnlNumber + " of the file.",
LDAPException.LOCAL_ERROR);
} // get control value
c++; // go to enst char after ':'
if (c > lastChar) {
throw new LDAPLocalException("com.novell.ldap.ldif_dsml."
+ "LDIFReader: No control value after ':' "
+ "in the record starting on line "
+ this.dnlNumber + " of the file.",
LDAPException.LOCAL_ERROR);
} // positioned at the first char right after ':'
// check if '::' or ':<'
t = line.charAt(c);
if( t == ':') {
isEncoded = true; // indicate encoded value
c++; // point to value
if (c > lastChar) {
throw new LDAPLocalException("com.novell.ldap.ldif_dsml."
+ "LDIFReader: No control value after '::' "
+ "in the record starting on line "
+ this.dnlNumber + " of the file.",
LDAPException.LOCAL_ERROR);
}
}
else if( t == '<') {
isURL = true; // indicate file URL value
c++; // point to value
if (c > lastChar) {
throw new LDAPLocalException("com.novell.ldap.ldif_dsml."
+ "LDIFReader: No control value after ':<' "
+ "in the record starting on line "
+ this.dnlNumber + " of the file.",
LDAPException.LOCAL_ERROR);
}
} // eliminate any space(s) after ':', '::' or ':<'
while((c <= lastChar) && (line.charAt(c) == ' ')) {
c++;
} if(c <= lastChar) { // thers is a value spec specified
char[] chars = new char[lastChar+1-c];
line.getChars(c, lastChar+1, chars, 0); if (isEncoded) {
this.bytes = Base64.decode(chars);
}
else if (isURL) {
// if isURL, what to do?
this.bytes = (new String(chars)).getBytes();
}
else {
this.bytes = (new String(chars)).getBytes();
}
}
// create LDAPControl object
LDAPControl ctrl = new LDAPControl(oid, criticality, this.bytes);
// add it to cList
this.cList.add(ctrl);
}
return null;
}
}

这样的好处是不用在ldif文件中添加 “version:1”  “changetype:add”

dn:: Yz3kuK3ljY7kurrmsJHlhbHlkozlm70=
objectClass: top
objectClass: country
c:: 5Lit5Y2O5Lq65rCR5YWx5ZKM5Zu9 dn:: bz3lm5vlt50sIGM95Lit5Y2O5Lq65rCR5YWx5ZKM5Zu9
objectClass: top
objectClass: organization
o:: 5Zub5bed dn:: bz3miJDpg70sbz3lm5vlt50sIGM95Lit5Y2O5Lq65rCR5YWx5ZKM5Zu9
objectClass: top
objectClass: organization
o:: 5oiQ6YO9

运行后,刷新根节点

java读取ldif文件并创建新的节点的更多相关文章

  1. java导入ldif文件

    网上导入ldif文件的方式都是基于命令,或者相应工具如LDAP Browser \Editor v2.8.2. 但用java去实现这样的功能好像网上很少,于是我参照相应的开源代码并整理了一下,亲自测试 ...

  2. java分享第十六天( java读取properties文件的几种方法&java配置文件持久化:static块的作用)

     java读取properties文件的几种方法一.项目中经常会需要读取配置文件(properties文件),因此读取方法总结如下: 1.通过java.util.Properties读取Propert ...

  3. JAVA读取XML文件并解析获取元素、属性值、子元素信息

    JAVA读取XML文件并解析获取元素.属性值.子元素信息 关键字 XML读取  InputStream   DocumentBuilderFactory   Element     Node 前言 最 ...

  4. java读取properties文件总结

    一.java读取properties文件总结 在java项目中,操作properties文件是经常要做的,因为很多的配置信息都会写在properties文件中,这里主要是总结使用getResource ...

  5. Java 读取txt文件生成Word文档

    本文将以Java程序代码为例介绍如何读取txt文件中的内容,生成Word文档.在编辑代码前,可参考如下代码环境进行配置: IntelliJ IDEA Free Spire.Doc for Java T ...

  6. Azure ARM (13) 从现有VHD文件,创建新的ARM VM

    <Windows Azure Platform 系列文章目录> 本文参考了Git Hub的ARM Template: https://github.com/Azure/azure-quic ...

  7. Java读取Excel文件的几种方法

    Java读取 Excel 文件的常用开源免费方法有以下几种: 1. JDBC-ODBC Excel Driver 2. jxl.jar 3. jcom.jar 4. poi.jar 简单介绍: 百度文 ...

  8. Java读取txt文件

    package com.loongtao.general.crawler.slave.utils; import java.io.BufferedReader; import java.io.File ...

  9. java 读取XML文件作为配置文件

    首先,贴上自己的实例: XML文件:NewFile.xml(该文件与src目录同级) <?xml version="1.0" encoding="UTF-8&quo ...

随机推荐

  1. Spring Boot 为什么这么火?(二)

    Spring Boot 的火 网上连载了 Spring Boot 系列文章,没想到这一开始便与 Spring Boot 深度结缘. 技术社区 Spring Boot 的文章越来越多:Spring Bo ...

  2. js Functor Copy

    原文地址:https://segmentfault.com/a/1190000006051586?utm_source=tuicool&utm_medium=referral 本处仅仅个人存档 ...

  3. 【烦人的字符集】linux字符集问题,中文乱码

    [1]快速修改命令 [2]locale 查看现在服务器的字符 [root@Master ~]# localeLANG=en_US.UTF-8LC_CTYPE="zh_CN.UTF-8&quo ...

  4. C++中的const分析

    1,C 语言中的 const: 1,const 修饰的变量是只读的,本质还是变量: 1,C 语言中的 const 使变量具有只读属性: 2,const 只在编译期有用,在运行期无用: 3,const ...

  5. Linux 環境下安裝swoole

    一.先安装依赖 yum -y install gcc gcc-c++ autoconf automake yum -y install zlib zlib-devel openssl openssl- ...

  6. ps的一点快捷键

    选区工具快捷键(shift alt很重要) 按M键切换到选区工具 矩形选区-> shift 正方形 shift+m 矩形/椭圆来回切换 参考线:alt+v 选中上方的工具 alt+v+e 新建参 ...

  7. mesg - 调节用户终端的写访问权

    总览 (SYNOPSIS) mesg [y|n] 描述 (DESCRIPTION) Mesg 控制 其他用户 对 你的终端 的 访问能力. 典型用途 是 允许 或 禁止 其他用户向 你的终端 输出 数 ...

  8. Codeforces Round #426 (Div. 2) - C

    题目链接:http://codeforces.com/contest/834/problem/C 题意:两个在玩一个游戏,对于每一轮,选定一个自然是k,初始两人的分数都为1,每一个回合赢的人在他当前分 ...

  9. 磁盘IO性能优化-实践

    RAID卡缓存策略调整 原因详解 操作实例 I/O 调度算法 文件系统journal 磁盘挂载参数 操作实例 性能数据对比 RAID卡缓存策略调整 可以将RAID卡缓存策略由No Write Cach ...

  10. The Preliminary Contest for ICPC Asia Xuzhou 2019 E. XKC's basketball team (线段树)

    题目链接:https://nanti.jisuanke.com/t/41387 题目大意:对于给定序列,求出对于每个位置求出比该数大于m的最靠右的位置. 思路:首先对序列进行离散化,然后对于每个数的下 ...