protected LdifEntry parseEntry()

in ldap/model/src/main/java/org/apache/directory/api/ldap/model/ldif/LdifReader.java [1440:1627]


    protected LdifEntry parseEntry() throws LdapException
    {
        if ( ( lines == null ) || lines.isEmpty() )
        {
            if ( LOG.isDebugEnabled() )
            {
                LOG.debug( I18n.msg( I18n.MSG_13408_END_OF_LDIF ) );
            }

            return null;
        }

        // The entry must start with a dn: or a dn::
        String line = lines.get( 0 );

        lineNumber -= ( lines.size() - 1 );

        String name = parseDn( line );

        Dn dn = null;
        
        try
        {
            dn = new Dn( schemaManager, name );
        }
        catch ( LdapInvalidDnException lide )
        {
            // Deal with the RDN whihc is not in the schema
            // First parse the DN without the schema
            dn = new Dn( name );
            
            Rdn rdn = dn.getRdn();
            
            // Process each Ava
            for ( Ava ava : rdn )
            {
                if ( ( schemaManager != null ) && ( schemaManager.getAttributeType( ava.getType() ) == null ) 
                    && schemaManager.isRelaxed() )
                {
                    // Not found : create a new one
                    AttributeType newAttributeType = new AttributeType( "1.3.6.1.4.1.18060.0.9999." + oidCounter++ );
                    newAttributeType.setNames( ava.getType() );
                    newAttributeType.setSyntax( schemaManager.getLdapSyntaxRegistry().get( SchemaConstants.DIRECTORY_STRING_SYNTAX ) );
                    schemaManager.add( newAttributeType );
                }
            }
            
            dn = new Dn( schemaManager, name );
        }

        // Ok, we have found a Dn
        LdifEntry entry = createLdifEntry( schemaManager );
        entry.setLengthBeforeParsing( entryLen );
        entry.setOffset( entryOffset );

        entry.setDn( dn );

        // We remove this dn from the lines
        lines.remove( 0 );

        // Now, let's iterate through the other lines
        Iterator<String> iter = lines.iterator();

        // This flag is used to distinguish between an entry and a change
        int type = LDIF_ENTRY;

        // The following boolean is used to check that a control is *not*
        // found elswhere than just after the dn
        boolean controlSeen = false;

        // We use this boolean to check that we do not have AttributeValues
        // after a change operation
        boolean changeTypeSeen = false;

        ChangeType operation = ChangeType.Add;
        String lowerLine;
        Control control;

        while ( iter.hasNext() )
        {
            lineNumber++;

            // Each line could start either with an OID, an attribute type, with
            // "control:" or with "changetype:"
            line = iter.next();
            lowerLine = Strings.toLowerCaseAscii( line );

            // We have three cases :
            // 1) The first line after the Dn is a "control:"
            // 2) The first line after the Dn is a "changeType:"
            // 3) The first line after the Dn is anything else
            if ( lowerLine.startsWith( "control:" ) )
            {
                if ( containsEntries )
                {
                    LOG.error( I18n.err( I18n.ERR_13401_CHANGE_NOT_ALLOWED, lineNumber ) );
                    throw new LdapLdifException( I18n.err( I18n.ERR_13440_NO_CHANGE ) );
                }

                containsChanges = true;

                if ( controlSeen )
                {
                    LOG.error( I18n.err( I18n.ERR_13418_CONTROL_ALREADY_FOUND, lineNumber ) );
                    throw new LdapLdifException( I18n.err( I18n.ERR_13457_MISPLACED_CONTROL ) );
                }

                // Parse the control
                control = parseControl( line.substring( "control:".length() ) );
                entry.addControl( control );
            }
            else if ( lowerLine.startsWith( "changetype:" ) )
            {
                if ( containsEntries )
                {
                    LOG.error( I18n.err( I18n.ERR_13401_CHANGE_NOT_ALLOWED, lineNumber ) );
                    throw new LdapLdifException( I18n.err( I18n.ERR_13440_NO_CHANGE ) );
                }

                containsChanges = true;

                if ( changeTypeSeen )
                {
                    LOG.error( I18n.err( I18n.ERR_13419_CHANGETYPE_ALREADY_FOUND, lineNumber ) );
                    throw new LdapLdifException( I18n.err( I18n.ERR_13458_MISPLACED_CHANGETYPE ) );
                }

                // A change request
                type = CHANGE;
                controlSeen = true;

                operation = parseChangeType( line );

                // Parse the change operation in a separate function
                parseChange( entry, iter, operation );
                changeTypeSeen = true;
            }
            else if ( line.indexOf( ':' ) > 0 )
            {
                if ( containsChanges )
                {
                    LOG.error( I18n.err( I18n.ERR_13401_CHANGE_NOT_ALLOWED, lineNumber ) );
                    throw new LdapLdifException( I18n.err( I18n.ERR_13440_NO_CHANGE ) );
                }

                containsEntries = true;

                if ( controlSeen || changeTypeSeen )
                {
                    LOG.error( I18n.err( I18n.ERR_13420_AT_VALUE_NOT_ALLOWED_AFTER_CONTROL, lineNumber ) );
                    throw new LdapLdifException( I18n.err( I18n.ERR_13459_MISPLACED_ATTRIBUTETYPE ) );
                }

                parseAttributeValue( entry, line, lowerLine );
                type = LDIF_ENTRY;
            }
            else
            {
                // Invalid attribute Value
                LOG.error( I18n.err( I18n.ERR_13421_ATTRIBUTE_TYPE_EXPECTED, lineNumber ) );
                throw new LdapLdifException( I18n.err( I18n.ERR_13460_BAD_ATTRIBUTE ) );
            }
        }

        if ( type == LDIF_ENTRY )
        {
            if ( LOG.isDebugEnabled() )
            {
                LOG.debug( I18n.msg( I18n.MSG_13406_READ_ENTRY, entry ) );
            }
        }
        else if ( type == CHANGE )
        {
            entry.setChangeType( operation );

            if ( LOG.isDebugEnabled() )
            {
                LOG.debug( I18n.msg( I18n.MSG_13404_READ_MODIF, entry ) );
            }
        }
        else
        {
            LOG.error( I18n.err( I18n.ERR_13422_UNKNOWN_ENTRY_TYPE, lineNumber ) );
            throw new LdapLdifException( I18n.err( I18n.ERR_13461_UNKNOWN_ENTRY ) );
        }

        return entry;
    }