You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by fe...@apache.org on 2007/11/21 21:08:33 UTC

svn commit: r597198 [3/3] - in /directory/sandbox/felixk: ./ studio-ldif-parser/ studio-ldif-parser/META-INF/ studio-ldif-parser/src/ studio-ldif-parser/src/main/ studio-ldif-parser/src/main/java/ studio-ldif-parser/src/main/java/org/ studio-ldif-parse...

Added: directory/sandbox/felixk/studio-ldif-parser/src/main/java/org/apache/directory/studio/ldifparser/parser/LdifParser.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-ldif-parser/src/main/java/org/apache/directory/studio/ldifparser/parser/LdifParser.java?rev=597198&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-ldif-parser/src/main/java/org/apache/directory/studio/ldifparser/parser/LdifParser.java (added)
+++ directory/sandbox/felixk/studio-ldif-parser/src/main/java/org/apache/directory/studio/ldifparser/parser/LdifParser.java Wed Nov 21 12:08:28 2007
@@ -0,0 +1,1073 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+
+package org.apache.directory.studio.ldifparser.parser;
+
+
+import java.io.Reader;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.directory.studio.ldifparser.model.LdifEOFPart;
+import org.apache.directory.studio.ldifparser.model.LdifEnumeration;
+import org.apache.directory.studio.ldifparser.model.LdifFile;
+import org.apache.directory.studio.ldifparser.model.LdifInvalidPart;
+import org.apache.directory.studio.ldifparser.model.container.LdifChangeAddRecord;
+import org.apache.directory.studio.ldifparser.model.container.LdifChangeDeleteRecord;
+import org.apache.directory.studio.ldifparser.model.container.LdifChangeModDnRecord;
+import org.apache.directory.studio.ldifparser.model.container.LdifChangeModifyRecord;
+import org.apache.directory.studio.ldifparser.model.container.LdifChangeRecord;
+import org.apache.directory.studio.ldifparser.model.container.LdifCommentContainer;
+import org.apache.directory.studio.ldifparser.model.container.LdifContainer;
+import org.apache.directory.studio.ldifparser.model.container.LdifContentRecord;
+import org.apache.directory.studio.ldifparser.model.container.LdifEOFContainer;
+import org.apache.directory.studio.ldifparser.model.container.LdifInvalidContainer;
+import org.apache.directory.studio.ldifparser.model.container.LdifModSpec;
+import org.apache.directory.studio.ldifparser.model.container.LdifRecord;
+import org.apache.directory.studio.ldifparser.model.container.LdifSepContainer;
+import org.apache.directory.studio.ldifparser.model.container.LdifVersionContainer;
+import org.apache.directory.studio.ldifparser.model.lines.LdifAttrValLine;
+import org.apache.directory.studio.ldifparser.model.lines.LdifChangeTypeLine;
+import org.apache.directory.studio.ldifparser.model.lines.LdifCommentLine;
+import org.apache.directory.studio.ldifparser.model.lines.LdifControlLine;
+import org.apache.directory.studio.ldifparser.model.lines.LdifDeloldrdnLine;
+import org.apache.directory.studio.ldifparser.model.lines.LdifDnLine;
+import org.apache.directory.studio.ldifparser.model.lines.LdifModSpecSepLine;
+import org.apache.directory.studio.ldifparser.model.lines.LdifModSpecTypeLine;
+import org.apache.directory.studio.ldifparser.model.lines.LdifNewrdnLine;
+import org.apache.directory.studio.ldifparser.model.lines.LdifNewsuperiorLine;
+import org.apache.directory.studio.ldifparser.model.lines.LdifSepLine;
+import org.apache.directory.studio.ldifparser.model.lines.LdifVersionLine;
+
+
+public class LdifParser
+{
+
+    private LdifScanner scanner;
+
+
+    public LdifParser()
+    {
+        this.scanner = new LdifScanner();
+    }
+
+
+    public LdifFile parse( String ldif )
+    {
+        LdifFile model = new LdifFile();
+        LdifEnumeration enumeration = this.parse( new StringReader( ldif ) );
+        try
+        {
+            while ( enumeration.hasNext() )
+            {
+                LdifContainer container = enumeration.next();
+                model.addContainer( container );
+            }
+        }
+        catch ( Exception e )
+        {
+        }
+        return model;
+    }
+
+
+    public LdifEnumeration parse( Reader ldifReader )
+    {
+
+        this.scanner.setLdif( ldifReader );
+
+        LdifEnumeration enumeration = new LdifEnumeration()
+        {
+
+            private List containerList = new ArrayList();
+
+            private boolean headerParsed = false;
+
+            private boolean bodyParsed = false;
+
+            private boolean footerParsed = false;
+
+
+            public boolean hasNext()
+            {
+                if ( containerList.isEmpty() )
+                {
+
+                    LdifFile model = new LdifFile();
+
+                    // parse header
+                    if ( !headerParsed )
+                    {
+                        checkAndParseComment( model );
+                        checkAndParseVersion( model );
+                        checkAndParseComment( model );
+                        headerParsed = true;
+                    }
+
+                    // parse body (in a loop)
+                    if ( headerParsed && !bodyParsed )
+                    {
+                        // parse comment lines
+                        if ( !checkAndParseComment( model ) )
+                        {
+                            // parse record
+                            if ( !checkAndParseRecord( model ) )
+                            {
+                                // parse unknown
+                                if ( !checkAndParseOther( model ) )
+                                {
+                                    // end of body
+                                    bodyParsed = true;
+                                }
+                            }
+                        }
+                    }
+
+                    // parse footer
+                    if ( headerParsed && bodyParsed && !footerParsed )
+                    {
+                        checkAndParseComment( model );
+                        footerParsed = true;
+                    }
+
+                    LdifContainer[] containers = model.getContainers();
+                    this.containerList.addAll( Arrays.asList( containers ) );
+                    return !containerList.isEmpty() && !( containers[0] instanceof LdifEOFContainer );
+
+                }
+                else
+                {
+                    return true;
+                }
+            }
+
+
+            public LdifContainer next()
+            {
+                if ( hasNext() )
+                {
+                    return ( LdifContainer ) this.containerList.remove( 0 );
+                }
+                else
+                {
+                    return null;
+                }
+            }
+        };
+
+        return enumeration;
+    }
+
+
+    // public LdifEnumeration parse(Reader ldifReader) {
+    //		
+    // this.scanner.setLdif(ldifReader);
+    //		
+    // LdifEnumeration enumeration = new LdifEnumeration(){
+    //
+    // private List containerList = new ArrayList();
+    //			
+    // public boolean
+    // hasNext(org.apache.directory.studio.ldapbrowser.core.jobs.ExtendedProgressMonitor
+    // monitor) {
+    // if(containerList.isEmpty()) {
+    // LdifFile model = parseFile();
+    // LdifContainer[] containers = model.getContainers();
+    // this.containerList.addAll(Arrays.asList(containers));
+    // return !containerList.isEmpty() && !(containers[0] instanceof
+    // LdifEOFContainer);
+    // }
+    // else {
+    // return true;
+    // }
+    // }
+    //
+    // public LdifContainer
+    // next(org.apache.directory.studio.ldapbrowser.core.jobs.ExtendedProgressMonitor
+    // monitor) {
+    // if(hasNext(monitor)) {
+    // return (LdifContainer)this.containerList.remove(0);
+    // }
+    // else {
+    // return null;
+    // }
+    // }
+    // };
+    //		
+    // return enumeration;
+    // }
+    //
+    // private LdifFile parseFile() {
+    //
+    // LdifFile model = new LdifFile();
+    //		
+    // // start comment-version-comment
+    // checkAndParseComment(model);
+    // checkAndParseVersion(model);
+    // checkAndParseComment(model);
+    //		
+    // parseRecords(model);
+    //		
+    // checkAndParseComment(model);
+    //		
+    // return model;
+    // }
+    //
+    // private void parseRecords(LdifFile model) {
+    // do {
+    // // parse comment lines
+    // if(!checkAndParseComment(model)) {
+    // // parse record
+    // if(!checkAndParseRecord(model)) {
+    // // parse unknown
+    // if(!checkAndParseOther(model)) {
+    // return;
+    // }
+    // }
+    // }
+    // }
+    // while(true);
+    //		
+    // }
+
+    /**
+     * Checks for version line. If version line is present it is parsed and
+     * added to the given model.
+     * 
+     * @param model
+     *                the model
+     * @return true if version line was added to the model, false otherwise
+     */
+    private boolean checkAndParseRecord( LdifFile model )
+    {
+
+        // record starts with dn-spec
+        LdifToken dnSpecToken = this.scanner.matchDnSpec();
+        if ( dnSpecToken == null )
+        {
+            return false;
+        }
+
+        // get DN
+        LdifToken dnValueTypeToken = null;
+        LdifToken dnToken = null;
+        LdifToken dnSepToken = null;
+        dnValueTypeToken = this.scanner.matchValueType();
+        if ( dnValueTypeToken != null )
+        {
+            dnToken = this.scanner.matchValue();
+            if ( dnToken != null )
+            {
+                dnSepToken = this.scanner.matchSep();
+            }
+        }
+        LdifDnLine dnLine = new LdifDnLine( dnSpecToken.getOffset(), getValueOrNull( dnSpecToken ),
+            getValueOrNull( dnValueTypeToken ), getValueOrNull( dnToken ), getValueOrNull( dnSepToken ) );
+        LdifToken dnErrorToken = null;
+        if ( dnSepToken == null )
+        {
+            dnErrorToken = this.scanner.matchCleanupLine();
+        }
+
+        // save comment lines after dns
+        LdifCommentLine[] commentLines = getCommentLines();
+
+        // check record type: to decide the record type we need the next token
+        // first check keywords 'control' and 'changetype'
+        LdifControlLine controlLine = getControlLine();
+        LdifChangeTypeLine changeTypeLine = getChangeTypeLine();
+        if ( controlLine != null || changeTypeLine != null )
+        {
+
+            LdifChangeRecord record = null;
+
+            // save all parts before changetype line
+            List partList = new ArrayList();
+            if ( dnErrorToken != null )
+            {
+                partList.add( new LdifInvalidPart( dnErrorToken.getOffset(), dnErrorToken.getValue() ) );
+            }
+            for ( int i = 0; i < commentLines.length; i++ )
+            {
+                partList.add( commentLines[i] );
+            }
+            if ( controlLine != null )
+            {
+                partList.add( controlLine );
+                if ( !controlLine.isValid() )
+                {
+                    LdifToken errorToken = this.cleanupLine();
+                    if ( errorToken != null )
+                    {
+                        partList.add( new LdifInvalidPart( errorToken.getOffset(), errorToken.getValue() ) );
+                    }
+                }
+            }
+
+            // save comments and controls before changetype line
+            while ( changeTypeLine == null && ( commentLines.length > 0 || controlLine != null ) )
+            {
+
+                commentLines = getCommentLines();
+                for ( int i = 0; i < commentLines.length; i++ )
+                {
+                    partList.add( commentLines[i] );
+                }
+
+                controlLine = getControlLine();
+                if ( controlLine != null )
+                {
+                    partList.add( controlLine );
+                    if ( !controlLine.isValid() )
+                    {
+                        LdifToken errorToken = this.cleanupLine();
+                        if ( errorToken != null )
+                        {
+                            partList.add( new LdifInvalidPart( errorToken.getOffset(), errorToken.getValue() ) );
+                        }
+                    }
+                }
+
+                changeTypeLine = getChangeTypeLine();
+            }
+
+            if ( changeTypeLine != null )
+            {
+
+                if ( changeTypeLine.isAdd() )
+                {
+                    record = new LdifChangeAddRecord( dnLine );
+                    append( record, partList );
+                    record.setChangeType( changeTypeLine );
+                    if ( !changeTypeLine.isValid() )
+                    {
+                        this.cleanupLine( record );
+                    }
+                    parseAttrValRecord( record );
+                }
+                else if ( changeTypeLine.isDelete() )
+                {
+                    record = new LdifChangeDeleteRecord( dnLine );
+                    append( record, partList );
+                    record.setChangeType( changeTypeLine );
+                    if ( !changeTypeLine.isValid() )
+                    {
+                        this.cleanupLine( record );
+                    }
+                    parseChangeDeleteRecord( record );
+                }
+                else if ( changeTypeLine.isModify() )
+                {
+                    record = new LdifChangeModifyRecord( dnLine );
+                    append( record, partList );
+                    record.setChangeType( changeTypeLine );
+                    if ( !changeTypeLine.isValid() )
+                    {
+                        this.cleanupLine( record );
+                    }
+                    parseChangeModifyRecord( ( LdifChangeModifyRecord ) record );
+                }
+                else if ( changeTypeLine.isModDn() )
+                {
+                    record = new LdifChangeModDnRecord( dnLine );
+                    append( record, partList );
+                    record.setChangeType( changeTypeLine );
+                    if ( !changeTypeLine.isValid() )
+                    {
+                        this.cleanupLine( record );
+                    }
+                    parseChangeModDnRecord( ( LdifChangeModDnRecord ) record );
+                }
+                else
+                {
+                    record = new LdifChangeRecord( dnLine );
+                    append( record, partList );
+                    record.setChangeType( changeTypeLine );
+                    if ( !changeTypeLine.isValid() )
+                    {
+                        this.cleanupLine( record );
+                    }
+                }
+            }
+            else
+            {
+                record = new LdifChangeRecord( dnLine );
+                append( record, partList );
+            }
+
+            model.addContainer( record );
+        }
+        else
+        {
+            // match attr-val-record
+            LdifContentRecord record = new LdifContentRecord( dnLine );
+            if ( dnErrorToken != null )
+            {
+                record.addInvalid( new LdifInvalidPart( dnErrorToken.getOffset(), dnErrorToken.getValue() ) );
+            }
+            for ( int i = 0; i < commentLines.length; i++ )
+            {
+                record.addComment( commentLines[i] );
+            }
+            parseAttrValRecord( record );
+            model.addContainer( record );
+        }
+
+        return true;
+    }
+
+
+    private void append( LdifChangeRecord record, List partList )
+    {
+        for ( Iterator it = partList.iterator(); it.hasNext(); )
+        {
+            Object o = it.next();
+            if ( o instanceof LdifCommentLine )
+                record.addComment( ( LdifCommentLine ) o );
+            if ( o instanceof LdifControlLine )
+                record.addControl( ( LdifControlLine ) o );
+            if ( o instanceof LdifInvalidPart )
+                record.addInvalid( ( LdifInvalidPart ) o );
+        }
+    }
+
+
+    private void parseChangeDeleteRecord( LdifRecord record )
+    {
+        do
+        {
+            if ( checkAndParseEndOfRecord( record ) )
+            {
+                return;
+            }
+
+            if ( !checkAndParseComment( record ) && !checkAndParseOther( record ) )
+            {
+                return;
+            }
+        }
+        while ( true );
+    }
+
+
+    private void parseChangeModDnRecord( LdifChangeModDnRecord record )
+    {
+        // do {
+        if ( checkAndParseEndOfRecord( record ) )
+        {
+            return;
+        }
+
+        // comments
+        checkAndParseComment( record );
+
+        // read newrdn line
+        LdifToken newrdnSpecToken = this.scanner.matchNewrdnSpec();
+        if ( newrdnSpecToken != null )
+        {
+            LdifToken newrdnValueTypeToken = this.scanner.matchValueType();
+            LdifToken newrdnValueToken = this.scanner.matchValue();
+            LdifToken newrdnSepToken = null;
+            if ( newrdnValueTypeToken != null || newrdnValueToken != null )
+            {
+                newrdnSepToken = this.scanner.matchSep();
+            }
+
+            LdifNewrdnLine newrdnLine = new LdifNewrdnLine( newrdnSpecToken.getOffset(),
+                getValueOrNull( newrdnSpecToken ), getValueOrNull( newrdnValueTypeToken ),
+                getValueOrNull( newrdnValueToken ), getValueOrNull( newrdnSepToken ) );
+            record.setNewrdn( newrdnLine );
+
+            if ( newrdnSepToken == null )
+            {
+                this.cleanupLine( record );
+            }
+        }
+
+        if ( newrdnSpecToken == null )
+        {
+            if ( !checkAndParseComment( record ) && !checkAndParseOther( record ) )
+            {
+                return;
+            }
+        }
+
+        // comments
+        checkAndParseComment( record );
+
+        // read deleteoldrdnline
+        LdifToken deleteoldrdnSpecToken = this.scanner.matchDeleteoldrdnSpec();
+        if ( deleteoldrdnSpecToken != null )
+        {
+            LdifToken deleteoldrdnValueTypeToken = this.scanner.matchValueType();
+            LdifToken deleteoldrdnValueToken = this.scanner.matchValue();
+            LdifToken deleteoldrdnSepToken = null;
+            if ( deleteoldrdnValueTypeToken != null || deleteoldrdnValueToken != null )
+            {
+                deleteoldrdnSepToken = this.scanner.matchSep();
+            }
+
+            LdifDeloldrdnLine deloldrdnLine = new LdifDeloldrdnLine( deleteoldrdnSpecToken.getOffset(),
+                getValueOrNull( deleteoldrdnSpecToken ), getValueOrNull( deleteoldrdnValueTypeToken ),
+                getValueOrNull( deleteoldrdnValueToken ), getValueOrNull( deleteoldrdnSepToken ) );
+            record.setDeloldrdn( deloldrdnLine );
+
+            if ( deleteoldrdnSepToken == null )
+            {
+                this.cleanupLine( record );
+            }
+        }
+
+        if ( deleteoldrdnSpecToken == null )
+        {
+            if ( !checkAndParseComment( record ) && !checkAndParseOther( record ) )
+            {
+                return;
+            }
+        }
+
+        // comments
+        checkAndParseComment( record );
+
+        // read newsuperior line
+        LdifToken newsuperiorSpecToken = this.scanner.matchNewsuperiorSpec();
+        if ( newsuperiorSpecToken != null )
+        {
+            LdifToken newsuperiorValueTypeToken = this.scanner.matchValueType();
+            LdifToken newsuperiorValueToken = this.scanner.matchValue();
+            LdifToken newsuperiorSepToken = null;
+            if ( newsuperiorValueTypeToken != null || newsuperiorValueToken != null )
+            {
+                newsuperiorSepToken = this.scanner.matchSep();
+            }
+
+            LdifNewsuperiorLine newsuperiorLine = new LdifNewsuperiorLine( newsuperiorSpecToken.getOffset(),
+                getValueOrNull( newsuperiorSpecToken ), getValueOrNull( newsuperiorValueTypeToken ),
+                getValueOrNull( newsuperiorValueToken ), getValueOrNull( newsuperiorSepToken ) );
+            record.setNewsuperior( newsuperiorLine );
+
+            if ( newsuperiorSepToken == null )
+            {
+                this.cleanupLine( record );
+            }
+        }
+
+        // comments
+        checkAndParseComment( record );
+
+        // eor
+        checkAndParseEndOfRecord( record );
+
+        // comments
+        // checkAndParseComment(record);
+
+        // }
+        // while(true);
+    }
+
+
+    private void parseChangeModifyRecord( LdifChangeModifyRecord record )
+    {
+
+        do
+        {
+            if ( checkAndParseEndOfRecord( record ) )
+            {
+                return;
+            }
+
+            // match mod type
+            LdifToken modSpecTypeSpecToken = this.scanner.matchModTypeSpec();
+            if ( modSpecTypeSpecToken != null )
+            {
+                // read mod type line
+                LdifToken modSpecTypeValueTypeToken = null;
+                LdifToken modSpecTypeAttributeDescriptionToken = null;
+                LdifToken sepToken = null;
+                modSpecTypeValueTypeToken = this.scanner.matchValueType();
+                if ( modSpecTypeValueTypeToken != null )
+                {
+                    modSpecTypeAttributeDescriptionToken = this.scanner.matchAttributeDescription();
+                    if ( modSpecTypeAttributeDescriptionToken != null )
+                    {
+                        sepToken = this.scanner.matchSep();
+                    }
+                }
+                LdifModSpecTypeLine modSpecTypeLine = new LdifModSpecTypeLine( modSpecTypeSpecToken.getOffset(),
+                    getValueOrNull( modSpecTypeSpecToken ), getValueOrNull( modSpecTypeValueTypeToken ),
+                    getValueOrNull( modSpecTypeAttributeDescriptionToken ), getValueOrNull( sepToken ) );
+                LdifModSpec modSpec = new LdifModSpec( modSpecTypeLine );
+                record.addModSpec( modSpec );
+
+                // clean line
+                if ( sepToken == null )
+                {
+                    this.cleanupLine( modSpec );
+                }
+
+                // comment
+                checkAndParseComment( record );
+
+                // read attr-val lines
+                do
+                {
+                    LdifAttrValLine line = this.getAttrValLine();
+                    if ( line != null )
+                    {
+                        modSpec.addAttrVal( line );
+
+                        // clean line
+                        if ( "".equals( line.getRawNewLine() ) )
+                        {
+                            this.cleanupLine( record );
+                        }
+                    }
+                    else
+                    {
+                        if ( !checkAndParseComment( record ) )
+                        {
+                            break;
+                        }
+                    }
+                }
+                while ( true );
+
+                // comments
+                checkAndParseComment( record );
+
+                // read sep line
+                LdifToken modSpecSepToken = this.scanner.matchModSep();
+                if ( modSpecSepToken != null )
+                {
+                    LdifToken modSpecSepSepToken = this.scanner.matchSep();
+                    LdifModSpecSepLine modSpecSepLine = new LdifModSpecSepLine( modSpecSepToken.getOffset(),
+                        getValueOrNull( modSpecSepToken ), getValueOrNull( modSpecSepSepToken ) );
+                    modSpec.finish( modSpecSepLine );
+                }
+            }
+
+            if ( modSpecTypeSpecToken == null )
+            {
+                if ( !checkAndParseComment( record ) && !checkAndParseOther( record ) )
+                {
+                    return;
+                }
+            }
+        }
+        while ( true );
+    }
+
+
+    private void parseAttrValRecord( LdifRecord record )
+    {
+
+        do
+        {
+            if ( checkAndParseEndOfRecord( record ) )
+            {
+                return;
+            }
+
+            // check attr-val line
+            LdifAttrValLine line = this.getAttrValLine();
+            if ( line != null )
+            {
+                if ( record instanceof LdifContentRecord )
+                {
+                    ( ( LdifContentRecord ) record ).addAttrVal( line );
+                }
+                else if ( record instanceof LdifChangeAddRecord )
+                {
+                    ( ( LdifChangeAddRecord ) record ).addAttrVal( line );
+                }
+
+                // clean line
+                if ( "".equals( line.getRawNewLine() ) )
+                {
+                    this.cleanupLine( record );
+                }
+            }
+            else
+            {
+                if ( !checkAndParseComment( record ) && !checkAndParseOther( record ) )
+                {
+                    return;
+                }
+            }
+
+            //			
+            // // check comment line
+            // if(lineStartToken == null) {
+            // lineStartToken = this.scanner.matchComment();
+            // if(lineStartToken != null) {
+            // LdifToken sepToken = this.scanner.matchSep();
+            // record.addComment(new
+            // LdifCommentLine(lineStartToken.getOffset(),
+            // getValueOrNull(lineStartToken), getValueOrNull(sepToken)));
+            // }
+            // }
+            //			
+            // // unknown line
+            // if(lineStartToken == null) {
+            // lineStartToken = this.scanner.matchOther();
+            // if(lineStartToken != null) {
+            // record.addOther(new
+            // LdifInvalidPart(lineStartToken.getOffset(),
+            // lineStartToken.getValue()));
+            // }
+            // }
+
+            // // end of file
+            // if(lineStartToken == null) {
+            // return;
+            // }
+        }
+        while ( true );
+    }
+
+
+    private boolean checkAndParseEndOfRecord( LdifRecord record )
+    {
+        // check end of record
+        LdifToken eorSepToken = this.scanner.matchSep();
+        if ( eorSepToken != null )
+        {
+            record.finish( new LdifSepLine( eorSepToken.getOffset(), getValueOrNull( eorSepToken ) ) );
+            return true;
+        }
+
+        // check end of file
+        LdifToken eofToken = this.scanner.matchEOF();
+        if ( eofToken != null )
+        {
+            record.finish( new LdifEOFPart( eofToken.getOffset() ) );
+            return true;
+        }
+        return false;
+    }
+
+
+    private boolean checkAndParseComment( LdifRecord record )
+    {
+        LdifToken commentToken = this.scanner.matchComment();
+        if ( commentToken != null )
+        {
+            LdifToken sepToken = this.scanner.matchSep();
+            record.addComment( new LdifCommentLine( commentToken.getOffset(), getValueOrNull( commentToken ),
+                getValueOrNull( sepToken ) ) );
+            return true;
+        }
+        else
+        {
+            return false;
+        }
+    }
+
+
+    private boolean checkAndParseOther( LdifRecord record )
+    {
+        LdifToken otherToken = this.scanner.matchOther();
+        if ( otherToken != null )
+        {
+            record.addInvalid( new LdifInvalidPart( otherToken.getOffset(), otherToken.getValue() ) );
+            return true;
+        }
+        else
+        {
+            return false;
+        }
+    }
+
+
+    /**
+     * Checks for version line. If version line is present it is parsed and
+     * added to the given model.
+     * 
+     * @param model
+     *                the model
+     * @return true if version line was added to the model, false otherwise
+     */
+    private boolean checkAndParseVersion( LdifFile model )
+    {
+        LdifToken versionSpecToken = this.scanner.matchVersionSpec();
+        if ( versionSpecToken != null )
+        {
+
+            LdifToken versionTypeToken = null;
+            LdifToken versionToken = null;
+            LdifToken sepToken = null;
+            versionTypeToken = this.scanner.matchValueType();
+            if ( versionTypeToken != null )
+            {
+                versionToken = this.scanner.matchNumber();
+                if ( versionToken != null )
+                {
+                    sepToken = this.scanner.matchSep();
+                }
+            }
+
+            LdifVersionContainer container = new LdifVersionContainer( new LdifVersionLine( versionSpecToken
+                .getOffset(), getValueOrNull( versionSpecToken ), getValueOrNull( versionTypeToken ),
+                getValueOrNull( versionToken ), getValueOrNull( sepToken ) ) );
+            model.addContainer( container );
+
+            // clean line
+            if ( sepToken == null )
+            {
+                this.cleanupLine( container );
+            }
+
+            return true;
+        }
+        else
+        {
+            return false;
+        }
+    }
+
+
+    /**
+     * Checks for comment lines or empty lines. If such lines are present
+     * they are parsed and added to the given model.
+     * 
+     * @param model
+     *                the model
+     * @return true if comment or empty lines were added to the model, false
+     *         otherwise
+     */
+    private boolean checkAndParseComment( LdifFile model )
+    {
+        LdifToken sepToken = this.scanner.matchSep();
+        LdifToken commentToken = this.scanner.matchComment();
+
+        if ( sepToken != null || commentToken != null )
+        {
+
+            while ( sepToken != null || commentToken != null )
+            {
+
+                if ( sepToken != null )
+                {
+                    LdifSepLine sepLine = new LdifSepLine( sepToken.getOffset(), getValueOrNull( sepToken ) );
+                    LdifSepContainer sepContainer = new LdifSepContainer( sepLine );
+                    model.addContainer( sepContainer );
+                }
+
+                if ( commentToken != null )
+                {
+                    LdifCommentContainer commentContainer = null;
+                    while ( commentToken != null )
+                    {
+                        LdifToken commentSepToken = this.scanner.matchSep();
+                        LdifCommentLine commentLine = new LdifCommentLine( commentToken.getOffset(),
+                            getValueOrNull( commentToken ), getValueOrNull( commentSepToken ) );
+
+                        if ( commentContainer == null )
+                        {
+                            commentContainer = new LdifCommentContainer( commentLine );
+                        }
+                        else
+                        {
+                            commentContainer.addComment( commentLine );
+                        }
+
+                        commentToken = this.scanner.matchComment();
+                    }
+                    model.addContainer( commentContainer );
+                }
+
+                sepToken = this.scanner.matchSep();
+                commentToken = this.scanner.matchComment();
+            }
+
+            return true;
+        }
+        else
+        {
+            return false;
+        }
+    }
+
+
+    /**
+     * Checks for other line. If such line is present it is parsed and added
+     * to the given model.
+     * 
+     * @param model
+     *                the model
+     * @return always true except if EOF reached
+     */
+    private boolean checkAndParseOther( LdifFile model )
+    {
+        LdifToken token = this.scanner.matchOther();
+        if ( token != null )
+        {
+            LdifInvalidPart unknownLine = new LdifInvalidPart( token.getOffset(), getValueOrNull( token ) );
+            LdifInvalidContainer otherContainer = new LdifInvalidContainer( unknownLine );
+            model.addContainer( otherContainer );
+            return true;
+        }
+        else
+        {
+            return false;
+        }
+    }
+
+
+    private LdifControlLine getControlLine()
+    {
+
+        LdifToken controlSpecToken = this.scanner.matchControlSpec();
+        if ( controlSpecToken != null )
+        {
+            LdifToken controlTypeToken = null;
+            LdifToken oidToken = null;
+            LdifToken criticalityToken = null;
+            LdifToken valueTypeToken = null;
+            LdifToken valueToken = null;
+            LdifToken sepToken = null;
+            controlTypeToken = this.scanner.matchValueType();
+            if ( controlTypeToken != null )
+            {
+                oidToken = this.scanner.matchOid();
+                if ( oidToken != null )
+                {
+                    criticalityToken = this.scanner.matchCriticality();
+                    valueTypeToken = this.scanner.matchValueType();
+                    if ( valueTypeToken != null )
+                    {
+                        valueToken = this.scanner.matchValue();
+                    }
+                    sepToken = this.scanner.matchSep();
+                }
+            }
+
+            LdifControlLine controlLine = new LdifControlLine( controlSpecToken.getOffset(),
+                getValueOrNull( controlSpecToken ), getValueOrNull( controlTypeToken ), getValueOrNull( oidToken ),
+                getValueOrNull( criticalityToken ), getValueOrNull( valueTypeToken ), getValueOrNull( valueToken ),
+                getValueOrNull( sepToken ) );
+
+            return controlLine;
+        }
+
+        return null;
+    }
+
+
+    private LdifChangeTypeLine getChangeTypeLine()
+    {
+
+        LdifToken changeTypeSpecToken = this.scanner.matchChangeTypeSpec();
+        if ( changeTypeSpecToken != null )
+        {
+            LdifToken changeTypeTypeToken = null;
+            LdifToken changeTypeToken = null;
+            LdifToken sepToken = null;
+            changeTypeTypeToken = this.scanner.matchValueType();
+            if ( changeTypeTypeToken != null )
+            {
+                changeTypeToken = this.scanner.matchChangeType();
+                if ( changeTypeToken != null )
+                {
+                    sepToken = this.scanner.matchSep();
+                }
+            }
+
+            LdifChangeTypeLine ctLine = new LdifChangeTypeLine( changeTypeSpecToken.getOffset(),
+                getValueOrNull( changeTypeSpecToken ), getValueOrNull( changeTypeTypeToken ),
+                getValueOrNull( changeTypeToken ), getValueOrNull( sepToken ) );
+
+            return ctLine;
+        }
+
+        return null;
+    }
+
+
+    private LdifAttrValLine getAttrValLine()
+    {
+        LdifToken attrToken = this.scanner.matchAttributeDescription();
+        if ( attrToken != null )
+        {
+            LdifToken valueTypeToken = null;
+            LdifToken valueToken = null;
+            LdifToken sepToken = null;
+            valueTypeToken = this.scanner.matchValueType();
+            if ( valueTypeToken != null )
+            {
+                valueToken = this.scanner.matchValue();
+                if ( valueToken != null )
+                {
+                    sepToken = this.scanner.matchSep();
+                }
+            }
+
+            LdifAttrValLine line = new LdifAttrValLine( attrToken.getOffset(), getValueOrNull( attrToken ),
+                getValueOrNull( valueTypeToken ), getValueOrNull( valueToken ), getValueOrNull( sepToken ) );
+
+            return line;
+        }
+
+        return null;
+    }
+
+
+    private LdifCommentLine[] getCommentLines()
+    {
+        List list = new ArrayList( 1 );
+        LdifToken commentToken = this.scanner.matchComment();
+        while ( commentToken != null )
+        {
+            LdifToken sepToken = this.scanner.matchSep();
+            list
+                .add( new LdifCommentLine( commentToken.getOffset(), commentToken.getValue(), getValueOrNull( sepToken ) ) );
+
+            commentToken = this.scanner.matchComment();
+        }
+        return ( LdifCommentLine[] ) list.toArray( new LdifCommentLine[list.size()] );
+    }
+
+
+    private void cleanupLine( LdifContainer container )
+    {
+        LdifToken errorToken = this.scanner.matchCleanupLine();
+        if ( errorToken != null )
+        {
+            container.addInvalid( new LdifInvalidPart( errorToken.getOffset(), errorToken.getValue() ) );
+        }
+    }
+
+
+    private LdifToken cleanupLine()
+    {
+        LdifToken errorToken = this.scanner.matchCleanupLine();
+        return errorToken;
+    }
+
+
+    private static String getValueOrNull( LdifToken token )
+    {
+        return token == null ? null : token.getValue();
+    }
+
+}

