blob: 063ccc6be895411fedebdbff5a482aa2b60b4ae2 [file] [log] [blame]
/*
* 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.server.core.schema;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.Stack;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.SearchResult;
import org.apache.directory.server.constants.MetaSchemaConstants;
import org.apache.directory.server.core.interceptor.context.EntryOperationContext;
import org.apache.directory.server.core.interceptor.context.ListOperationContext;
import org.apache.directory.server.core.interceptor.context.LookupOperationContext;
import org.apache.directory.server.core.partition.Partition;
import org.apache.directory.server.schema.bootstrap.Schema;
import org.apache.directory.server.schema.registries.AbstractSchemaLoader;
import org.apache.directory.server.schema.registries.AttributeTypeRegistry;
import org.apache.directory.server.schema.registries.Registries;
import org.apache.directory.server.schema.registries.SchemaLoader;
import org.apache.directory.shared.ldap.constants.SchemaConstants;
import org.apache.directory.shared.ldap.name.LdapDN;
import org.apache.directory.shared.ldap.schema.AttributeType;
import org.apache.directory.shared.ldap.schema.Normalizer;
import org.apache.directory.shared.ldap.schema.ObjectClass;
import org.apache.directory.shared.ldap.schema.Syntax;
import org.apache.directory.shared.ldap.schema.MatchingRule;
import org.apache.directory.shared.ldap.schema.syntax.ComparatorDescription;
import org.apache.directory.shared.ldap.schema.syntax.NormalizerDescription;
import org.apache.directory.shared.ldap.schema.syntax.SyntaxChecker;
import org.apache.directory.shared.ldap.schema.syntax.SyntaxCheckerDescription;
import org.apache.directory.shared.ldap.util.AttributeUtils;
import org.apache.directory.shared.ldap.util.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* A class that loads schemas from a partition.
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
* @version $Rev$
*/
public class PartitionSchemaLoader extends AbstractSchemaLoader
{
/** static class logger */
private final static Logger log = LoggerFactory.getLogger( PartitionSchemaLoader.class );
private final SchemaPartitionDao dao;
private SchemaEntityFactory factory;
private Partition partition;
private AttributeTypeRegistry attrRegistry;
private final AttributeType mOidAT;
private final AttributeType mNameAT;
private final AttributeType cnAT;
private final AttributeType byteCodeAT;
private final AttributeType descAT;
private final AttributeType fqcnAT;
private static Map<String, LdapDN> staticAttributeTypeDNs = new HashMap<String, LdapDN>();
private static Map<String, LdapDN> staticMatchingRulesDNs = new HashMap<String, LdapDN>();
private static Map<String, LdapDN> staticObjectClassesDNs = new HashMap<String, LdapDN>();
private static Map<String, LdapDN> staticComparatorsDNs = new HashMap<String, LdapDN>();
private static Map<String, LdapDN> staticNormalizersDNs = new HashMap<String, LdapDN>();
private static Map<String, LdapDN> staticSyntaxCheckersDNs = new HashMap<String, LdapDN>();
private static Map<String, LdapDN> staticSyntaxesDNs = new HashMap<String, LdapDN>();
public PartitionSchemaLoader( Partition partition, Registries bootstrapRegistries ) throws NamingException
{
this.factory = new SchemaEntityFactory( bootstrapRegistries );
this.partition = partition;
this.attrRegistry = bootstrapRegistries.getAttributeTypeRegistry();
this.dao = new SchemaPartitionDao( this.partition, bootstrapRegistries );
this.mOidAT = bootstrapRegistries.getAttributeTypeRegistry().lookup( MetaSchemaConstants.M_OID_AT );
this.mNameAT = bootstrapRegistries.getAttributeTypeRegistry().lookup( MetaSchemaConstants.M_NAME_AT );
this.cnAT = bootstrapRegistries.getAttributeTypeRegistry().lookup( SchemaConstants.CN_AT );
this.byteCodeAT = bootstrapRegistries.getAttributeTypeRegistry().lookup( MetaSchemaConstants.M_BYTECODE_AT );
this.descAT = bootstrapRegistries.getAttributeTypeRegistry().lookup( MetaSchemaConstants.M_DESCRIPTION_AT );
this.fqcnAT = bootstrapRegistries.getAttributeTypeRegistry().lookup( MetaSchemaConstants.M_FQCN_AT );
initStaticDNs( "system" );
initStaticDNs( "core" );
initStaticDNs( "apache" );
initStaticDNs( "apachemeta" );
initStaticDNs( "other" );
initStaticDNs( "collective" );
initStaticDNs( "java" );
initStaticDNs( "cosine" );
initStaticDNs( "inetorgperson" );
}
private void initStaticDNs( String schemaName ) throws NamingException
{
// Initialize AttributeType Dns
LdapDN dn = new LdapDN( "ou=attributeTypes,cn=" + schemaName + ",ou=schema" );
dn.normalize( this.attrRegistry.getNormalizerMapping() );
staticAttributeTypeDNs.put( schemaName, dn );
// Initialize ObjectClasses Dns
dn = new LdapDN( "ou=objectClasses,cn=" + schemaName + ",ou=schema" );
dn.normalize( this.attrRegistry.getNormalizerMapping() );
staticObjectClassesDNs.put( schemaName, dn );
// Initialize MatchingRules Dns
dn = new LdapDN( "ou=matchingRules,cn=" + schemaName + ",ou=schema" );
dn.normalize( this.attrRegistry.getNormalizerMapping() );
staticMatchingRulesDNs.put( schemaName, dn );
// Initialize Comparators Dns
dn = new LdapDN( "ou=comparators,cn=" + schemaName + ",ou=schema" );
dn.normalize( this.attrRegistry.getNormalizerMapping() );
staticComparatorsDNs.put( schemaName, dn );
// Initialize Normalizers Dns
dn = new LdapDN( "ou=normalizers,cn=" + schemaName + ",ou=schema" );
dn.normalize( this.attrRegistry.getNormalizerMapping() );
staticNormalizersDNs.put( schemaName, dn );
// Initialize SyntaxCheckers Dns
dn = new LdapDN( "ou=syntaxCheckers,cn=" + schemaName + ",ou=schema" );
dn.normalize( this.attrRegistry.getNormalizerMapping() );
staticSyntaxCheckersDNs.put( schemaName, dn );
// Initialize Syntaxes Dns
dn = new LdapDN( "ou=syntaxes,cn=" + schemaName + ",ou=schema" );
dn.normalize( this.attrRegistry.getNormalizerMapping() );
staticSyntaxesDNs.put( schemaName, dn );
}
/**
* Utility method to load all enabled schemas into this registry.
*
* @param targetRegistries
* @throws NamingException
*/
public void loadEnabled( Registries targetRegistries ) throws NamingException
{
/*
* We need to load all names and oids into the oid registry regardless of
* the entity being in an enabled schema. This is necessary because we
* search for values in the schema partition that represent matchingRules
* and other entities that are not loaded. While searching these values
* in disabled schemas normalizers will attempt to equate names with oids
* and if there is an unrecognized value by a normalizer then the search
* will fail.
*
* For example there is a NameOrNumericOidNormalizer that will reduce a
* numeric OID or a non-numeric OID to it's numeric form using the OID
* registry. While searching the schema partition for attributeTypes we
* might find values of matchingRules in the m-ordering, m-equality, and
* m-substr attributes of metaAttributeType definitions. Now if an entry
* references a matchingRule that has not been loaded then the
* NameOrNumericOidNormalizer will bomb out when it tries to resolve
* names of matchingRules in unloaded schemas to OID values using the
* OID registry. To prevent this we need to load all the OID's in advance
* regardless of whether they are used or not.
*/
NamingEnumeration ne = dao.listAllNames();
while ( ne.hasMore() )
{
Attributes attrs = ( ( SearchResult ) ne.next() ).getAttributes();
String oid = ( String ) AttributeUtils.getAttribute( attrs, mOidAT ).get();
Attribute names = AttributeUtils.getAttribute( attrs, mNameAT );
targetRegistries.getOidRegistry().register( oid, oid );
for ( int ii = 0; ii < names.size(); ii++ )
{
targetRegistries.getOidRegistry().register( ( String ) names.get( ii ), oid );
}
}
ne.close();
Map<String, Schema> allSchemaMap = getSchemas();
Set<Schema> enabledSchemaSet = new HashSet<Schema>();
for ( Schema schema: allSchemaMap.values() )
{
if ( ! schema.isDisabled() )
{
log.debug( "will attempt to load enabled schema: {}", schema.getSchemaName() );
enabledSchemaSet.add( schema );
}
else
{
log.debug( "will NOT attempt to load disabled schema: {}", schema.getSchemaName() );
}
}
loadWithDependencies( enabledSchemaSet, targetRegistries );
}
/**
* Lists the names of the schemas that depend on the schema name provided.
*
* @param schemaName the name of the schema to find dependents for
* @return a set of schemas (String names) that depend on the schema
* @throws NamingException if there are problems searching the schema partition
*/
public Set<String> listDependentSchemaNames( String schemaName ) throws NamingException
{
Set<String> dependees = new HashSet<String>();
Set<SearchResult> results = dao.listSchemaDependents( schemaName );
if ( results.isEmpty() )
{
return dependees;
}
for ( SearchResult sr: results )
{
Attribute cn = AttributeUtils.getAttribute( sr.getAttributes(), cnAT );
dependees.add( ( String ) cn.get() );
}
return dependees;
}
/**
* Lists the names of the enabled schemas that depend on the schema name
* provided.
*
* @param schemaName the name of the schema to find dependents for
* @return a set of enabled schemas (String names) that depend on the schema
* @throws NamingException if there are problems searching the schema partition
*/
public Set<String> listEnabledDependentSchemaNames( String schemaName ) throws NamingException
{
Set<String> dependees = new HashSet<String>();
Set<SearchResult> results = dao.listEnabledSchemaDependents( schemaName );
if ( results.isEmpty() )
{
return dependees;
}
for ( SearchResult sr: results )
{
Attribute cn = AttributeUtils.getAttribute( sr.getAttributes(), cnAT );
dependees.add( ( String ) cn.get() );
}
return dependees;
}
public Map<String,Schema> getSchemas() throws NamingException
{
return dao.getSchemas();
}
public Set<String> getSchemaNames() throws NamingException
{
return dao.getSchemaNames();
}
public Schema getSchema( String schemaName ) throws NamingException
{
return dao.getSchema( schemaName );
}
public Schema getSchema( String schemaName, Properties schemaProperties ) throws NamingException
{
return getSchema( schemaName );
}
public final void loadWithDependencies( Collection<Schema> schemas, Registries targetRegistries ) throws NamingException
{
HashMap<String,Schema> notLoaded = new HashMap<String,Schema>();
Iterator<Schema> list = schemas.iterator();
while ( list.hasNext() )
{
Schema schema = list.next();
notLoaded.put( schema.getSchemaName(), schema );
}
list = notLoaded.values().iterator();
while ( list.hasNext() )
{
Schema schema = ( Schema ) list.next();
loadDepsFirst( schema, new Stack<String>(), notLoaded, schema, targetRegistries, null );
list = notLoaded.values().iterator();
}
}
/**
* {@link SchemaLoader#load(Schema, Registries, boolean)}
*/
public final void load( Schema schema, Registries targetRegistries, boolean isDepLoad ) throws NamingException
{
// if we're loading a dependency and it has not been enabled on
// disk then enable it on disk before we proceed to load it
if ( schema.isDisabled() && isDepLoad )
{
dao.enableSchema( schema.getSchemaName() );
}
if ( targetRegistries.getLoadedSchemas().containsKey( schema.getSchemaName() ) )
{
log.debug( "schema {} already seems to be loaded", schema.getSchemaName() );
return;
}
log.debug( "loading {} schema ...", schema.getSchemaName() );
loadComparators( schema, targetRegistries );
loadNormalizers( schema, targetRegistries );
loadSyntaxCheckers( schema, targetRegistries );
loadSyntaxes( schema, targetRegistries );
loadMatchingRules( schema, targetRegistries );
loadAttributeTypes( schema, targetRegistries );
loadObjectClasses( schema, targetRegistries );
loadMatchingRuleUses( schema, targetRegistries );
loadDitContentRules( schema, targetRegistries );
loadNameForms( schema, targetRegistries );
// order does matter here so some special trickery is needed
// we cannot load a DSR before the DSRs it depends on are loaded?
// TODO need ot confirm this ( or we must make the class for this and use deferred
// resolution until everything is available?
loadDitStructureRules( schema, targetRegistries );
notifyListenerOrRegistries( schema, targetRegistries );
}
private void loadMatchingRuleUses( Schema schema, Registries targetRegistries )
{
// TODO Auto-generated method stub
}
private void loadDitStructureRules( Schema schema, Registries targetRegistries ) throws NamingException
{
// TODO Auto-generated method stub
}
private void loadNameForms( Schema schema, Registries targetRegistries ) throws NamingException
{
// TODO Auto-generated method stub
}
private void loadDitContentRules( Schema schema, Registries targetRegistries ) throws NamingException
{
// TODO Auto-generated method stub
}
private void loadObjectClasses( Schema schema, Registries targetRegistries ) throws NamingException
{
/**
* Sometimes search may return child objectClasses before their superiors have
* been registered like with attributeTypes. To prevent this from bombing out
* the loader we will defer the registration of elements until later.
*/
LinkedList<ObjectClass> deferred = new LinkedList<ObjectClass>();
LdapDN dn = staticObjectClassesDNs.get( schema.getSchemaName() );
if ( dn == null )
{
dn = new LdapDN( "ou=objectClasses,cn=" + schema.getSchemaName() + ",ou=schema" );
dn.normalize( this.attrRegistry.getNormalizerMapping() );
staticObjectClassesDNs.put( schema.getSchemaName(), dn );
}
if ( ! partition.hasEntry( new EntryOperationContext( dn ) ) )
{
return;
}
log.debug( "{} schema: loading objectClasses", schema.getSchemaName() );
NamingEnumeration list = partition.list( new ListOperationContext( dn ) );
while ( list.hasMore() )
{
SearchResult result = ( SearchResult ) list.next();
LdapDN resultDN = new LdapDN( result.getName() );
resultDN.normalize( attrRegistry.getNormalizerMapping() );
Attributes attrs = partition.lookup( new LookupOperationContext( resultDN ) );
ObjectClass oc = factory.getObjectClass( attrs, targetRegistries, schema.getSchemaName() );
try
{
targetRegistries.getObjectClassRegistry().register( oc );
}
catch ( NamingException ne )
{
deferred.add( oc );
}
}
log.debug( "Deferred queue size = {}", deferred.size() );
if ( log.isDebugEnabled() )
{
StringBuffer buf = new StringBuffer();
buf.append( "Deferred queue contains: " );
for ( ObjectClass extra : deferred )
{
buf.append( extra.getName() );
buf.append( '[' );
buf.append( extra.getOid() );
buf.append( "]" );
buf.append( "\n" );
}
}
int lastCount = deferred.size();
while ( ! deferred.isEmpty() )
{
log.debug( "Deferred queue size = {}", deferred.size() );
ObjectClass oc = deferred.removeFirst();
NamingException lastException = null;
try
{
targetRegistries.getObjectClassRegistry().register( oc );
}
catch ( NamingException ne )
{
deferred.addLast( oc );
lastException = ne;
}
// if we shrank the deferred list we're doing good and can continue
if ( deferred.size() < lastCount )
{
lastCount = deferred.size();
}
else
{
StringBuffer buf = new StringBuffer();
buf.append( "A cycle must exist somewhere within the objectClasses of the " );
buf.append( schema.getSchemaName() );
buf.append( " schema. We cannot seem to register the following objectClasses:\n" );
for ( ObjectClass extra : deferred )
{
buf.append( extra.getName() );
buf.append( '[' );
buf.append( extra.getOid() );
buf.append( "]" );
buf.append( "\n" );
}
NamingException ne = new NamingException( buf.toString() );
ne.setRootCause( lastException );
}
}
}
private void loadAttributeTypes( Schema schema, Registries targetRegistries ) throws NamingException
{
LinkedList<AttributeType> deferred = new LinkedList<AttributeType>();
LdapDN dn = staticAttributeTypeDNs.get( schema.getSchemaName() );
if ( dn == null )
{
dn = new LdapDN( "ou=attributeTypes,cn=" + schema.getSchemaName() + ",ou=schema" );
dn.normalize( this.attrRegistry.getNormalizerMapping() );
staticAttributeTypeDNs.put( schema.getSchemaName(), dn );
}
if ( ! partition.hasEntry( new EntryOperationContext( dn ) ) )
{
return;
}
log.debug( "{} schema: loading attributeTypes", schema.getSchemaName() );
NamingEnumeration list = partition.list( new ListOperationContext( dn ) );
while ( list.hasMore() )
{
SearchResult result = ( SearchResult ) list.next();
LdapDN resultDN = new LdapDN( result.getName() );
resultDN.normalize( attrRegistry.getNormalizerMapping() );
Attributes attrs = partition.lookup( new LookupOperationContext( resultDN ) );
AttributeType at = factory.getAttributeType( attrs, targetRegistries, schema.getSchemaName() );
try
{
targetRegistries.getAttributeTypeRegistry().register( at );
}
catch ( NamingException ne )
{
deferred.add( at );
}
}
log.debug( "Deferred queue size = {}", deferred.size() );
if ( log.isDebugEnabled() )
{
StringBuffer buf = new StringBuffer();
buf.append( "Deferred queue contains: " );
for ( AttributeType extra : deferred )
{
buf.append( extra.getName() );
buf.append( '[' );
buf.append( extra.getOid() );
buf.append( "]" );
buf.append( "\n" );
}
}
int lastCount = deferred.size();
while ( ! deferred.isEmpty() )
{
log.debug( "Deferred queue size = {}", deferred.size() );
AttributeType at = deferred.removeFirst();
NamingException lastException = null;
try
{
targetRegistries.getAttributeTypeRegistry().register( at );
}
catch ( NamingException ne )
{
deferred.addLast( at );
lastException = ne;
}
// if we shrank the deferred list we're doing good and can continue
if ( deferred.size() < lastCount )
{
lastCount = deferred.size();
}
else
{
StringBuffer buf = new StringBuffer();
buf.append( "A cycle must exist somewhere within the attributeTypes of the " );
buf.append( schema.getSchemaName() );
buf.append( " schema. We cannot seem to register the following attributeTypes:\n" );
for ( AttributeType extra : deferred )
{
buf.append( extra.getName() );
buf.append( '[' );
buf.append( extra.getOid() );
buf.append( "]" );
buf.append( "\n" );
}
NamingException ne = new NamingException( buf.toString() );
ne.setRootCause( lastException );
}
}
}
private void loadMatchingRules( Schema schema, Registries targetRegistries ) throws NamingException
{
LdapDN dn = staticMatchingRulesDNs.get( schema.getSchemaName() );
if ( dn == null )
{
dn = new LdapDN( "ou=matchingRules,cn=" + schema.getSchemaName() + ",ou=schema" );
dn.normalize( this.attrRegistry.getNormalizerMapping() );
staticMatchingRulesDNs.put( schema.getSchemaName(), dn );
}
if ( ! partition.hasEntry( new EntryOperationContext( dn ) ) )
{
return;
}
log.debug( "{} schema: loading matchingRules", schema.getSchemaName() );
NamingEnumeration list = partition.list( new ListOperationContext( dn ) );
while ( list.hasMore() )
{
SearchResult result = ( SearchResult ) list.next();
LdapDN resultDN = new LdapDN( result.getName() );
resultDN.normalize( attrRegistry.getNormalizerMapping() );
Attributes attrs = partition.lookup( new LookupOperationContext( resultDN ) );
MatchingRule mrule = factory.getMatchingRule( attrs, targetRegistries, schema.getSchemaName() );
targetRegistries.getMatchingRuleRegistry().register( mrule );
}
}
private void loadSyntaxes( Schema schema, Registries targetRegistries ) throws NamingException
{
LdapDN dn = staticSyntaxesDNs.get( schema.getSchemaName() );
if ( dn == null )
{
dn = new LdapDN( "ou=syntaxes,cn=" + schema.getSchemaName() + ",ou=schema" );
dn.normalize( this.attrRegistry.getNormalizerMapping() );
staticSyntaxesDNs.put( schema.getSchemaName(), dn );
}
if ( ! partition.hasEntry( new EntryOperationContext( dn ) ) )
{
return;
}
log.debug( "{} schema: loading syntaxes", schema.getSchemaName() );
NamingEnumeration list = partition.list( new ListOperationContext( dn ) );
while ( list.hasMore() )
{
SearchResult result = ( SearchResult ) list.next();
LdapDN resultDN = new LdapDN( result.getName() );
resultDN.normalize( attrRegistry.getNormalizerMapping() );
Attributes attrs = partition.lookup( new LookupOperationContext( resultDN ) );
Syntax syntax = factory.getSyntax( attrs, targetRegistries, schema.getSchemaName() );
targetRegistries.getSyntaxRegistry().register( syntax );
}
}
private void loadSyntaxCheckers( Schema schema, Registries targetRegistries ) throws NamingException
{
LdapDN dn = staticSyntaxCheckersDNs.get( schema.getSchemaName() );
if ( dn == null )
{
dn = new LdapDN( "ou=syntaxCheckers,cn=" + schema.getSchemaName() + ",ou=schema" );
dn.normalize( this.attrRegistry.getNormalizerMapping() );
staticSyntaxCheckersDNs.put( schema.getSchemaName(), dn );
}
if ( ! partition.hasEntry( new EntryOperationContext( dn ) ) )
{
return;
}
log.debug( "{} schema: loading syntaxCheckers", schema.getSchemaName() );
NamingEnumeration list = partition.list( new ListOperationContext( dn ) );
while ( list.hasMore() )
{
SearchResult result = ( SearchResult ) list.next();
LdapDN resultDN = new LdapDN( result.getName() );
resultDN.normalize( attrRegistry.getNormalizerMapping() );
Attributes attrs = partition.lookup( new LookupOperationContext( resultDN ) );
SyntaxChecker sc = factory.getSyntaxChecker( attrs, targetRegistries );
SyntaxCheckerDescription syntaxCheckerDescription =
getSyntaxCheckerDescription( schema.getSchemaName(), attrs );
targetRegistries.getSyntaxCheckerRegistry().register( syntaxCheckerDescription, sc );
}
}
private void loadNormalizers( Schema schema, Registries targetRegistries ) throws NamingException
{
LdapDN dn = staticNormalizersDNs.get( schema.getSchemaName() );
if ( dn == null )
{
dn = new LdapDN( "ou=normalizers,cn=" + schema.getSchemaName() + ",ou=schema" );
dn.normalize( this.attrRegistry.getNormalizerMapping() );
staticNormalizersDNs.put( schema.getSchemaName(), dn );
}
if ( ! partition.hasEntry( new EntryOperationContext( dn ) ) )
{
return;
}
log.debug( "{} schema: loading normalizers", schema.getSchemaName() );
NamingEnumeration list = partition.list( new ListOperationContext( dn ) );
while ( list.hasMore() )
{
SearchResult result = ( SearchResult ) list.next();
LdapDN resultDN = new LdapDN( result.getName() );
resultDN.normalize( attrRegistry.getNormalizerMapping() );
Attributes attrs = partition.lookup( new LookupOperationContext( resultDN ) );
Normalizer normalizer = factory.getNormalizer( attrs, targetRegistries );
NormalizerDescription normalizerDescription = getNormalizerDescription( schema.getSchemaName(), attrs );
targetRegistries.getNormalizerRegistry().register( normalizerDescription, normalizer );
}
}
private String getOid( Attributes entry ) throws NamingException
{
Attribute oid = AttributeUtils.getAttribute( entry, mOidAT );
if ( oid == null )
{
return null;
}
return ( String ) oid.get();
}
private NormalizerDescription getNormalizerDescription( String schemaName, Attributes entry ) throws NamingException
{
NormalizerDescription description = new NormalizerDescription();
description.setNumericOid( getOid( entry ) );
List<String> values = new ArrayList<String>();
values.add( schemaName );
description.addExtension( MetaSchemaConstants.X_SCHEMA, values );
description.setFqcn( ( String ) AttributeUtils.getAttribute( entry, fqcnAT ).get() );
Attribute desc = AttributeUtils.getAttribute( entry, descAT );
if ( desc != null && desc.size() > 0 )
{
description.setDescription( ( String ) desc.get() );
}
Attribute bytecode = AttributeUtils.getAttribute( entry, byteCodeAT );
if ( bytecode != null && bytecode.size() > 0 )
{
byte[] bytes = ( byte[] ) bytecode.get();
description.setBytecode( new String( Base64.encode( bytes ) ) );
}
return description;
}
private void loadComparators( Schema schema, Registries targetRegistries ) throws NamingException
{
LdapDN dn = staticComparatorsDNs.get( schema.getSchemaName() );
if ( dn == null )
{
dn = new LdapDN( "ou=comparators,cn=" + schema.getSchemaName() + ",ou=schema" );
dn.normalize( this.attrRegistry.getNormalizerMapping() );
staticComparatorsDNs.put( schema.getSchemaName(), dn );
}
if ( ! partition.hasEntry( new EntryOperationContext( dn ) ) )
{
return;
}
log.debug( "{} schema: loading comparators", schema.getSchemaName() );
NamingEnumeration list = partition.list( new ListOperationContext( dn ) );
while ( list.hasMore() )
{
SearchResult result = ( SearchResult ) list.next();
LdapDN resultDN = new LdapDN( result.getName() );
resultDN.normalize( attrRegistry.getNormalizerMapping() );
Attributes attrs = partition.lookup( new LookupOperationContext( resultDN ) );
Comparator comparator = factory.getComparator( attrs, targetRegistries );
ComparatorDescription comparatorDescription = getComparatorDescription( schema.getSchemaName(), attrs );
targetRegistries.getComparatorRegistry().register( comparatorDescription, comparator );
}
}
private ComparatorDescription getComparatorDescription( String schemaName, Attributes entry ) throws NamingException
{
ComparatorDescription description = new ComparatorDescription();
description.setNumericOid( getOid( entry ) );
List<String> values = new ArrayList<String>();
values.add( schemaName );
description.addExtension( MetaSchemaConstants.X_SCHEMA, values );
description.setFqcn( ( String ) AttributeUtils.getAttribute( entry, fqcnAT ).get() );
Attribute desc = AttributeUtils.getAttribute( entry, descAT );
if ( desc != null && desc.size() > 0 )
{
description.setDescription( ( String ) desc.get() );
}
Attribute bytecode = AttributeUtils.getAttribute( entry, byteCodeAT );
if ( bytecode != null && bytecode.size() > 0 )
{
byte[] bytes = ( byte[] ) bytecode.get();
description.setBytecode( new String( Base64.encode( bytes ) ) );
}
return description;
}
private SyntaxCheckerDescription getSyntaxCheckerDescription( String schemaName, Attributes entry )
throws NamingException
{
SyntaxCheckerDescription description = new SyntaxCheckerDescription();
description.setNumericOid( getOid( entry ) );
List<String> values = new ArrayList<String>();
values.add( schemaName );
description.addExtension( MetaSchemaConstants.X_SCHEMA, values );
description.setFqcn( ( String ) AttributeUtils.getAttribute( entry, fqcnAT ).get() );
Attribute desc = AttributeUtils.getAttribute( entry, descAT );
if ( desc != null && desc.size() > 0 )
{
description.setDescription( ( String ) desc.get() );
}
Attribute bytecode = AttributeUtils.getAttribute( entry, byteCodeAT );
if ( bytecode != null && bytecode.size() > 0 )
{
byte[] bytes = ( byte[] ) bytecode.get();
description.setBytecode( new String( Base64.encode( bytes ) ) );
}
return description;
}
public void loadWithDependencies( Schema schema, Registries registries ) throws NamingException
{
HashMap<String,Schema> notLoaded = new HashMap<String,Schema>();
notLoaded.put( schema.getSchemaName(), schema );
Properties props = new Properties();
loadDepsFirst( schema, new Stack<String>(), notLoaded, schema, registries, props );
}
}