Le 06/02/16 16:54, Kiran Ayyagari a écrit :
> On Sat, Feb 6, 2016 at 2:26 PM, Emmanuel Lécharny <[email protected]>
> wrote:
>
>> Hi guys,
>>
>> I'm trying to do something that is not that specific : on a client tool,
>> load a SchemaManager with all the default schema presents (enabled and
>> disabled), then load a new external schema. And I'm hitting a wall here
>> : there is no simple way to get a schema which is not present in the
>> list of existing schemas being added afterward.
>>
>> This is quite a pain, and I'd like to extend the SchemaManager interface
>> to allow something like : SchemaManager.add( String schemaFile[,
>> SchemaLoader] ).
>>
>> This is not exactly simple, considering the format this schema file will
>> use. We have three kind of supported formats :
>> - ldif : one ldif file per schema element
>> - single ldif : one single ldif file containing all the elements
>> - JAR : a jar file containing a ldif format schema (1 format)
>>
>> the above mentioned differ only in the way of finding the schema file
> after that
> they all parse the LDIF file in the same way

Not exactly true. When you want to load a schema, it will try to check
the dependencis, in order to load the one that are not already loaded :

        for ( String depName : deps )
        {
            if ( registries.isSchemaLoaded( schemaName ) )
            {
                // The schema is already loaded. Loop on the next schema
                continue;
            }
            else
            {
                // Call recursively this method
                Schema schemaDep = schemaLoader.getSchema( depName );
                loadDepsFirst( registries, schemaDep );
            }

and here, we use the SchemaLoader the SchemaManager has been initialized
with. This is where we have a problem.

>
>> When you create a schemaManager, you inject a SchemaLoader into it, and
>> this is used for the lifetime of this SchemaManager. That makes it
>> impossible to use another SchemaLoader than the one that has been used
>> initially. Sadly, we still need the previous SchemaLoader because we
>> don't process all the schemas when we initialize the SchemaManager : the
>> disabled schemas aren't read at all. So we may need it later, if the
>> newly added schema requires a dependency from the old SchemaLoader.
>>
> IMO what we actually need is a way to add new Schemas (as in an instance of
> Schema class)
> to an already instantiated SchemaManager (using whichever loader during
> initialization)

That forces us to use a schema written using teh exact same format that
the initial SchemaLoader is supporting. In my case, the SchemManager is
using the LdifSchemaLoader, and I want to use the SingleLdifSchemaLoader
format. We can imagine other configuration (for instance, loading a
OpenLDAP formatted schema...)

>
>> At this point, I'm a bit stuck with the current API, and even though
>> there are some ways to deal with that, none of the solution is
>> convenient from a User POV, and we are talking about an API here.
>>
>> I think we have all the necessary pieces to get this done with a few
> changes.
>
> One solution is to modify the SingleLdifSchemaLoader(SLSL),
> DefaultSchemaManager and Schema classes.
>
> 1. add a new method, addSchemaObject(SchemaObject so) to DefaultSchema class
>   which when called populates the 'content' field
>
> 2. add a 'schema' field of type DefaultSchema in SLSL
>
> 3. add a new method, getSchema(), in SLSL (I am assuming this for a single
> schema defined in file,
> to support multiple schemas this can return a list)
>
>   a. make getSchema() call various loadXXX() methods
>
>   b. update the loadXXX() methods to create the appropriate SchemaObject
> instances
>     and populate the 'content' field of 'schema'
>
> 4. change the visibility of addSchemaObject() of DefaultSchemaManager to
> public
>
> 5. now, call getSchema() of SLSL and iterate over the 'content' and call
> addSchemaObject()
>
> Now, this is all theory ;) and I think it will work

The SchemaManager does that when it comes to load a Schema :

loadWithDeps( Schema... )
  loadDepsFirst( Registries, Schemas )
    ... (here we load the dependencies, which at the bottom, do the same
thing as what we will see on the next line)
    load( Registries, Schema )
      addSchemaObjects( Schema, Registries )
        addComparators( Schema, Registries ) // Same think for AT, OC, etc
          for ( Entry entry : schemaLoader.loadComparators( schema ) )
          {
            LdapComparator<?> comparator = factory.getLdapComparator(
this, entry, registries, schema.getSchemaName() );

            addSchemaObject( registries, comparator, schema );
          }

As you can see, we use the SchemaManager's declared SchemaLoader, which
is not what we want.

Having each Schema associated with its SchemaLoader would make it
possible to use a different SchemaLoader :

        addComparators( Schema schema, Registries registries ) // Same
think for AT, OC, etc
          for ( Entry entry : schema.getSchemaLoader().loadComparators(
schema ) )
          {
            LdapComparator<?> comparator = factory.getLdapComparator(
this, entry, registries, schema.getSchemaName() );

            addSchemaObject( registries, comparator, schema );
          }

Way simpler than any other change, IMO.
>
>
>> So the solution I will come with is to associate each Schema with its
>> schema loader, instead of associate the SchemaLoader to the
>> SchemaManager. This way, we will be able to have more than one
>> SchemaLoader used by the SchemaManager.
>>
>> IMO a loader should give us a schema rather than a Schema containing a
> loader.

But the SchemaLoader does not know about Schemas. Technically, it's the
other way out.

Thanks Kiran !

Reply via email to