zoukankan      html  css  js  c++  java
  • java读取ldif文件并创建新的节点

       所需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 BrowserEditor 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

    运行后,刷新根节点

  • 相关阅读:
    IOS开发---菜鸟学习之路--(二十四)-iOS7View被导航栏遮挡问题的解决
    IOS开发---菜鸟学习之路--(二十三)-直接利用键值对的方式来处理数据的感想
    IOS开发---菜鸟学习之路--(二十二)-近期感想以及我的IOS学习之路
    一口一口吃掉Hexo(六)
    一口一口吃掉Hexo(二)
    setSupportActionBar(toolbar)导致程序崩溃闪退
    【原创+译文】官方文档中声明的如何创建抽屉导航栏(Navigation Drawer)
    【文章内容来自《Android 应用程序开发权威指南》(第四版)】如何设计兼容的用户界面的一些建议(有删改)
    如何为按钮设置一组不同状态的颜色
    如何避免Activity 被杀死
  • 原文地址:https://www.cnblogs.com/dqcer/p/7660524.html
Copyright © 2011-2022 走看看