You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by se...@apache.org on 2016/11/09 11:52:45 UTC

svn commit: r1768917 - in /directory/shared/trunk/ldap: client/api/ client/api/src/test/java/org/apache/directory/ldap/client/api/ client/api/src/test/resources/ model/src/main/java/org/apache/directory/api/ldap/model/exception/ model/src/main/java/org...

Author: semancik
Date: Wed Nov  9 11:52:45 2016
New Revision: 1768917

URL: http://svn.apache.org/viewvc?rev=1768917&view=rev
Log:
Test for quirky schema, fixing schema error, making the API more tolerant to undefined syntaxes in schema (in relaxed mode).

Added:
    directory/shared/trunk/ldap/client/api/src/test/java/org/apache/directory/ldap/client/api/QuirkySchemaTest.java
    directory/shared/trunk/ldap/client/api/src/test/resources/schema-minimal.ldif
    directory/shared/trunk/ldap/client/api/src/test/resources/schema-quirky.ldif
Modified:
    directory/shared/trunk/ldap/client/api/pom.xml
    directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/exception/LdapSchemaViolationException.java
    directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/registries/helper/AttributeTypeHelper.java

Modified: directory/shared/trunk/ldap/client/api/pom.xml
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/client/api/pom.xml?rev=1768917&r1=1768916&r2=1768917&view=diff
==============================================================================
--- directory/shared/trunk/ldap/client/api/pom.xml (original)
+++ directory/shared/trunk/ldap/client/api/pom.xml Wed Nov  9 11:52:45 2016
@@ -94,6 +94,11 @@
       <version>1.10.19</version>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-log4j12</artifactId>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
 
   <build>