Propchange: directory/sandbox/felixk/studio-ldif-parser/src/main/java/org/apache/directory/studio/ldifparser/parser/LdifParser.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: directory/sandbox/felixk/studio-ldif-parser/src/main/java/org/apache/directory/studio/ldifparser/parser/LdifScanner.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-ldif-parser/src/main/java/org/apache/directory/studio/ldifparser/parser/LdifScanner.java?rev=597198&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-ldif-parser/src/main/java/org/apache/directory/studio/ldifparser/parser/LdifScanner.java (added)
+++ directory/sandbox/felixk/studio-ldif-parser/src/main/java/org/apache/directory/studio/ldifparser/parser/LdifScanner.java Wed Nov 21 12:08:28 2007
@@ -0,0 +1,1100 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+
+package org.apache.directory.studio.ldifparser.parser;
+
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.Reader;
+
+
+// RFC 2849
+//
+// ldif-file = ldif-content / ldif-changes
+// ldif-content = version-spec 1*(1*SEP ldif-attrval-record)
+// ldif-changes = version-spec 1*(1*SEP ldif-change-record)
+// ldif-attrval-record = dn-spec SEP 1*attrval-spec
+// ldif-change-record = dn-spec SEP *control changerecord
+// version-spec = "version:" FILL version-number
+// version-number = 1*DIGIT
+// ; version-number MUST be "1" for the
+// ; LDIF format described in this document.
+// dn-spec = "dn:" (FILL distinguishedName /
+// ":" FILL base64-distinguishedName)
+// distinguishedName = SAFE-STRING
+// ; a distinguished name, as defined in [3]
+// base64-distinguishedName = BASE64-UTF8-STRING
+// ; a distinguishedName which has been base64
+// ; encoded (see note 10, below)
+// rdn = SAFE-STRING
+// ; a relative distinguished name, defined as
+// ; <name-component> in [3]
+// base64-rdn = BASE64-UTF8-STRING
+// ; an rdn which has been base64 encoded (see
+// ; note 10, below)
+// control = "control:" FILL ldap-oid ; controlType
+// 0*1(1*SPACE ("true" / "false")) ; criticality
+// 0*1(value-spec) ; controlValue
+// SEP
+// ; (See note 9, below)
+// ldap-oid = 1*DIGIT 0*1("." 1*DIGIT)
+// ; An LDAPOID, as defined in [4]
+// attrval-spec = AttributeDescription value-spec SEP
+// value-spec = ":" ( FILL 0*1(SAFE-STRING) /
+// ":" FILL (BASE64-STRING) /
+// "<" FILL url)
+// ; See notes 7 and 8, below
+// url = <a Uniform Resource Locator,
+// as defined in [6]>
+// ; (See Note 6, below)
+// AttributeDescription = AttributeType [";" options]
+// ; Definition taken from [4]
+// AttributeType = ldap-oid / (ALPHA *(attr-type-chars))
+// options = option / (option ";" options)
+// option = 1*opt-char
+// attr-type-chars = ALPHA / DIGIT / "-"
+// opt-char = attr-type-chars
+// changerecord = "changetype:" FILL
+// (change-add / change-delete /
+// change-modify / change-moddn)
+// change-add = "add" SEP 1*attrval-spec
+// change-delete = "delete" SEP
+// change-moddn = ("modrdn" / "moddn") SEP
+// "newrdn:" ( FILL rdn /
+// ":" FILL base64-rdn) SEP
+// "deleteoldrdn:" FILL ("0" / "1") SEP
+// 0*1("newsuperior:"
+// ( FILL distinguishedName /
+// ":" FILL base64-distinguishedName) SEP)
+// change-modify = "modify" SEP *mod-spec
+// mod-spec = ("add:" / "delete:" / "replace:")
+// FILL AttributeDescription SEP
+// *attrval-spec
+// "-" SEP
+// SPACE = %x20
+// ; ASCII SP, space
+// FILL = *SPACE
+// SEP = (CR LF / LF)
+// CR = %x0D
+// ; ASCII CR, carriage return
+// LF = %x0A
+// ; ASCII LF, line feed
+// ALPHA = %x41-5A / %x61-7A
+// ; A-Z / a-z
+// DIGIT = %x30-39
+// ; 0-9
+// UTF8-1 = %x80-BF
+// UTF8-2 = %xC0-DF UTF8-1
+// UTF8-3 = %xE0-EF 2UTF8-1
+// UTF8-4 = %xF0-F7 3UTF8-1
+// UTF8-5 = %xF8-FB 4UTF8-1
+// UTF8-6 = %xFC-FD 5UTF8-1
+// SAFE-CHAR = %x01-09 / %x0B-0C / %x0E-7F
+// ; any value <= 127 decimal except NUL, LF,
+// ; and CR
+// SAFE-INIT-CHAR = %x01-09 / %x0B-0C / %x0E-1F /
+// %x21-39 / %x3B / %x3D-7F
+// ; any value <= 127 except NUL, LF, CR,
+// ; SPACE, colon (":", ASCII 58 decimal)
+// ; and less-than ("<" , ASCII 60 decimal)
+// SAFE-STRING = [SAFE-INIT-CHAR *SAFE-CHAR]
+// UTF8-CHAR = SAFE-CHAR / UTF8-2 / UTF8-3 /
+// UTF8-4 / UTF8-5 / UTF8-6
+// UTF8-STRING = *UTF8-CHAR
+// BASE64-UTF8-STRING = BASE64-STRING
+// ; MUST be the base64 encoding of a
+// ; UTF8-STRING
+// BASE64-CHAR = %x2B / %x2F / %x30-39 / %x3D / %x41-5A /
+// %x61-7A
+// ; +, /, 0-9, =, A-Z, and a-z
+// ; as specified in [5]
+// BASE64-STRING = [*(BASE64-CHAR)]
+
+public class LdifScanner
+{
+
+    private Reader ldifReader;
+
+    private char[] buffer = new char[256];
+
+    private StringBuffer ldifBuffer;
+
+    private int ldifBufferOffset;
+
+    private int pos;
+
+
+    public LdifScanner()
+    {
+        super();
+    }
+
+
+    public void setLdif( Reader ldifReader )
+    {
+        // this.ldif = ldif;
+        this.ldifReader = ldifReader;
+        this.pos = -1;
+
+        this.ldifBuffer = new StringBuffer();
+        this.ldifBufferOffset = 0;
+    }
+
+
+    char currentChar() throws EOFException
+    {
+
+        // check and fill buffer
+        try
+        {
+            int num = 0;
+            while ( ldifBufferOffset + ldifBuffer.length() <= pos && num > -1 )
+            {
+                num = this.ldifReader.read( buffer );
+                if ( num > -1 )
+                {
+                    ldifBuffer.append( buffer, 0, num );
+                }
+            }
+        }
+        catch ( IOException e )
+        {
+        }
+
+        if ( 0 <= pos && pos < ldifBufferOffset + ldifBuffer.length() )
+        {
+            try
+            {
+                return ldifBuffer.charAt( pos - ldifBufferOffset );
+            }
+            catch ( RuntimeException e )
+            {
+                e.printStackTrace();
+                throw e;
+            }
+        }
+        else
+        {
+            throw new EOFException();
+        }
+
+        // return 0<=pos&&pos<ldif.length() ? ldif.charAt(pos) : '\u0000';
+    }
+
+
+    void addFolding( StringBuffer sb )
+    {
+
+        int oldPos = pos;
+
+        try
+        {
+            pos++;
+            char c = currentChar();
+            if ( c == '\n' || c == '\r' )
+            {
+                StringBuffer temp = new StringBuffer( 3 );
+                temp.append( c );
+                if ( c == '\r' )
+                {
+                    pos++;
+                    c = currentChar();
+                    if ( c == '\n' )
+                    {
+                        temp.append( c );
+                    }
+                    else
+                    {
+                        pos--;
+                    }
+                }
+                else if ( c == '\n' )
+                {
+                    pos++;
+                    c = currentChar();
+                    if ( c == '\r' )
+                    {
+                        temp.append( c );
+                    }
+                    else
+                    {
+                        pos--;
+                    }
+                }
+
+                pos++;
+                c = currentChar();
+                if ( c == ' ' )
+                {
+                    // space after newline, continue
+                    temp.append( c );
+                    sb.append( temp );
+                }
+                else
+                {
+                    for ( int i = 0; i < temp.length(); i++ )
+                    {
+                        pos--;
+                    }
+                    pos--;
+                }
+            }
+            else
+            {
+                pos--;
+            }
+        }
+        catch ( EOFException e )
+        {
+            // reset position
+            pos = oldPos;
+        }
+
+    }
+
+
+    /**
+     * Reads the next character from input stram if available. If read was
+     * possible the character is appended to the given StringBuffer and
+     * returned. Otherwise throws a EOFException. Additionally this method
+     * checks folding sequence SEP + SPACE. If any folding sequence was
+     * found the sequence is appended to the given StringBuffer. So it is
+     * possible the StringBuffer doesn't end with the read character after
+     * calling this method but with a folding sequence
+     * 
+     * @param sb
+     * @return the next character if available
+     * @throws EOFException
+     */
+    public char read( StringBuffer sb ) throws EOFException
+    {
+        try
+        {
+
+            // check EOF
+            // if(pos > -1) {
+            // currentChar();
+            // }
+
+            // get next char
+            pos++;
+            char c = currentChar();
+            sb.append( c );
+
+            // folding
+            addFolding( sb );
+
+            return c;
+        }
+        catch ( EOFException e )
+        {
+            pos--;
+            throw e;
+        }
+    }
+
+
+    void removeFolding( StringBuffer sb )
+    {
+
+        int oldPos = pos;
+
+        try
+        {
+            char c = currentChar();
+            pos--;
+            if ( c == ' ' )
+            {
+                StringBuffer temp = new StringBuffer();
+                temp.insert( 0, c );
+                c = currentChar();
+                pos--;
+
+                if ( c == '\n' || c == '\r' )
+                {
+                    if ( c == '\r' )
+                    {
+                        temp.insert( 0, c );
+                        c = currentChar();
+                        pos--;
+                        if ( c == '\n' )
+                        {
+                            temp.insert( 0, c );
+                        }
+                        else
+                        {
+                            pos++;
+                        }
+                    }
+                    else if ( c == '\n' )
+                    {
+                        temp.insert( 0, c );
+                        c = currentChar();
+                        pos--;
+                        if ( c == '\r' )
+                        {
+                            temp.insert( 0, c );
+                        }
+                        else
+                        {
+                            pos++;
+                        }
+                    }
+
+                    sb.delete( sb.length() - temp.length(), sb.length() );
+                }
+                else
+                {
+                    pos++;
+                    pos++;
+                }
+            }
+            else
+            {
+                pos++;
+            }
+        }
+        catch ( EOFException e )
+        {
+            // reset position
+            pos = oldPos;
+        }
+    }
+
+
+    /**
+     * Inverses the previous read().
+     * 
+     * @param sb
+     * @return the previous character if available
+     * @throws EOFException
+     */
+    public void unread( StringBuffer sb )
+    {
+        removeFolding( sb );
+
+        if ( pos > -1 )
+        {
+            pos--;
+
+            if ( sb.length() > 0 )
+            {
+                sb.deleteCharAt( sb.length() - 1 );
+            }
+        }
+    }
+
+
+    private String getFullLine( String start )
+    {
+        String s1 = this.getWord( start );
+        if ( s1 != null )
+        {
+            String s2 = getContent();
+            return s2 != null ? s1 + s2 : s1;
+        }
+        else
+        {
+            return null;
+        }
+    }
+
+
+    private String getContent()
+    {
+
+        StringBuffer sb = new StringBuffer( 256 );
+
+        try
+        {
+            char c = '\u0000';
+            while ( c != '\n' && c != '\r' )
+            {
+                c = read( sb );
+            }
+            unread( sb );
+
+        }
+        catch ( EOFException e )
+        {
+        }
+
+        return sb.length() > 0 ? sb.toString() : null;
+    }
+
+
+    // private String getStartAndFill(String start) {
+    // String s = this.getWord(start);
+    // if(s != null) {
+    // StringBuffer sb = new StringBuffer(s);
+    //			
+    // try {
+    // char c = '\u0000';
+    // while (c==' ') {
+    // c = read(sb);
+    // }
+    // unread(sb);
+    // } catch (EOFException e) {
+    // }
+    //    		
+    // return sb.toString();
+    // }
+    // else {
+    // return null;
+    // }
+    // }
+
+    private String getWord( String word )
+    {
+        StringBuffer sb = new StringBuffer();
+
+        // read
+        try
+        {
+            boolean matches = true;
+            for ( int i = 0; i < word.length(); i++ )
+            {
+
+                char c = read( sb );
+                if ( c != word.charAt( i ) )
+                {
+                    matches = false;
+                    unread( sb );
+                    break;
+                }
+            }
+
+            if ( matches )
+            {
+                return sb.toString();
+            }
+        }
+        catch ( EOFException e )
+        {
+        }
+
+        // unread
+        while ( sb.length() > 0 )
+        {
+            unread( sb );
+        }
+        // prevChar(sb);
+        return null;
+    }
+
+
+    private String getWordTillColon( String word )
+    {
+
+        String wordWithColon = word + ":";
+        String line = getWord( wordWithColon );
+        if ( line != null )
+        {
+            StringBuffer sb = new StringBuffer( line );
+            unread( sb );
+            return sb.toString();
+        }
+
+        // allow eof and sep
+        line = getWord( word );
+        if ( line != null )
+        {
+            StringBuffer sb = new StringBuffer( line );
+            try
+            {
+                char c = read( sb );
+                unread( sb );
+                if ( c == '\r' || c == '\n' )
+                {
+                    return sb.toString();
+                }
+                else
+                {
+                    while ( sb.length() > 0 )
+                    {
+                        unread( sb );
+                    }
+                    return null;
+                }
+            }
+            catch ( EOFException e )
+            {
+                return sb.toString();
+            }
+        }
+
+        return null;
+    }
+
+
+    private void flushBuffer()
+    {
+
+        // System.out.println("flushBuffer():
+        // before("+this.pos+","+this.ldifBufferOffset+")");
+
+        if ( this.ldifBufferOffset < this.pos && this.ldifBuffer.length() > 0 )
+        {
+            int delta = Math.min( pos - this.ldifBufferOffset, this.ldifBuffer.length() );
+            delta--;
+            this.ldifBuffer.delete( 0, delta );
+            this.ldifBufferOffset += delta;
+        }
+
+        // System.out.println("flushBuffer():
+        // after("+this.pos+","+this.ldifBufferOffset+")");
+    }
+
+
+    public LdifToken matchCleanupLine()
+    {
+        this.flushBuffer();
+
+        String line = getContent();
+        LdifToken sep = matchSep();
+
+        if ( line != null || sep != null )
+        {
+            if ( line == null )
+                line = "";
+
+            if ( sep != null )
+                line += sep.getValue();
+
+            return new LdifToken( LdifToken.UNKNOWN, line, pos - line.length() + 1 );
+        }
+
+        return null;
+    }
+
+
+    public LdifToken matchOther()
+    {
+        this.flushBuffer();
+
+        String line = getContent();
+        if ( line != null )
+        {
+            LdifToken sep = matchSep();
+            if ( sep != null )
+                line += sep.getValue();
+            return new LdifToken( LdifToken.UNKNOWN, line, pos - line.length() + 1 );
+        }
+
+        return null;
+    }
+
+
+    public LdifToken matchEOF()
+    {
+        this.flushBuffer();
+
+        StringBuffer sb = new StringBuffer( 1 );
+        try
+        {
+            read( sb );
+            unread( sb );
+            return null;
+        }
+        catch ( EOFException e )
+        {
+            return new LdifToken( LdifToken.EOF, "", pos + 1 );
+        }
+
+    }
+
+
+    public LdifToken matchSep()
+    {
+        this.flushBuffer();
+
+        try
+        {
+            StringBuffer sb = new StringBuffer();
+            char c = read( sb );
+            if ( c == '\n' || c == '\r' )
+            {
+
+                // check for two-char-linebreak
+                try
+                {
+                    if ( c == '\r' )
+                    {
+                        c = read( sb );
+                        if ( c != '\n' )
+                        {
+                            unread( sb );
+                        }
+                    }
+                    else if ( c == '\n' )
+                    {
+                        c = read( sb );
+                        if ( c != '\r' )
+                        {
+                            unread( sb );
+                        }
+                    }
+                }
+                catch ( EOFException e )
+                {
+                }
+
+                return new LdifToken( LdifToken.SEP, sb.toString(), pos - sb.length() + 1 );
+            }
+            else
+            {
+                unread( sb );
+            }
+        }
+        catch ( EOFException e )
+        {
+        }
+
+        return null;
+    }
+
+
+    public LdifToken matchComment()
+    {
+        this.flushBuffer();
+
+        String line = getFullLine( "#" );
+        if ( line != null )
+        {
+            return new LdifToken( LdifToken.COMMENT, line, pos - line.length() + 1 );
+        }
+
+        return null;
+    }
+
+
+    public LdifToken matchVersionSpec()
+    {
+        this.flushBuffer();
+
+        String line = getWordTillColon( "version" );
+        if ( line != null )
+        {
+            return new LdifToken( LdifToken.VERSION_SPEC, line, pos - line.length() + 1 );
+        }
+
+        return null;
+    }
+
+
+    public LdifToken matchDnSpec()
+    {
+        this.flushBuffer();
+
+        String line = getWordTillColon( "dn" );
+        if ( line != null )
+        {
+            return new LdifToken( LdifToken.DN_SPEC, line, pos - line.length() + 1 );
+        }
+
+        return null;
+    }
+
+
+    public LdifToken matchControlSpec()
+    {
+        this.flushBuffer();
+
+        String line = getWordTillColon( "control" );
+        if ( line != null )
+        {
+            return new LdifToken( LdifToken.CONTROL_SPEC, line, pos - line.length() + 1 );
+        }
+
+        return null;
+    }
+
+
+    public LdifToken matchChangeTypeSpec()
+    {
+        this.flushBuffer();
+
+        String line = getWordTillColon( "changetype" );
+        if ( line != null )
+        {
+            return new LdifToken( LdifToken.CHANGETYPE_SPEC, line, pos - line.length() + 1 );
+        }
+
+        return null;
+    }
+
+
+    public LdifToken matchChangeType()
+    {
+        this.flushBuffer();
+
+        String line = getWord( "add" );
+        if ( line != null )
+        {
+            return new LdifToken( LdifToken.CHANGETYPE_ADD, line, pos - line.length() + 1 );
+        }
+        line = getWord( "modify" );
+        if ( line != null )
+        {
+            return new LdifToken( LdifToken.CHANGETYPE_MODIFY, line, pos - line.length() + 1 );
+        }
+        line = getWord( "delete" );
+        if ( line != null )
+        {
+            return new LdifToken( LdifToken.CHANGETYPE_DELETE, line, pos - line.length() + 1 );
+        }
+        line = getWord( "moddn" );
+        if ( line != null )
+        {
+            return new LdifToken( LdifToken.CHANGETYPE_MODDN, line, pos - line.length() + 1 );
+        }
+        line = getWord( "modrdn" );
+        if ( line != null )
+        {
+            return new LdifToken( LdifToken.CHANGETYPE_MODDN, line, pos - line.length() + 1 );
+        }
+
+        return null;
+    }
+
+
+    public LdifToken matchCriticality()
+    {
+        this.flushBuffer();
+
+        StringBuffer sb = new StringBuffer();
+
+        String s = getWord( " " );
+        while ( s != null )
+        {
+            sb.append( s );
+            s = getWord( " " );
+        }
+
+        String t = getWord( "true" );
+        if ( t != null )
+        {
+            sb.append( t );
+            return new LdifToken( LdifToken.CONTROL_CRITICALITY_TRUE, sb.toString(), pos - sb.length() + 1 );
+        }
+        String f = getWord( "false" );
+        if ( f != null )
+        {
+            sb.append( f );
+            return new LdifToken( LdifToken.CONTROL_CRITICALITY_FALSE, sb.toString(), pos - sb.length() + 1 );
+        }
+
+        while ( sb.length() > 0 )
+        {
+            unread( sb );
+        }
+
+        // for(int i=0; i<sb.length(); i++) {
+        // unread(sb);
+        // }
+
+        return null;
+    }
+
+
+    public LdifToken matchNumber()
+    {
+        this.flushBuffer();
+
+        try
+        {
+            StringBuffer sb = new StringBuffer();
+            char c = read( sb );
+            if ( '0' <= c && c <= '9' )
+            {
+
+                try
+                {
+                    while ( '0' <= c && c <= '9' )
+                    {
+                        c = read( sb );
+                    }
+                    unread( sb );
+                }
+                catch ( EOFException e )
+                {
+                }
+
+                return new LdifToken( LdifToken.NUMBER, sb.toString(), pos - sb.length() + 1 );
+            }
+            else
+            {
+                unread( sb );
+            }
+        }
+        catch ( EOFException e )
+        {
+        }
+
+        return null;
+    }
+
+
+    public LdifToken matchOid()
+    {
+        this.flushBuffer();
+
+        try
+        {
+            StringBuffer sb = new StringBuffer();
+            char c = read( sb );
+            if ( '0' <= c && c <= '9' )
+            {
+
+                try
+                {
+                    while ( '0' <= c && c <= '9' || c == '.' )
+                    {
+                        c = read( sb );
+                    }
+                    unread( sb );
+                }
+                catch ( EOFException e )
+                {
+                }
+
+                return new LdifToken( LdifToken.OID, sb.toString(), pos - sb.length() + 1 );
+            }
+            else
+            {
+                unread( sb );
+            }
+        }
+        catch ( EOFException e )
+        {
+        }
+
+        return null;
+    }
+
+
+    public LdifToken matchAttributeDescription()
+    {
+        this.flushBuffer();
+
+        try
+        {
+            StringBuffer sb = new StringBuffer();
+            char c = read( sb );
+            if ( 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || '0' <= c && c <= '9' )
+            {
+
+                try
+                {
+                    while ( 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || '0' <= c && c <= '9' || c == '.'
+                        || c == ';' || c == '-' )
+                    {
+                        c = read( sb );
+                    }
+                    unread( sb );
+                }
+                catch ( EOFException e )
+                {
+                }
+
+                return new LdifToken( LdifToken.ATTRIBUTE, sb.toString(), pos - sb.length() + 1 );
+            }
+            else
+            {
+                unread( sb );
+            }
+        }
+        catch ( EOFException e )
+        {
+        }
+
+        // // a-z,A-Z,0-9,.,-,;
+        // StringBuffer sb = new StringBuffer();
+        // char c = nextChar(sb);
+        // if('a'<=c&&c<='z' || 'A'<=c&&c<='Z' || '0'<=c&&c<='9') {
+        // while('a'<=c&&c<='z' || 'A'<=c&&c<='Z' || '0'<=c&&c<='9' || c=='.' ||
+        // c==';' || c=='-') {
+        // sb.append(c);
+        // c = nextChar(sb);
+        // }
+        // unread(sb);
+        //
+        // return new LdifToken(LdifToken.ATTRIBUTE, sb.toString(),
+        // pos-sb.length()+1);
+        // }
+        // else {
+        // unread(sb);
+        // }
+
+        return null;
+    }
+
+
+    public LdifToken matchModTypeSpec()
+    {
+        this.flushBuffer();
+
+        String line = getWord( "add" );
+        if ( line != null )
+        {
+            return new LdifToken( LdifToken.MODTYPE_ADD_SPEC, line, pos - line.length() + 1 );
+        }
+        line = getWord( "replace" );
+        if ( line != null )
+        {
+            return new LdifToken( LdifToken.MODTYPE_REPLACE_SPEC, line, pos - line.length() + 1 );
+        }
+        line = getWord( "delete" );
+        if ( line != null )
+        {
+            return new LdifToken( LdifToken.MODTYPE_DELETE_SPEC, line, pos - line.length() + 1 );
+        }
+
+        return null;
+    }
+
+
+    public LdifToken matchModSep()
+    {
+        this.flushBuffer();
+
+        String line = getWord( "-" );
+        if ( line != null )
+        {
+            return new LdifToken( LdifToken.MODTYPE_SEP, line, pos - line.length() + 1 );
+        }
+
+        return null;
+    }
+
+
+    public LdifToken matchValueType()
+    {
+        this.flushBuffer();
+
+        try
+        {
+            StringBuffer sb = new StringBuffer();
+            char c = read( sb );
+            if ( c == ':' )
+            {
+
+                int tokenType = LdifToken.VALUE_TYPE_SAFE;
+                try
+                {
+                    c = read( sb );
+                    if ( c == ':' )
+                    {
+                        tokenType = LdifToken.VALUE_TYPE_BASE64;
+                    }
+                    else if ( c == '<' )
+                    {
+                        tokenType = LdifToken.VALUE_TYPE_URL;
+                    }
+                    else
+                    {
+                        tokenType = LdifToken.VALUE_TYPE_SAFE;
+                        unread( sb );
+                    }
+
+                    c = read( sb );
+                    while ( c == ' ' )
+                    {
+                        c = read( sb );
+                    }
+                    unread( sb );
+
+                }
+                catch ( EOFException e )
+                {
+                }
+
+                return new LdifToken( tokenType, sb.toString(), pos - sb.length() + 1 );
+            }
+            else
+            {
+                unread( sb );
+            }
+        }
+        catch ( EOFException e )
+        {
+        }
+
+        return null;
+    }
+
+
+    public LdifToken matchValue()
+    {
+        this.flushBuffer();
+
+        String line = getContent();
+        if ( line != null )
+        {
+            return new LdifToken( LdifToken.VALUE, line, pos - line.length() + 1 );
+        }
+
+        return null;
+    }
+
+
+    public LdifToken matchNewrdnSpec()
+    {
+        this.flushBuffer();
+
+        String line = getWordTillColon( "newrdn" );
+        if ( line != null )
+        {
+            return new LdifToken( LdifToken.MODDN_NEWRDN_SPEC, line, pos - line.length() + 1 );
+        }
+
+        return null;
+    }
+
+
+    public LdifToken matchDeleteoldrdnSpec()
+    {
+        this.flushBuffer();
+
+        String line = getWordTillColon( "deleteoldrdn" );
+        if ( line != null )
+        {
+            return new LdifToken( LdifToken.MODDN_DELOLDRDN_SPEC, line, pos - line.length() + 1 );
+        }
+
+        return null;
+    }
+
+
+    public LdifToken matchNewsuperiorSpec()
+    {
+        this.flushBuffer();
+
+        String line = getWordTillColon( "newsuperior" );
+        if ( line != null )
+        {
+            return new LdifToken( LdifToken.MODDN_NEWSUPERIOR_SPEC, line, pos - line.length() + 1 );
+        }
+
+        return null;
+    }
+
+}