Added: directory/shared/trunk/ldap/client/api/src/test/java/org/apache/directory/ldap/client/api/QuirkySchemaTest.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/client/api/src/test/java/org/apache/directory/ldap/client/api/QuirkySchemaTest.java?rev=1768917&view=auto
==============================================================================
--- directory/shared/trunk/ldap/client/api/src/test/java/org/apache/directory/ldap/client/api/QuirkySchemaTest.java (added)
+++ directory/shared/trunk/ldap/client/api/src/test/java/org/apache/directory/ldap/client/api/QuirkySchemaTest.java Wed Nov  9 11:52:45 2016
@@ -0,0 +1,663 @@
+/*
+ *  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.ldap.client.api;
+
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.directory.api.asn1.util.Oid;
+import org.apache.directory.api.ldap.codec.api.BinaryAttributeDetector;
+import org.apache.directory.api.ldap.codec.api.LdapApiService;
+import org.apache.directory.api.ldap.model.constants.SchemaConstants;
+import org.apache.directory.api.ldap.model.cursor.EntryCursor;
+import org.apache.directory.api.ldap.model.cursor.SearchCursor;
+import org.apache.directory.api.ldap.model.entry.DefaultEntry;
+import org.apache.directory.api.ldap.model.entry.Entry;
+import org.apache.directory.api.ldap.model.entry.Modification;
+import org.apache.directory.api.ldap.model.entry.ModificationOperation;
+import org.apache.directory.api.ldap.model.entry.Value;
+import org.apache.directory.api.ldap.model.exception.LdapException;
+import org.apache.directory.api.ldap.model.ldif.LdifEntry;
+import org.apache.directory.api.ldap.model.ldif.LdifReader;
+import org.apache.directory.api.ldap.model.message.AbandonRequest;
+import org.apache.directory.api.ldap.model.message.AddRequest;
+import org.apache.directory.api.ldap.model.message.AddResponse;
+import org.apache.directory.api.ldap.model.message.BindRequest;
+import org.apache.directory.api.ldap.model.message.BindResponse;
+import org.apache.directory.api.ldap.model.message.CompareRequest;
+import org.apache.directory.api.ldap.model.message.CompareResponse;
+import org.apache.directory.api.ldap.model.message.Control;
+import org.apache.directory.api.ldap.model.message.DeleteRequest;
+import org.apache.directory.api.ldap.model.message.DeleteResponse;
+import org.apache.directory.api.ldap.model.message.ExtendedRequest;
+import org.apache.directory.api.ldap.model.message.ExtendedResponse;
+import org.apache.directory.api.ldap.model.message.ModifyDnRequest;
+import org.apache.directory.api.ldap.model.message.ModifyDnResponse;
+import org.apache.directory.api.ldap.model.message.ModifyRequest;
+import org.apache.directory.api.ldap.model.message.ModifyResponse;
+import org.apache.directory.api.ldap.model.message.SearchRequest;
+import org.apache.directory.api.ldap.model.message.SearchScope;
+import org.apache.directory.api.ldap.model.name.Dn;
+import org.apache.directory.api.ldap.model.name.Rdn;
+import org.apache.directory.api.ldap.model.schema.ObjectClass;
+import org.apache.directory.api.ldap.model.schema.SchemaManager;
+import org.apache.directory.api.ldap.model.schema.registries.Schema;
+import org.apache.directory.api.ldap.schema.manager.impl.DefaultSchemaManager;
+import org.apache.directory.api.util.exception.Exceptions;
+import org.junit.Test;
+
+
+/**
+ * Tests the DefaultSchemaLoader and DefaultSchemaManager with schema that is full of quirks.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class QuirkySchemaTest
+{
+
+    protected static final String SCHEMA_DN = "cn=schema";
+
+
+    /**
+     * Try to load a very minimal (and correct) schema. It has just 'person' objectclass and all
+     * the necessary attributes, matching rules and syntaxes. Load it in strict mode.
+     * This test is here mostly to make sure that the test itself works.
+     */
+    @Test
+    public void testLoadMinimalSchema() throws Exception
+    {
+        LdapConnection connection = createFakeConnection( "src/test/resources/schema-minimal.ldif" );
+        DefaultSchemaLoader loader = new DefaultSchemaLoader( connection );
+        Collection<Schema> allEnabled = loader.getAllEnabled();
+        assertEquals( 1, allEnabled.size() );
+        Schema schema = allEnabled.iterator().next();
+        assertNotNull( schema );
+        assertEquals( 26, schema.getContent().size() );
+
+        SchemaManager schemaManager = new DefaultSchemaManager( loader );
+
+        boolean loaded = schemaManager.loadAllEnabled();
+
+        if ( !loaded )
+        {
+            fail( "Schema load failed : " + Exceptions.printErrors( schemaManager.getErrors() ) );
+        }
+
+        assertTrue( schemaManager.getRegistries().getAttributeTypeRegistry().contains( "cn" ) );
+        ObjectClass person = schemaManager.getRegistries().getObjectClassRegistry().lookup( "person" );
+        assertNotNull( person );
+        assertEquals( 2, person.getMustAttributeTypes().size() );
+        assertEquals( 4, person.getMayAttributeTypes().size() );
+    }
+    
+    /**
+     * Try to load a quirky schema. This schema has a lot of issues that violate the
+     * standards. Therefore load the schema in relaxed mode. We should be able to work
+     * with this schema anyway. E.g. the loader and schema manager should not die on
+     * null pointer or similar trivial error.
+     */
+    @Test
+    public void testLoadQuirkySchema() throws Exception
+    {
+        LdapConnection connection = createFakeConnection( "src/test/resources/schema-quirky.ldif" );
+        DefaultSchemaLoader loader = new DefaultSchemaLoader( connection, true );
+        Collection<Schema> allEnabled = loader.getAllEnabled();
+        assertEquals( 1, allEnabled.size() );
+        Schema schema = allEnabled.iterator().next();
+        assertNotNull( schema );
+//        assertEquals( 26, schema.getContent().size() );
+
+        SchemaManager schemaManager = new DefaultSchemaManager( loader );
+
+        boolean loaded = schemaManager.loadAllEnabledRelaxed();
+        
+        if ( !loaded )
+        {
+            fail( "Schema load failed : " + Exceptions.printErrors( schemaManager.getErrors() ) );
+        }
+        
+        assertTrue ( "Surprisingly no errors after load", schemaManager.getErrors().size() > 0 );
+
+        assertTrue( schemaManager.getRegistries().getAttributeTypeRegistry().contains( "cn" ) );
+        ObjectClass person = schemaManager.getRegistries().getObjectClassRegistry().lookup( "person" );
+        assertNotNull( person );
+        assertEquals( 2, person.getMustAttributeTypes().size() );
+        assertEquals( 5, person.getMayAttributeTypes().size() );
+    }
+
+
+    private LdapConnection createFakeConnection( final String schemaFileName )
+    {
+        return new LdapConnection()
+        {
+            
+            @Override
+            public void unBind() throws LdapException
+            {
+            }
+            
+            
+            @Override
+            public void setTimeOut( long timeOut )
+            {
+            }
+            
+            
+            @Override
+            public void setSchemaManager( SchemaManager schemaManager )
+            {
+            }
+            
+            
+            @Override
+            public void setBinaryAttributeDetector( BinaryAttributeDetector binaryAttributeDetecter )
+            {
+            }
+            
+            
+            @Override
+            public SearchCursor search( SearchRequest searchRequest ) throws LdapException
+            {
+                return null;
+            }
+            
+            
+            @Override
+            public EntryCursor search( String baseDn, String filter, SearchScope scope, String... attributes )
+                throws LdapException
+            {
+                return null;
+            }
+            
+            
+            @Override
+            public EntryCursor search( Dn baseDn, String filter, SearchScope scope, String... attributes ) throws LdapException
+            {
+                return null;
+            }
+            
+            
+            @Override
+            public void rename( Dn entryDn, Rdn newRdn, boolean deleteOldRdn ) throws LdapException
+            {
+            }
+            
+            
+            @Override
+            public void rename( String entryDn, String newRdn, boolean deleteOldRdn ) throws LdapException
+            {
+            }
+            
+            
+            @Override
+            public void rename( Dn entryDn, Rdn newRdn ) throws LdapException
+            {
+            }
+            
+            
+            @Override
+            public void rename( String entryDn, String newRdn ) throws LdapException
+            {
+            }
+            
+            
+            @Override
+            public void moveAndRename( String entryDn, String newDn, boolean deleteOldRdn ) throws LdapException
+            {
+            }
+            
+            
+            @Override
+            public void moveAndRename( Dn entryDn, Dn newDn, boolean deleteOldRdn ) throws LdapException
+            {
+            }
+            
+            
+            @Override
+            public void moveAndRename( String entryDn, String newDn ) throws LdapException
+            {
+            }
+            
+            
+            @Override
+            public void moveAndRename( Dn entryDn, Dn newDn ) throws LdapException
+            {
+            }
+            
+            
+            @Override
+            public void move( Dn entryDn, Dn newSuperiorDn ) throws LdapException
+            {
+            }
+            
+            
+            @Override
+            public void move( String entryDn, String newSuperiorDn ) throws LdapException
+            {
+            }
+            
+            
+            @Override
+            public ModifyDnResponse modifyDn( ModifyDnRequest modDnRequest ) throws LdapException
+            {
+                return null;
+            }
+            
+            
+            @Override
+            public ModifyResponse modify( ModifyRequest modRequest ) throws LdapException
+            {
+                return null;
+            }
+            
+            
+            @Override
+            public void modify( Entry entry, ModificationOperation modOp ) throws LdapException
+            {
+            }
+            
+            
+            @Override
+            public void modify( String dn, Modification... modifications ) throws LdapException
+            {
+            }
+            
+            
+            @Override
+            public void modify( Dn dn, Modification... modifications ) throws LdapException
+            {
+            }
+            
+            
+            @Override
+            public Entry lookup( String dn, Control[] controls, String... attributes ) throws LdapException
+            {
+            	return lookup(new Dn(dn));
+            }
+            
+            
+            @Override
+            public Entry lookup( String dn, String... attributes ) throws LdapException
+            {
+            	return lookup(new Dn(dn));
+            }
+            
+            
+            @Override
+            public Entry lookup( Dn dn, Control[] controls, String... attributes ) throws LdapException
+            {
+            	return lookup(dn);
+            }
+            
+            
+            @Override
+            public Entry lookup( Dn dn, String... attributes ) throws LdapException
+            {
+            	return lookup(dn);
+            }
+            
+            
+            @Override
+            public Entry lookup( String dn ) throws LdapException
+            {
+                return lookup(new Dn(dn));
+            }
+            
+            
+            @Override
+            public Entry lookup( Dn dn ) throws LdapException
+            {
+            	if (dn.isRootDse()) {
+            		Entry entry = new DefaultEntry( dn );
+            		entry.add( SchemaConstants.SUBSCHEMA_SUBENTRY_AT, SCHEMA_DN );
+            		return entry;
+            	} else if (dn.toString().equals( SCHEMA_DN )) {
+            		Entry entry = loadSchemaEntry( schemaFileName );
+            		return entry;
+            	} else {
+            		throw new UnsupportedOperationException("Unexpected DN "+dn);
+            	}
+            }
+
+
+            @Override
+            public void loadSchemaRelaxed() throws LdapException
+            {
+            }
+            
+            
+            @Override
+            public void loadSchema() throws LdapException
+            {
+            }
+            
+            
+            @Override
+            public boolean isRequestCompleted( int messageId )
+            {
+                return true;
+            }
+            
+            
+            @Override
+            public boolean isControlSupported( String controlOID ) throws LdapException
+            {
+                return true;
+            }
+            
+            
+            @Override
+            public boolean isConnected()
+            {
+                return true;
+            }
+            
+            
+            @Override
+            public boolean isAuthenticated()
+            {
+                return false;
+            }
+            
+            
+            @Override
+            public List<String> getSupportedControls() throws LdapException
+            {
+                return null;
+            }
+            
+            
+            @Override
+            public SchemaManager getSchemaManager()
+            {
+                return null;
+            }
+            
+            
+            @Override
+            public Entry getRootDse( String... attributes ) throws LdapException
+            {
+                return lookup( Dn.ROOT_DSE );
+            }
+            
+            
+            @Override
+            public Entry getRootDse() throws LdapException
+            {
+                return lookup( Dn.ROOT_DSE );
+            }
+            
+            
+            @Override
+            public LdapApiService getCodecService()
+            {
+                return null;
+            }
+            
+            
+            @Override
+            public BinaryAttributeDetector getBinaryAttributeDetector()
+            {
+                return null;
+            }
+            
+            
+            @Override
+            public ExtendedResponse extended( ExtendedRequest extendedRequest ) throws LdapException
+            {
+                return null;
+            }
+            
+            
+            @Override
+            public ExtendedResponse extended( Oid oid, byte[] value ) throws LdapException
+            {
+                return null;
+            }
+            
+            
+            @Override
+            public ExtendedResponse extended( Oid oid ) throws LdapException
+            {
+                return null;
+            }
+            
+            
+            @Override
+            public ExtendedResponse extended( String oid, byte[] value ) throws LdapException
+            {
+                return null;
+            }
+            
+            
+            @Override
+            public ExtendedResponse extended( String oid ) throws LdapException
+            {
+                return null;
+            }
+            
+            
+            @Override
+            public boolean exists( Dn dn ) throws LdapException
+            {
+                return false;
+            }
+            
+            
+            @Override
+            public boolean exists( String dn ) throws LdapException
+            {
+                return false;
+            }
+            
+            
+            @Override
+            public boolean doesFutureExistFor( int messageId )
+            {
+                return false;
+            }
+            
+            
+            @Override
+            public DeleteResponse delete( DeleteRequest deleteRequest ) throws LdapException
+            {
+                return null;
+            }
+            
+            
+            @Override
+            public void delete( Dn dn ) throws LdapException
+            {
+            }
+            
+            
+            @Override
+            public void delete( String dn ) throws LdapException
+            {
+            }
+            
+            
+            @Override
+            public boolean connect() throws LdapException
+            {
+                return true;
+            }
+            
+            
+            @Override
+            public CompareResponse compare( CompareRequest compareRequest ) throws LdapException
+            {
+                return null;
+            }
+            
+            
+            @Override
+            public boolean compare( Dn dn, String attributeName, Value<?> value ) throws LdapException
+            {
+                return false;
+            }
+            
+            
+            @Override
+            public boolean compare( Dn dn, String attributeName, byte[] value ) throws LdapException
+            {
+                return false;
+            }
+            
+            
+            @Override
+            public boolean compare( Dn dn, String attributeName, String value ) throws LdapException
+            {
+                return false;
+            }
+            
+            
+            @Override
+            public boolean compare( String dn, String attributeName, Value<?> value ) throws LdapException
+            {
+                return false;
+            }
+            
+            
+            @Override
+            public boolean compare( String dn, String attributeName, byte[] value ) throws LdapException
+            {
+                return false;
+            }
+            
+            
+            @Override
+            public boolean compare( String dn, String attributeName, String value ) throws LdapException
+            {
+                return false;
+            }
+            
+            
+            @Override
+            public void close() throws IOException
+            {                
+            }
+            
+            
+            @Override
+            public BindResponse bind( BindRequest bindRequest ) throws LdapException
+            {
+                return null;
+            }
+            
+            
+            @Override
+            public void bind( Dn name, String credentials ) throws LdapException
+            {
+            }
+            
+            
+            @Override
+            public void bind( Dn name ) throws LdapException
+            {
+            }
+            
+            
+            @Override
+            public void bind( String name, String credentials ) throws LdapException
+            {
+            }
+            
+            
+            @Override
+            public void bind( String name ) throws LdapException
+            {
+            }
+            
+            
+            @Override
+            public void bind() throws LdapException
+            {
+            }
+            
+            
+            @Override
+            public void anonymousBind() throws LdapException
+            {
+            }
+            
+            
+            @Override
+            public AddResponse add( AddRequest addRequest ) throws LdapException
+            {
+                return null;
+            }
+            
+            
+            @Override
+            public void add( Entry entry ) throws LdapException
+            {
+            }
+            
+            
+            @Override
+            public void abandon( AbandonRequest abandonRequest )
+            {
+            }
+            
+            
+            @Override
+            public void abandon( int messageId )
+            {
+            }
+        };
+    }
+    
+    private Entry loadSchemaEntry( String schemaFileName )
+    {
+    	LdifEntry ldifEntry = null;
+    	try
+        {
+        	InputStream in = new FileInputStream( schemaFileName );
+        	LdifReader ldifReader = new LdifReader( in );
+            if (ldifReader.hasNext()) 
+            {
+            	ldifEntry = ldifReader.next();
+            }
+        
+            ldifReader.close();
+        }
+        catch ( IOException e )
+        {
+            throw new IllegalStateException( "IO error with " + schemaFileName , e );
+        }
+    	catch (LdapException e ) {
+    		throw new IllegalStateException( "LDAP error with " + schemaFileName , e );
+    	}
+        if (ldifEntry == null) {
+        	throw new IllegalStateException( "No entry in LDIF " + schemaFileName );
+        }
+        return ldifEntry.getEntry();
+    }
+}

Added: directory/shared/trunk/ldap/client/api/src/test/resources/schema-minimal.ldif
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/client/api/src/test/resources/schema-minimal.ldif?rev=1768917&view=auto
==============================================================================
--- directory/shared/trunk/ldap/client/api/src/test/resources/schema-minimal.ldif (added)
+++ directory/shared/trunk/ldap/client/api/src/test/resources/schema-minimal.ldif Wed Nov  9 11:52:45 2016
@@ -0,0 +1,57 @@
+# Minimal correct schema
+dn: cn=schema
+objectClass: top
+objectClass: subentry
+objectClass: subschema
+cn: schema
+ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'Distinguished Name' )
+ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'Directory String' )
+ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5 String' )
+ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )
+ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'Octet String' )
+ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'Telephone Number' )
+ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.58 DESC 'Substring Assertion' )
+matchingRules: ( 1.3.6.1.4.1.4203.1.2.1 NAME 'caseExactIA5SubstringsMatch' SYN
+ TAX 1.3.6.1.4.1.1466.115.121.1.26 )
+matchingRules: ( 2.5.13.0 NAME 'objectIdentifierMatch' SYNTAX 1.3.6.1.4.1.1466
+ .115.121.1.38 )
+matchingRules: ( 2.5.13.1 NAME 'distinguishedNameMatch' SYNTAX 1.3.6.1.4.1.146
+ 6.115.121.1.12 )
+matchingRules: ( 2.5.13.2 NAME 'caseIgnoreMatch' SYNTAX 1.3.6.1.4.1.1466.115.1
+ 21.1.15 )
+matchingRules: ( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' SYNTAX 1.3.6.1.4.1.
+ 1466.115.121.1.58 )
+matchingRules: ( 2.5.13.17 NAME 'octetStringMatch' SYNTAX 1.3.6.1.4.1.1466.115
+ .121.1.40 )
+matchingRules: ( 2.5.13.20 NAME 'telephoneNumberMatch' SYNTAX 1.3.6.1.4.1.1466
+ .115.121.1.50 )
+matchingRules: ( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' SYNTAX 1.3.6.
+ 1.4.1.1466.115.121.1.58 )
+attributeTypes: ( 2.5.4.0 NAME 'objectClass' DESC 'RFC4512: object classes of 
+ the entity' EQUALITY objectIdentifierMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.
+ 38 )
+attributeTypes: ( 2.5.4.13 NAME 'description' DESC 'RFC4519: descriptive infor
+ mation' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.
+ 6.1.4.1.1466.115.121.1.15{1024} )
+attributeTypes: ( 2.5.4.20 NAME 'telephoneNumber' DESC 'RFC2256: Telephone Num
+ ber' EQUALITY telephoneNumberMatch SUBSTR telephoneNumberSubstringsMatch SYNT
+ AX 1.3.6.1.4.1.1466.115.121.1.50{32} )
+attributeTypes: ( 2.5.4.41 NAME 'name' DESC 'RFC4519: common supertype of name
+  attributes' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX
+  1.3.6.1.4.1.1466.115.121.1.15{32768} )
+attributeTypes: ( 2.5.4.49 NAME 'distinguishedName' DESC 'RFC4519: common supe
+ rtype of DN attributes' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.14
+ 66.115.121.1.12 )
+attributeTypes: ( 2.5.4.3 NAME ( 'cn' 'commonName' ) DESC 'RFC4519: common nam
+ e(s) for which the entity is known by' SUP name )
+attributeTypes: ( 2.5.4.4 NAME ( 'sn' 'surname' ) DESC 'RFC2256: last (family)
+  name(s) for which the entity is known by' SUP name )
+attributeTypes: ( 2.5.4.34 NAME 'seeAlso' DESC 'RFC4519: DN of related object'
+  SUP distinguishedName )
+attributeTypes: ( 2.5.4.35 NAME 'userPassword' DESC 'RFC4519/2307: password of
+  user' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{128} )
+objectClasses: ( 2.5.6.0 NAME 'top' DESC 'top of the superclass chain' ABSTRAC
+ T MUST objectClass )
+objectClasses: ( 2.5.6.6 NAME 'person' DESC 'RFC2256: a person' SUP top STRUCT
+ URAL MUST ( sn $ cn ) MAY ( userPassword $ telephoneNumber $ seeAlso $ descri
+ ption ) )

Added: directory/shared/trunk/ldap/client/api/src/test/resources/schema-quirky.ldif
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/client/api/src/test/resources/schema-quirky.ldif?rev=1768917&view=auto
==============================================================================
--- directory/shared/trunk/ldap/client/api/src/test/resources/schema-quirky.ldif (added)
+++ directory/shared/trunk/ldap/client/api/src/test/resources/schema-quirky.ldif Wed Nov  9 11:52:45 2016
@@ -0,0 +1,59 @@
+# Quirky schema. There are a lot of issues with the schema. It is not
+# standard-compliant.
+dn: cn=schema
+objectClass: top
+objectClass: subentry
+objectClass: subschema
+cn: schema
+ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'Distinguished Name' )
+ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'Directory String' )
+ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5 String' )
+ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'Telephone Number' )
+# We do not have syntax 1.3.6.1.4.1.1466.115.121.1.38, 40 and 58 
+matchingRules: ( 1.3.6.1.4.1.4203.1.2.1 NAME 'caseExactIA5SubstringsMatch' SYN
+ TAX 1.3.6.1.4.1.1466.115.121.1.26 )
+matchingRules: ( 2.5.13.0 NAME 'objectIdentifierMatch' SYNTAX 1.3.6.1.4.1.1466
+ .115.121.1.38 )
+matchingRules: ( 2.5.13.1 NAME 'distinguishedNameMatch' SYNTAX 1.3.6.1.4.1.146
+ 6.115.121.1.12 )
+matchingRules: ( 2.5.13.2 NAME 'caseIgnoreMatch' SYNTAX 1.3.6.1.4.1.1466.115.1
+ 21.1.15 )
+matchingRules: ( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' SYNTAX 1.3.6.1.4.1.
+ 1466.115.121.1.58 )
+matchingRules: ( 2.5.13.17 NAME 'octetStringMatch' SYNTAX 1.3.6.1.4.1.1466.115
+ .121.1.40 )
+matchingRules: ( 2.5.13.20 NAME 'telephoneNumberMatch' SYNTAX 1.3.6.1.4.1.1466
+ .115.121.1.50 )
+ # No definition for telephoneNumberSubstringsMatch (2.5.13.21)
+attributeTypes: ( 2.5.4.0 NAME 'objectClass' DESC 'RFC4512: object classes of 
+ the entity' EQUALITY objectIdentifierMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.
+ 38 )
+ # No definition for 'description' attribute (2.5.4.13)
+attributeTypes: ( 2.5.4.20 NAME 'telephoneNumber' DESC 'RFC2256: Telephone Num
+ ber' EQUALITY telephoneNumberMatch SUBSTR telephoneNumberSubstringsMatch SYNT
+ AX 1.3.6.1.4.1.1466.115.121.1.50{32} )
+attributeTypes: ( 2.5.4.41 NAME 'name' DESC 'RFC4519: common supertype of name
+  attributes' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX
+  1.3.6.1.4.1.1466.115.121.1.15{32768} )
+attributeTypes: ( 2.5.4.49 NAME 'distinguishedName' DESC 'RFC4519: common supe
+ rtype of DN attributes' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.14
+ 66.115.121.1.12 )
+attributeTypes: ( 2.5.4.3 NAME ( 'cn' 'commonName' ) DESC 'RFC4519: common nam
+ e(s) for which the entity is known by' SUP name )
+# 'sn' definition has no syntax
+attributeTypes: ( 2.5.4.4 NAME 'sn' )
+attributeTypes: ( 2.5.4.34 NAME 'seeAlso' DESC 'RFC4519: DN of related object'
+  SUP distinguishedName )
+# userPassword has matching rule, but it does not have syntax
+attributeTypes: ( 2.5.4.35 NAME 'userPassword' DESC 'RFC4519/2307: password of
+  user' EQUALITY octetStringMatch )
+objectClasses: ( 2.5.6.0 NAME 'top' DESC 'top of the superclass chain' ABSTRAC
+ T MUST objectClass )
+# subSn is a subtype of sn which does not have a syntax OID
+attributeTypes: ( 1.3.6.1.4.1.45689.1.4.300.1 NAME 'subSn' SUP sn )
+# subPassword is a subtype of userPassword which does has syntax OID, but has no
+# syntax definition
+attributeTypes: ( 1.3.6.1.4.1.45689.1.4.300.2 NAME 'subPassword' SUP userPassword )
+objectClasses: ( 2.5.6.6 NAME 'person' DESC 'RFC2256: a person' SUP top STRUCT
+ URAL MUST ( sn $ cn ) MAY ( userPassword $ telephoneNumber $ seeAlso $ descri
+ ption $ subSn $ subPassword ) )

Modified: directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/exception/LdapSchemaViolationException.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/exception/LdapSchemaViolationException.java?rev=1768917&r1=1768916&r2=1768917&view=diff
==============================================================================
--- directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/exception/LdapSchemaViolationException.java (original)
+++ directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/exception/LdapSchemaViolationException.java Wed Nov  9 11:52:45 2016
@@ -94,6 +94,7 @@ public class LdapSchemaViolationExceptio
             case OBJECT_CLASS_VIOLATION:
             case NOT_ALLOWED_ON_RDN:
             case OBJECT_CLASS_MODS_PROHIBITED:
+            case INVALID_ATTRIBUTE_SYNTAX: // may happen during schema processing
                 return;
 
             default:

Modified: directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/registries/helper/AttributeTypeHelper.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/registries/helper/AttributeTypeHelper.java?rev=1768917&r1=1768916&r2=1768917&view=diff
==============================================================================
--- directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/registries/helper/AttributeTypeHelper.java (original)
+++ directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/registries/helper/AttributeTypeHelper.java Wed Nov  9 11:52:45 2016
@@ -329,7 +329,23 @@ public final class AttributeTypeHelper
             // We inherit from the superior's syntax, if any
             if ( attributeType.getSuperior() != null )
             {
-                attributeType.setSyntax( attributeType.getSuperior().getSyntax() );
+                if ( attributeType.getSuperior().getSyntax() != null )
+                {
+                    attributeType.setSyntax( attributeType.getSuperior().getSyntax() );
+                }
+                else
+                {
+                    String msg = I18n.err( I18n.ERR_04306, syntaxOid, attributeType.getName() );
+
+                    LdapSchemaException ldapSchemaException = new LdapSchemaException(
+                        LdapSchemaExceptionCodes.AT_NONEXISTENT_SYNTAX, msg );
+                    ldapSchemaException.setSourceObject( attributeType );
+                    ldapSchemaException.setRelatedId( syntaxOid );
+                    errors.add( ldapSchemaException );
+                    LOG.info( msg );
+                    
+                    return;
+                }
             }
             else
             {