Propchange: directory/sandbox/felixk/studio-ldif-parser/src/main/java/org/apache/directory/studio/ldifparser/parser/LdifScanner.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: directory/sandbox/felixk/studio-ldif-parser/src/main/java/org/apache/directory/studio/ldifparser/parser/LdifToken.java
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/studio-ldif-parser/src/main/java/org/apache/directory/studio/ldifparser/parser/LdifToken.java?rev=597198&view=auto
==============================================================================
--- directory/sandbox/felixk/studio-ldif-parser/src/main/java/org/apache/directory/studio/ldifparser/parser/LdifToken.java (added)
+++ directory/sandbox/felixk/studio-ldif-parser/src/main/java/org/apache/directory/studio/ldifparser/parser/LdifToken.java Wed Nov 21 12:08:28 2007
@@ -0,0 +1,160 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+
+package org.apache.directory.studio.ldifparser.parser;
+
+
+public class LdifToken implements Comparable
+{
+
+    public static final int NEW = Integer.MIN_VALUE;
+
+    public static final int ERROR = -2;
+
+    public static final int EOF = -1;
+
+    public static final int UNKNOWN = 0;
+
+    public static final int COMMENT = 1;
+
+    public static final int SEP = 2;
+
+    public static final int VERSION_SPEC = 4;
+
+    public static final int NUMBER = 5;
+
+    public static final int OID = 6;
+
+    public static final int DN_SPEC = 11;
+
+    public static final int DN = 12;
+
+    public static final int ATTRIBUTE = 21;
+
+    public static final int VALUE_TYPE_SAFE = 22;
+
+    public static final int VALUE_TYPE_BASE64 = 23;
+
+    public static final int VALUE_TYPE_URL = 24;
+
+    public static final int VALUE = 27;
+
+    public static final int CHANGETYPE_SPEC = 30;
+
+    public static final int CHANGETYPE_ADD = 31;
+
+    public static final int CHANGETYPE_DELETE = 32;
+
+    public static final int CHANGETYPE_MODIFY = 33;
+
+    public static final int CHANGETYPE_MODDN = 34;
+
+    public static final int MODTYPE_ADD_SPEC = 41;
+
+    public static final int MODTYPE_DELETE_SPEC = 42;
+
+    public static final int MODTYPE_REPLACE_SPEC = 43;
+
+    public static final int MODTYPE_SEP = 45; //
+
+    public static final int CONTROL_SPEC = 51; // control:FILL
+
+    public static final int CONTROL_LDAPOID = 52; // 
+
+    public static final int CONTROL_CRITICALITY_TRUE = 53; // FILLtrue
+
+    public static final int CONTROL_CRITICALITY_FALSE = 54; // FILLfalse
+
+    public static final int MODDN_NEWRDN_SPEC = 61;
+
+    public static final int MODDN_DELOLDRDN_SPEC = 63;
+
+    public static final int MODDN_NEWSUPERIOR_SPEC = 65;
+
+    private int offset;
+
+    private int type;
+
+    private String value;
+
+
+    public LdifToken( int type, String value, int offset )
+    {
+        this.type = type;
+        this.value = value;
+        this.offset = offset;
+    }
+
+
+    /**
+     * Returns the start position of the token in the original ldif
+     * 
+     * @return the start positon of the token
+     */
+    public int getOffset()
+    {
+        return this.offset;
+    }
+
+
+    /**
+     * Returns the length of the token in the original ldif
+     * 
+     * @return the length of the token
+     */
+    public int getLength()
+    {
+        return this.value.length();
+    }
+
+
+    public int getType()
+    {
+        return this.type;
+    }
+
+
+    public String getValue()
+    {
+        return this.value;
+    }
+
+
+    public String toString()
+    {
+        return "(type=" + this.type + ") " + "(offset=" + this.offset + ") " + "(length=" + this.getLength() + ") '"
+            + this.value + "'";
+    }
+
+
+    public int compareTo( Object o )
+    {
+        if ( o instanceof LdifToken )
+        {
+            LdifToken token = ( LdifToken ) o;
+            return this.offset - token.offset;
+        }
+        else
+        {
+            throw new ClassCastException( "Not instanceof LdifToken: " + o.getClass().getName() );
+        }
+    }
+
+}

Propchange: directory/sandbox/felixk/studio-ldif-parser/src/main/java/org/apache/directory/studio/ldifparser/parser/LdifToken.java
------------------------------------------------------------------------------
    svn:eol-style = native