Index: apacheds/core/src/main/java/org/apache/directory/server/core/configuration/SchemaLoader.java =================================================================== --- apacheds/core/src/main/java/org/apache/directory/server/core/configuration/SchemaLoader.java (revision 0) +++ apacheds/core/src/main/java/org/apache/directory/server/core/configuration/SchemaLoader.java (revision 0) @@ -0,0 +1,20 @@ +package org.apache.directory.server.core.configuration; + +import org.apache.directory.server.core.schema.bootstrap.BootstrapRegistries; +import org.apache.directory.server.core.schema.Registries; + +import java.util.Collection; + + +/** + * Can be implemented by classes wishing to load schemas dynamically at server startup (refer to + * {@link org.apache.directory.server.core.configuration.StartupConfiguration#getSchemaLoaders()}). + * + * @author Apache Directory Project + * @version $Rev: 437012 $, $Date: 2006-08-26 09:25:30 +1000 (Sat, 26 Aug 2006) $ + */ +public interface SchemaLoader +{ + /** Load schemas into provided registries, and then return them. */ + public Collection loadSchemas(final StartupConfiguration startupConfiguration, final Registries registries); +} Property changes on: apacheds\core\src\main\java\org\apache\directory\server\core\configuration\SchemaLoader.java ___________________________________________________________________ Name: svn:keywords + Id Index: apacheds/core/src/main/java/org/apache/directory/server/core/configuration/StartupConfiguration.java =================================================================== --- apacheds/core/src/main/java/org/apache/directory/server/core/configuration/StartupConfiguration.java (revision 454606) +++ apacheds/core/src/main/java/org/apache/directory/server/core/configuration/StartupConfiguration.java (working copy) @@ -21,11 +21,7 @@ import java.io.File; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; +import java.util.*; import javax.naming.directory.Attributes; @@ -42,14 +38,7 @@ import org.apache.directory.server.core.operational.OperationalAttributeService; import org.apache.directory.server.core.referral.ReferralService; import org.apache.directory.server.core.schema.SchemaService; -import org.apache.directory.server.core.schema.bootstrap.ApacheSchema; -import org.apache.directory.server.core.schema.bootstrap.BootstrapSchema; -import org.apache.directory.server.core.schema.bootstrap.CollectiveSchema; -import org.apache.directory.server.core.schema.bootstrap.CoreSchema; -import org.apache.directory.server.core.schema.bootstrap.CosineSchema; -import org.apache.directory.server.core.schema.bootstrap.InetorgpersonSchema; -import org.apache.directory.server.core.schema.bootstrap.JavaSchema; -import org.apache.directory.server.core.schema.bootstrap.SystemSchema; +import org.apache.directory.server.core.schema.bootstrap.*; import org.apache.directory.server.core.subtree.SubentryService; import org.apache.directory.server.core.trigger.TriggerService; import org.apache.directory.shared.ldap.ldif.Entry; @@ -80,12 +69,12 @@ private int maxTimeLimit = MAX_TIME_LIMIT_DEFAULT; // set to default value (milliseconds) private Set authenticatorConfigurations; // Set private List interceptorConfigurations; // Set - private PartitionConfiguration systemPartitionConfiguration; + private PartitionConfiguration systemPartitionConfiguration; + private List schemaLoaders; private Set bootstrapSchemas; // Set private Set contextPartitionConfigurations = new HashSet(); // Set private List testEntries = new ArrayList(); // List - /** * Creates a new instance with default settings. */ @@ -257,7 +246,21 @@ this.authenticatorConfigurations = newSet; } + /** + * An optional list of {@link SchemaLoader}s which can be specified to load schemas dynamically at server-startup. + * + * @return The loader bean, if one has been configured. + */ + public List getSchemaLoaders() + { + return schemaLoaders; + } + public void setSchemaLoaders(final List schemaLoaders) + { + this.schemaLoaders = schemaLoaders; + } + /** * Returns {@link BootstrapSchema}s to load while bootstrapping. */ Index: apacheds/core/src/main/java/org/apache/directory/server/core/DefaultDirectoryService.java =================================================================== --- apacheds/core/src/main/java/org/apache/directory/server/core/DefaultDirectoryService.java (revision 454606) +++ apacheds/core/src/main/java/org/apache/directory/server/core/DefaultDirectoryService.java (working copy) @@ -20,11 +20,7 @@ package org.apache.directory.server.core; -import java.util.Hashtable; -import java.util.Iterator; -import java.util.Map; -import java.util.Set; -import java.util.HashSet; +import java.util.*; import javax.naming.Context; import javax.naming.NamingException; @@ -35,6 +31,7 @@ import org.apache.directory.server.core.configuration.Configuration; import org.apache.directory.server.core.configuration.ConfigurationException; import org.apache.directory.server.core.configuration.StartupConfiguration; +import org.apache.directory.server.core.configuration.SchemaLoader; import org.apache.directory.server.core.interceptor.InterceptorChain; import org.apache.directory.server.core.jndi.AbstractContextFactory; import org.apache.directory.server.core.jndi.DeadContext; @@ -526,7 +523,8 @@ partitionNexus.add(normName, attributes ); AuthorizationService authzSrvc = ( AuthorizationService ) interceptorChain.get( "authorizationService" ); - authzSrvc.cacheNewGroup( upName, normName, attributes ); + if (authzSrvc != null) + authzSrvc.cacheNewGroup( upName, normName, attributes ); } // ------------------------------------------------------------------- @@ -726,7 +724,7 @@ * * @throws javax.naming.NamingException if there are problems along the way */ - private void initialize() throws NamingException + protected void initialize() throws NamingException { if ( log.isDebugEnabled() ) { @@ -740,7 +738,17 @@ BootstrapRegistries bootstrapRegistries = new BootstrapRegistries(); BootstrapSchemaLoader loader = new BootstrapSchemaLoader(); loader.load( startupConfiguration.getBootstrapSchemas(), bootstrapRegistries ); + if (startupConfiguration.getSchemaLoaders() != null) + { + for (Iterator it = startupConfiguration.getSchemaLoaders().iterator(); it.hasNext();) + { + final SchemaLoader schemaLoader; + schemaLoader = (SchemaLoader) it.next(); + schemaLoader.loadSchemas(startupConfiguration, bootstrapRegistries); + } + } + java.util.List errors = bootstrapRegistries.checkRefInteg(); if ( !errors.isEmpty() ) { Index: apacheds/core/src/main/java/org/apache/directory/server/core/schema/FileSystemSchemaLoader.java =================================================================== --- apacheds/core/src/main/java/org/apache/directory/server/core/schema/FileSystemSchemaLoader.java (revision 0) +++ apacheds/core/src/main/java/org/apache/directory/server/core/schema/FileSystemSchemaLoader.java (revision 0) @@ -0,0 +1,142 @@ +package org.apache.directory.server.core.schema; + + +import java.util.*; +import java.io.File; +import java.io.FilenameFilter; + +import org.apache.directory.server.core.configuration.StartupConfiguration; +import org.apache.directory.server.core.configuration.SchemaLoader; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +/** + * Allows a filesystem directory name can be specified, in which case it will be scanned for OpenLDAP + * formatted .schema files and their contents returned. This is a more dynamic alternative (but works in + * addition to) the scheme were schemas are built into the release via the Maven2 plug-in. + * + * @author Apache Directory Project + * @version $Rev: 437012 $ + */ +public class FileSystemSchemaLoader implements SchemaLoader +{ + private static final Logger log = LoggerFactory.getLogger( FileSystemSchemaLoader.class ); + + private final String directoryName; + private final String fileNameRegex; + private final List fileNames; + + + // ------------------------------------------------------------------------ + // Constructor + // ------------------------------------------------------------------------ + + /** Calls FileSystemSchemaLoader(null, (String)null). */ + public FileSystemSchemaLoader() + { + this(null, (String)null); + } + + /** + * Loads all files in specified directory that match the specified regex, after they have been + * sort alphabetically. Note that you must ensure, using lexicographical ordering, that schema files + * are loaded before any files that are dependant on them. + * + * @param directoryName Directory to be read, if null the "./" will be used. + * @param fileNameRegex Regular expression which file names need to match, if null + * then ".*_openldap.schema" will be used. + */ + public FileSystemSchemaLoader(final String directoryName, final String fileNameRegex) + { + this.directoryName = directoryName; + this.fileNameRegex = fileNameRegex; + this.fileNames = null; + } + + /** + * Loads named files under the specified directory in strict order. + * + * @param directoryName Directory to be read, if null the "./" will be used. + * @param fileNames Names of files under directoryName to load, in order (a schema + * file must appear before any files that are dependant on it). + */ + public FileSystemSchemaLoader(final String directoryName, final List fileNames) + { + this.directoryName = directoryName; + this.fileNames = fileNames; + fileNameRegex = null; + } + + public String getDirectoryName() + { + return directoryName; + } + + public Collection loadSchemas(final StartupConfiguration startupConfiguration, final Registries registries) + { + final File schemaDir; + final File[] schemaFiles; + final List files; + final Collection schemas; + + if (directoryName == null) + return null; + + schemaDir = new File(directoryName); + if (!schemaDir.isDirectory()) + return null; + + if (fileNameRegex != null) + { + schemaFiles = schemaDir.listFiles(new FilenameFilter() { + public boolean accept(final File dir, final String name) + { + return name.matches(fileNameRegex); + } + }); + if (schemaFiles == null) + return null; + Arrays.sort(schemaFiles); + files = Arrays.asList(schemaFiles); + } + else + { + if ((fileNames == null) || fileNames.isEmpty()) + return null; + files = new ArrayList(fileNames.size()); + for (Iterator it = fileNames.iterator(); it.hasNext();) + { + final String fl = (String) it.next(); + + files.add(new File(schemaDir, fl)); + } + } + + if (log.isInfoEnabled()) + log.info("about to read " + files.size() + " schema files"); + schemas = new ArrayList(files.size()); + for (Iterator it = files.iterator(); it.hasNext();) + { + final File schemaFile = (File) it.next(); + final String schemaName; + final SchemaFromFileConverter schema; + + schemaName = schemaFile.getName().replaceFirst("_[^_]*", ""); + try + { + schema = new SchemaFromFileConverter(schemaName, schemaFile); + schema.convert(registries); + if (log.isInfoEnabled()) + log.info("read schema from '" + schemaFile + '\''); + schemas.add(schemas); + } + catch (Exception e) + { + log.error("failed reading schema from '" + schemaFile + '\'', e); + } + } + return (schemas.isEmpty() ? null : schemas); + } +} Property changes on: apacheds\core\src\main\java\org\apache\directory\server\core\schema\FileSystemSchemaLoader.java ___________________________________________________________________ Name: svn:keywords + Id Index: apacheds/core/src/main/java/org/apache/directory/server/core/schema/RegistrySchemaProducer.java =================================================================== --- apacheds/core/src/main/java/org/apache/directory/server/core/schema/RegistrySchemaProducer.java (revision 0) +++ apacheds/core/src/main/java/org/apache/directory/server/core/schema/RegistrySchemaProducer.java (revision 0) @@ -0,0 +1,456 @@ +package org.apache.directory.server.core.schema; + +import org.apache.directory.shared.ldap.schema.*; + +import javax.naming.NamingException; +import java.util.Comparator; + +/** + * An abstract producer implementation which doesn't make explicit reference + * to "bootstrap". + * todo: Based on org.apache.ldap.server.schema.bootstrap.AbstractBootstrapProducer + * rev 226451 which should be recoded to use this more generic class. + */ +public abstract class RegistrySchemaProducer +{ + /** a reused empty String array */ + protected static final String[] EMPTY = new String[0]; + + protected RegistrySchemaProducer() + { + } + + protected static RegistrySchemaProducer.ConceteSchemaSyntax + newSyntax( String oid, Registries registries ) + { + return new RegistrySchemaProducer.ConceteSchemaSyntax( oid, registries.getSyntaxCheckerRegistry() ); + } + + protected static RegistrySchemaProducer.ConcreteSchemaAttributeType + newAttributeType( String oid, Registries registries ) + { + return new RegistrySchemaProducer.ConcreteSchemaAttributeType( oid, registries ); + } + + protected static RegistrySchemaProducer.ConcreteSchemaObjectClass + newObjectClass( String oid, Registries registries ) + { + return new RegistrySchemaProducer.ConcreteSchemaObjectClass( oid, registries ); + } + + protected static RegistrySchemaProducer.ConcreteSchemaMatchingRule + newMatchingRule( String oid, Registries registries ) + { + return new RegistrySchemaProducer.ConcreteSchemaMatchingRule( oid, registries ); + } + + + /** + * A mutable Syntax for the bootstrap phase that uses the + * syntaxCheckerRegistry to dynamically resolve syntax checkers. + */ + public static class ConceteSchemaSyntax extends AbstractSyntax + { + final SyntaxCheckerRegistry registry; + + + protected ConceteSchemaSyntax( String oid, SyntaxCheckerRegistry registry ) + { + super( oid ); + this.registry = registry; + } + + + public void setDescription( String description ) + { + super.setDescription( description ); + } + + + public void setHumanReadible( boolean isHumanReadible ) + { + super.setHumanReadible( isHumanReadible ); + } + + + public void setNames( String[] names ) + { + super.setNames( names ); + } + + + public SyntaxChecker getSyntaxChecker( ) throws NamingException + { + return registry.lookup( getOid() ); + } + + + public boolean isObsolete() + { + return false; + } + } + + + public static class ConcreteSchemaMatchingRule extends AbstractMatchingRule + { + final SyntaxRegistry syntaxRegistry; + final NormalizerRegistry normalizerRegistry; + final ComparatorRegistry comparatorRegistry; + String syntaxOid; + + + protected ConcreteSchemaMatchingRule( String oid, Registries registries ) + { + super( oid ); + this.syntaxRegistry = registries.getSyntaxRegistry(); + this.normalizerRegistry = registries.getNormalizerRegistry(); + this.comparatorRegistry = registries.getComparatorRegistry(); + } + + + public void setNames( String[] names ) + { + super.setNames( names ); + } + + public void setSyntaxOid( String syntaxOid ) + { + this.syntaxOid = syntaxOid; + } + + public void setDescription( String description ) + { + super.setDescription( description ); + } + + public void setObsolete( boolean isObsolete ) + { + super.setObsolete( isObsolete ); + } + + + // accessors + + + public Syntax getSyntax() throws NamingException + { + return syntaxRegistry.lookup( syntaxOid ); + } + + public Comparator getComparator() throws NamingException + { + return comparatorRegistry.lookup( getOid() ); + } + + public Normalizer getNormalizer() throws NamingException + { + return normalizerRegistry.lookup( getOid() ); + } + } + + + /** + * A concrete mutable attributeType implementation for bootstrapping which + * uses registries for dynamically resolving dependent objects. + */ + public static class ConcreteSchemaAttributeType extends AbstractAttributeType + { + private static final long serialVersionUID = 4050205236738471984L; + + private final SyntaxRegistry syntaxRegistry; + private final MatchingRuleRegistry matchingRuleRegistry; + private final AttributeTypeRegistry attributeTypeRegistry; + private String superiorId; + private String equalityId; + private String substrId; + private String orderingId; + private String syntaxId; + + + protected ConcreteSchemaAttributeType( String oid, Registries registries ) + { + super( oid ); + + syntaxRegistry = registries.getSyntaxRegistry(); + matchingRuleRegistry = registries.getMatchingRuleRegistry(); + attributeTypeRegistry = registries.getAttributeTypeRegistry(); + } + + public void setSuperiorId( String superiorId ) + { + this.superiorId = superiorId; + } + + public AttributeType getSuperior() throws NamingException + { + if ( superiorId == null ) + { + return null; + } + + return this.attributeTypeRegistry.lookup( superiorId ); + } + + public void setNames( String[] names ) + { + super.setNames( names ); + } + + public MatchingRule getEquality() throws NamingException + { + if ( equalityId != null ) + { + return this.matchingRuleRegistry.lookup( equalityId ); + } + + if ( superiorId != null ) + { + return getSuperior().getEquality(); + } + + return null; + } + + public void setEqualityId( String equalityId ) + { + this.equalityId = equalityId; + } + + public MatchingRule getSubstr() throws NamingException + { + if ( substrId != null ) + { + return this.matchingRuleRegistry.lookup( substrId ); + } + + if ( superiorId != null ) + { + return getSuperior().getSubstr(); + } + + return null; + } + + public void setSubstrId( String substrId ) + { + this.substrId = substrId; + } + + public MatchingRule getOrdering() throws NamingException + { + if ( orderingId != null ) + { + return this.matchingRuleRegistry.lookup( orderingId ); + } + + if ( superiorId != null ) + { + return getSuperior().getOrdering(); + } + + return null; + } + + public void setOrderingId( String orderingId ) + { + this.orderingId = orderingId; + } + + public void setSyntaxId( String syntaxId ) + { + this.syntaxId = syntaxId; + } + + public Syntax getSyntax() throws NamingException + { + if ( syntaxId != null ) + { + return this.syntaxRegistry.lookup( syntaxId ); + } + + if ( superiorId != null ) + { + return getSuperior().getSyntax(); + } + + return null; + } + + public void setSingleValue( boolean singleValue ) + { + super.setSingleValue( singleValue ); + } + + public void setCollective( boolean collective ) + { + super.setCollective( collective ); + } + + public void setCanUserModify( boolean canUserModify ) + { + super.setCanUserModify( canUserModify ); + } + + public void setObsolete( boolean obsolete ) + { + super.setObsolete( obsolete ); + } + + public void setDescription( String description ) + { + super.setDescription( description ); + } + + public void setUsage( UsageEnum usage ) + { + super.setUsage( usage ); + } + + public void setLength( int length ) + { + super.setLength( length ); + } + } + + + /** + * A concrete mutable objectClass implementation for bootstrapping which + * uses registries for dynamically resolving dependent objects. + */ + public static class ConcreteSchemaObjectClass extends AbstractSchemaObject + implements ObjectClass + { + private final ObjectClassRegistry objectClassRegistry; + private final AttributeTypeRegistry attributeTypeRegistry; + + private String[] superClassIds = RegistrySchemaProducer.EMPTY; + private ObjectClass[] superClasses; + private ObjectClassTypeEnum type = ObjectClassTypeEnum.STRUCTURAL; + + private String[] mayListIds = RegistrySchemaProducer.EMPTY; + private AttributeType[] mayList; + + private String[] mustListIds = RegistrySchemaProducer.EMPTY; + private AttributeType[] mustList; + + + /** + * Creates a mutable ObjectClass for the bootstrap process. + * + * @param oid the OID of the new objectClass + * @param registries the bootstrap registries to use for resolving dependent objects + */ + protected ConcreteSchemaObjectClass( String oid, Registries registries ) + { + super( oid ); + + objectClassRegistry = registries.getObjectClassRegistry(); + attributeTypeRegistry = registries.getAttributeTypeRegistry(); + } + + + // -------------------------------------------------------------------- + // ObjectClass Accessors + // -------------------------------------------------------------------- + + + public ObjectClass[] getSuperClasses() throws NamingException + { + if ( superClasses == null ) + { + superClasses = new ObjectClass[superClassIds.length]; + } + + for( int ii = 0; ii < superClassIds.length; ii++ ) + { + superClasses[ii] = objectClassRegistry.lookup( superClassIds[ii] ); + } + + return superClasses; + } + + + public void setSuperClassIds( String[] superClassIds ) + { + this.superClassIds = superClassIds; + } + + + public ObjectClassTypeEnum getType() + { + return type; + } + + + public void setType( ObjectClassTypeEnum type ) + { + this.type = type; + } + + + public AttributeType[] getMustList() throws NamingException + { + if ( mustList == null ) + { + mustList = new AttributeType[mustListIds.length]; + } + + for( int ii = 0; ii < mustListIds.length; ii++ ) + { + mustList[ii] = attributeTypeRegistry.lookup( mustListIds[ii] ); + } + + return mustList; + } + + + public void setMustListIds( String[] mustListIds ) + { + this.mustListIds = mustListIds; + } + + + public AttributeType[] getMayList() throws NamingException + { + if ( mayList == null ) + { + mayList = new AttributeType[mayListIds.length]; + } + + for( int ii = 0; ii < mayListIds.length; ii++ ) + { + mayList[ii] = attributeTypeRegistry.lookup( mayListIds[ii] ); + } + + return mayList; + } + + + public void setMayListIds( String[] mayListIds ) + { + this.mayListIds = mayListIds; + } + + + // -------------------------------------------------------------------- + // SchemaObject Mutators + // -------------------------------------------------------------------- + + + public void setObsolete( boolean obsolete ) + { + super.setObsolete( obsolete ); + } + + public void setNames( String[] names ) + { + super.setNames( names ); + } + + public void setDescription( String description ) + { + super.setDescription( description ); + } + } +} Property changes on: apacheds\core\src\main\java\org\apache\directory\server\core\schema\RegistrySchemaProducer.java ___________________________________________________________________ Name: svn:keywords + Id Index: apacheds/core/src/main/java/org/apache/directory/server/core/schema/SchemaFromFileConverter.java =================================================================== --- apacheds/core/src/main/java/org/apache/directory/server/core/schema/SchemaFromFileConverter.java (revision 0) +++ apacheds/core/src/main/java/org/apache/directory/server/core/schema/SchemaFromFileConverter.java (revision 0) @@ -0,0 +1,184 @@ +package org.apache.directory.server.core.schema; + +import org.apache.directory.server.core.tools.schema.AttributeTypeLiteral; +import org.apache.directory.server.core.tools.schema.ObjectClassLiteral; +import org.apache.directory.server.core.tools.schema.OpenLdapSchemaParser; +import org.apache.directory.shared.ldap.schema.SchemaUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.naming.NamingException; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; + +/** + * Wrapper that can parse an OpenLDAP format schema and help register the + * contents with the ApacheDS + * {@link org.apache.directory.server.core.schema.SchemaService}. + */ +public class SchemaFromFileConverter extends SchemaProducer +{ + private static final Logger log = LoggerFactory.getLogger(SchemaFromFileConverter.class); + + private final String schemaName; + private final File schemaFile; + private final InputStream schemaStream; + + public SchemaFromFileConverter(final String schemaName, final File schemaFile) + { + this.schemaName = schemaName; + this.schemaFile = schemaFile; + schemaStream = null; + } + + public SchemaFromFileConverter(final String schemaName, final InputStream schemaStream) + { + this.schemaName = schemaName; + this.schemaFile = null; + this.schemaStream = schemaStream; + } + + public void convert(final Registries registries) throws NamingException, IOException, ParseException + { + final OpenLdapSchemaParser parser = new OpenLdapSchemaParser(); + + if (schemaFile != null) + parser.parse(schemaFile); + else + parser.parse(schemaStream); + convertAttributeTypes(registries, parser.getAttributeTypes()); + convertObjectClasses(registries, parser.getObjectClassTypes()); + } + + + /** + * Take in list() result on schema attribute type container and register + * types in global registry. + * + * @param toRegistries Registry to be populated. + * @throws javax.naming.NamingException + */ + public void convertAttributeTypes(final Registries toRegistries, final Collection attributeTypeLiterals) + throws NamingException + { + final AttributeTypeRegistry attributeTypeRegistry; + final ArrayList skipped = new ArrayList(); + int good = 0; + + attributeTypeRegistry = toRegistries.getAttributeTypeRegistry(); + for (Iterator it = attributeTypeLiterals.iterator(); it.hasNext();) + { + final AttributeTypeLiteral in = (AttributeTypeLiteral) it.next(); + final String oid = in.getOid(); + final String name; + final ConcreteSchemaAttributeType out; + + name = in.getNames()[0]; + if (attributeTypeRegistry.hasAttributeType(oid)) + { + skipped.add(name + " : " + oid); + continue; + } + out = newAttributeType(oid, toRegistries); + out.setDescription(in.getDescription()); + out.setEqualityId(in.getEquality()); + out.setLength(in.getLength()); + out.setNames(in.getNames()); + out.setOrderingId(in.getOrdering()); + out.setSubstrId(in.getSubstr()); + out.setSuperiorId(in.getSuperior()); + out.setSyntaxId(in.getSyntax()); + out.setUsage(in.getUsage()); + + if (SchemaFromFileConverter.log.isDebugEnabled()) + SchemaFromFileConverter.log.debug("converting attributeType[" + good + "]: " + oid + + "=" + name); + good++; + attributeTypeRegistry.register(schemaName, out); + } + SchemaFromFileConverter.log.info("'" + schemaName + "': registered " + good + " attributeTypes (skipped " + + skipped.size() + ")"); + if (! skipped.isEmpty()) + { + int i = 0; + + Collections.sort(skipped); + for (Iterator it = skipped.iterator(); it.hasNext(); i++) + { + final String skip = (String)it.next(); + + SchemaFromFileConverter.log.error("skipped attributeType[" + i + "]: " + skip); + } + } + } + + private void convertObjectClasses(final Registries toRegistries, final Collection objectClassLiterals) + { + final ObjectClassRegistry objectClassRegistry; + final ArrayList skipped = new ArrayList(); + int good = 0; + + objectClassRegistry = toRegistries.getObjectClassRegistry(); + + for (Iterator it = objectClassLiterals.iterator(); it.hasNext();) + { + final ObjectClassLiteral in = (ObjectClassLiteral) it.next(); + final String oid = in.getOid(); + final String name; + final ConcreteSchemaObjectClass out; + + name = in.getNames()[0]; + if (objectClassRegistry.hasObjectClass(oid)) + { + skipped.add(name + " : " + oid); + continue; + } + if (SchemaFromFileConverter.log.isDebugEnabled()) + SchemaFromFileConverter.log.debug("converting objectClass[" + good + "]: " + oid + + "=" + name); + good++; + // @note Code copied from ./plugin/src/main/java/org/apache/ldap/server/tools/schema/ObjectClasses.template + out = newObjectClass(oid, toRegistries); + out.setDescription(in.getDescription()); + out.setNames(in.getNames()); + out.setType(in.getClassType()); + out.setMayListIds(in.getMay()); + out.setMustListIds(in.getMust()); + out.setSuperClassIds(in.getSuperiors()); + out.setObsolete(in.isObsolete()); + + try + { + // avoid case where external schema attempts to register + // OC with bad references + SchemaUtils.render(out); + objectClassRegistry.register(schemaName, out); + } + catch (NamingException e) + { + log.error("failed validation objectClass: " + name + ": " + e); + skipped.add(name + " : " + oid + " [failed]"); + } + } + log.info("'" + schemaName + "': registered " + good + " objectClasss (skipped " + + skipped.size() + ")"); + if (! skipped.isEmpty()) + { + int i = 0; + + Collections.sort(skipped); + for (Iterator it = skipped.iterator(); it.hasNext(); i++) + { + final String skip = (String)it.next(); + + SchemaFromFileConverter.log.error("skipped objectClass[" + i + "]: " + skip); + } + } + } +} Property changes on: apacheds\core\src\main\java\org\apache\directory\server\core\schema\SchemaFromFileConverter.java ___________________________________________________________________ Name: svn:keywords + Id Index: apacheds/core/src/main/java/org/apache/directory/server/core/schema/SchemaFromSearchConverter.java =================================================================== --- apacheds/core/src/main/java/org/apache/directory/server/core/schema/SchemaFromSearchConverter.java (revision 0) +++ apacheds/core/src/main/java/org/apache/directory/server/core/schema/SchemaFromSearchConverter.java (revision 0) @@ -0,0 +1,455 @@ +package org.apache.directory.server.core.schema; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.apache.directory.server.core.schema.global.GlobalRegistries; +import org.apache.directory.shared.ldap.schema.UsageEnum; +import org.apache.directory.shared.ldap.schema.ObjectClassTypeEnum; +import org.apache.directory.shared.ldap.schema.SchemaUtils; + +import javax.naming.NameClassPair; +import javax.naming.NamingEnumeration; +import javax.naming.NamingException; +import javax.naming.directory.Attribute; +import javax.naming.directory.Attributes; +import javax.naming.directory.DirContext; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Wrapper that can parse an OpenLDAP format schema and help register the + * contents with the ApacheDS + * {@link SchemaService}. + */ +public class SchemaFromSearchConverter extends RegistrySchemaProducer +{ + private static final Logger log = LoggerFactory.getLogger(SchemaFromSearchConverter.class); + + private final String schemaName; + private final DirContext schema; + private static final String ATTR_DEFS = "AttributeDefinition"; + private static final String OBJ_CLASS_DEFS = "ClassDefinition"; + private static final String SYNTAX_DEFS = "SyntaxDefinition"; + private static final String MATCHING_RULE_DEFS = "MatchingRule"; + + /** Common schema attributes defined for an "Object Class". */ + public static final String OID_ATTR = "NUMERICOID"; + public static final String NAME_ATTR = "NAME"; + public static final String DESC_ATTR = "DESC"; + public static final String OBSOLETE_ATTR = "OBSOLETE"; + public static final String SUP_ATTR = "SUP"; + + /** Schema attributes defined for an "Attribute Type". */ + public static final String AT_EQUALITY_ATTR = "EQUALITY"; + public static final String AT_ORDERING_ATTR = "ORDERING"; + public static final String AT_SUBSTRING_ATTR = "SUBSTRING"; + public static final String AT_SYNTAX_ATTR = "SYNTAX"; + public static final String AT_SINGLE_VALUE_ATTR = "SINGLE-VALUE"; + public static final String AT_COLLECTIVE_ATTR = "COLLECTIVE"; + public static final String AT_NO_USER_MODIFICATION_ATTR = "NO-USER-MODIFICATION"; + public static final String AT_USAGE_ATTR = "USAGE"; + + /** Schema attributes defined for an "Object Class". */ + public static final String OC_ABSTRACT_ATTR = "ABSTRACT"; + public static final String OC_STRUCTURAL_ATTR = "STRUCTURAL"; + public static final String OC_AUXILIARY_ATTR = "AUXILIARY"; + public static final String OC_MUST_ATTR = "MUST"; + public static final String OC_MAY_ATTR = "MAY"; + + /** Schema attributes defined for a "Matching Rule". */ + public static final String RL_SYNTAX = "SYNTAX"; + + private final static String[] EMPTY = new String[0]; + + public SchemaFromSearchConverter(final String schemaName, final DirContext schema) + { + this.schemaName = schemaName; + this.schema = schema; + } + + public void convert(final GlobalRegistries registries) + throws NamingException + { + convertAttributeTypes(registries); + convertObjectClasses(registries); + convertSyntaxDefs(registries); + convertMatchingRuleDefs(registries); +// registries.getSyntaxRegistry(); +// registries.getMatchingRuleRegistry(); +// registries.getDitStructureRuleRegistry(); + } + + + /** + * Take in list() result on schema attribute type container and register + * types in global registry. + * + * @param toRegistries Registry to be populated. + * @throws NamingException + */ + public void convertAttributeTypes(final GlobalRegistries toRegistries) + throws NamingException + { + final AttributeTypeRegistry attributeTypeRegistry; + final ArrayList skipped = new ArrayList(); + int good = 0; + final DirContext attrTypes; + final NamingEnumeration atPairs; + + attrTypes = (DirContext)schema.lookup(ATTR_DEFS); + atPairs = schema.list(ATTR_DEFS); + + attributeTypeRegistry = toRegistries.getAttributeTypeRegistry(); + while (atPairs.hasMore()) + { + final NameClassPair pair = (NameClassPair)atPairs.next(); + final Attributes atSchemaAttrs; + final String[] names; + final String name; + final String id; + final String usage; + final ConcreteSchemaAttributeType at; + + atSchemaAttrs = attrTypes.getAttributes(pair.getName()); + id = getValueAsString(atSchemaAttrs, OID_ATTR); + names = getValueAsStringArray(atSchemaAttrs, NAME_ATTR); + name = (names != null ? names[0] : "***unknown***"); + if ("eTGlobalUserContainerName".equals(name)) + log.info("*** GOT: " + "eTGlobalUserContainerName"); + if (attributeTypeRegistry.hasAttributeType(id)) + { + skipped.add(name + " : " + id); + continue; + } + if (log.isDebugEnabled()) + log.debug("converting attributeType[" + good + "]: " + id + + "=" + name); + good++; + // @note Code copied from ./plugin/src/main/java/org/apache/ldap/server/tools/schema/AttributeTypes.template + at = newAttributeType(id, toRegistries); + at.setNames(names); + at.setDescription(getValueAsString(atSchemaAttrs, DESC_ATTR)); + at.setCanUserModify(! getValueAsBoolean(atSchemaAttrs, + AT_NO_USER_MODIFICATION_ATTR)); + at.setSingleValue(getValueAsBoolean(atSchemaAttrs, + AT_SINGLE_VALUE_ATTR)); + at.setCollective(getValueAsBoolean(atSchemaAttrs, + AT_COLLECTIVE_ATTR)); + at.setObsolete(getValueAsBoolean(atSchemaAttrs, OBSOLETE_ATTR)); + usage = getValueAsString(atSchemaAttrs, AT_USAGE_ATTR); + if (usage != null) + at.setUsage(UsageEnum.getUsage(usage)); + at.setSuperiorId(getValueAsString(atSchemaAttrs, SUP_ATTR)); + at.setEqualityId(getValueAsString(atSchemaAttrs, + AT_EQUALITY_ATTR)); + at.setSubstrId(getValueAsString(atSchemaAttrs, AT_SUBSTRING_ATTR)); + at.setOrderingId(getValueAsString(atSchemaAttrs, AT_ORDERING_ATTR)); + at.setSyntaxId(getValueAsString(atSchemaAttrs, AT_SYNTAX_ATTR)); + + attributeTypeRegistry.register(schemaName, at); + } + log.info("'" + schemaName + "': registered " + good + " attributeTypes (skipped " + + skipped.size() + ")"); + if (! skipped.isEmpty()) + { + int i = 0; + + Collections.sort(skipped); + for (Iterator it = skipped.iterator(); it.hasNext(); i++) + { + final String skip = (String)it.next(); + + log.error("skipped attributeType[" + i + "]: " + skip); + } + } + } + + private void convertObjectClasses(final GlobalRegistries toRegistries) throws NamingException + { + final ObjectClassRegistry objectClassRegistry; + final ArrayList skipped = new ArrayList(); + int good = 0; + final DirContext objClasses; + final NamingEnumeration ocPairs; + + objClasses = (DirContext)schema.lookup(OBJ_CLASS_DEFS); + ocPairs = schema.list(OBJ_CLASS_DEFS); + objectClassRegistry = toRegistries.getObjectClassRegistry(); + + while (ocPairs.hasMoreElements()) + { + final NameClassPair pair = (NameClassPair)ocPairs.next(); + final Attributes ocSchemaAttrs; + final String[] names; + final String name; + final String id; + final ConcreteSchemaObjectClass oc; + final ObjectClassTypeEnum type; + + ocSchemaAttrs = objClasses.getAttributes(pair.getName()); + id = getValueAsString(ocSchemaAttrs, OID_ATTR); + names = getValueAsStringArray(ocSchemaAttrs, NAME_ATTR); + name = (names != null ? names[0] : "***unknown***"); + if (objectClassRegistry.hasObjectClass(id)) + { + skipped.add(name + " : " + id); + continue; + } + if (log.isDebugEnabled()) + log.debug("converting objectClass[" + good + "]: " + id + + "=" + name); + good++; + // @note Code copied from ./plugin/src/main/java/org/apache/ldap/server/tools/schema/ObjectClasses.template + oc = newObjectClass(id, toRegistries); + // set names + oc.setNames(names); + oc.setDescription(getValueAsString(ocSchemaAttrs, DESC_ATTR)); + oc.setObsolete(getValueAsBoolean(ocSchemaAttrs, OBSOLETE_ATTR)); + // set superior objectClasses + oc.setSuperClassIds(getValueAsStringArray(ocSchemaAttrs, SUP_ATTR)); + + if (getValueAsBoolean(ocSchemaAttrs, OC_ABSTRACT_ATTR)) + type = ObjectClassTypeEnum.ABSTRACT; + else if (getValueAsBoolean(ocSchemaAttrs, OC_STRUCTURAL_ATTR)) + type = ObjectClassTypeEnum.STRUCTURAL; + else if (getValueAsBoolean(ocSchemaAttrs, OC_AUXILIARY_ATTR)) + type = ObjectClassTypeEnum.AUXILIARY; + else + type = null; + if (type != null) + oc.setType(type); + + oc.setMustListIds(getValueAsStringArray(ocSchemaAttrs, + OC_MUST_ATTR)); + oc.setMayListIds(getValueAsStringArray(ocSchemaAttrs, + OC_MAY_ATTR)); + + try + { + // avoid case where external schema attempts to register + // OC with bad references + SchemaUtils.render(oc); + objectClassRegistry.register(schemaName, oc); + } + catch (NamingException e) + { + log.error("failed validation objectClass: " + name); + skipped.add(name + " : " + id + " [failed]"); + } + } + log.info("'" + schemaName + "': registered " + good + " objectClasss (skipped " + + skipped.size() + ")"); + if (! skipped.isEmpty()) + { + int i = 0; + + Collections.sort(skipped); + for (Iterator it = skipped.iterator(); it.hasNext(); i++) + { + final String skip = (String)it.next(); + + log.error("skipped objectClass[" + i + "]: " + skip); + } + } + } + + private void convertSyntaxDefs(final GlobalRegistries toRegistries) + throws NamingException + { + final SyntaxRegistry syntaxRegistry; + final ArrayList skipped = new ArrayList(); + int good = 0; + final DirContext syntaxes; + final NamingEnumeration synPairs; + final Pattern humanPat; + final Pattern notPat; + + syntaxes = (DirContext)schema.lookup(SYNTAX_DEFS); + synPairs = schema.list(SYNTAX_DEFS); + + syntaxRegistry = toRegistries.getSyntaxRegistry(); + humanPat = Pattern.compile("human", Pattern.CASE_INSENSITIVE); + notPat = Pattern.compile("not", Pattern.CASE_INSENSITIVE); + while (synPairs.hasMore()) + { + final NameClassPair pair = (NameClassPair)synPairs.next(); + final Attributes synSchemaAttrs; + String[] names; + final String name; + final String id; + final ConceteSchemaSyntax syn; + + synSchemaAttrs = syntaxes.getAttributes(pair.getName()); + id = getValueAsString(synSchemaAttrs, OID_ATTR); + names = getValueAsStringArray(synSchemaAttrs, NAME_ATTR); + if ((names == null) || (names.length == 0)) + { + name = id; + names = new String[] { name }; + } + else + name = names[0] + ":" + id; + if (syntaxRegistry.hasSyntax(id)) + { + skipped.add(name); + continue; + } + if (log.isDebugEnabled()) + log.debug("converting syntax[" + good + "]: " + name); + good++; + syn = newSyntax(id, toRegistries); + syn.setNames(names); + + // end mandatory attrs according to RFC + + // doesn't seem to be a standard attr name for human readable + final NamingEnumeration iDs = synSchemaAttrs.getIDs(); + while (iDs.hasMoreElements()) + { + final String nm = (String)iDs.nextElement(); + Matcher m = humanPat.matcher(nm); + + if (m.matches()) + { + boolean b = getValueAsBoolean(synSchemaAttrs, nm); + + m = notPat.matcher(nm); + if (m.matches()) + b = !b; + syn.setHumanReadible(!b); + break; + } + } + syntaxRegistry.register(schemaName, syn); + } + log.info("'" + schemaName + "': registered " + good + " syntaxes (skipped " + + skipped.size() + ")"); + if (! skipped.isEmpty()) + { + int i = 0; + + Collections.sort(skipped); + for (Iterator it = skipped.iterator(); it.hasNext(); i++) + { + final String skip = (String)it.next(); + + log.error("skipped syntax[" + i + "]: " + skip); + } + } + } + + private void convertMatchingRuleDefs(final GlobalRegistries toRegistries) + throws NamingException + { + final MatchingRuleRegistry ruleRegistry; + final ArrayList skipped = new ArrayList(); + int good = 0; + final DirContext rules; + final NamingEnumeration rulePairs; + + try + { + // todo Use some more flexible rule to identify these rules + // (called dITStructureRule in CA directory) + rules = (DirContext)schema.lookup(MATCHING_RULE_DEFS); + } + catch (NamingException e) + { + log.warn("no section " + MATCHING_RULE_DEFS + " found in schema"); + return; + } + rulePairs = schema.list(MATCHING_RULE_DEFS); + + ruleRegistry = toRegistries.getMatchingRuleRegistry(); + while (rulePairs.hasMore()) + { + final NameClassPair pair = (NameClassPair)rulePairs.next(); + final Attributes ruleSchemaAttrs; + final String[] names; + final String name; + final String id; + final ConcreteSchemaMatchingRule rule; + + ruleSchemaAttrs = rules.getAttributes(pair.getName()); + id = getValueAsString(ruleSchemaAttrs, OID_ATTR); + names = getValueAsStringArray(ruleSchemaAttrs, NAME_ATTR); + name = (names != null ? names[0] : id); + if (ruleRegistry.hasMatchingRule(id)) + { + skipped.add(name + " : " + "*** unknown ***"); + continue; + } + if (log.isDebugEnabled()) + log.debug("converting rule[" + good + "]: " + id + + "=" + name); + good++; + rule = newMatchingRule(id, toRegistries); + rule.setNames(names); + rule.setDescription(getValueAsString(ruleSchemaAttrs, DESC_ATTR)); + rule.setObsolete(getValueAsBoolean(ruleSchemaAttrs, OBSOLETE_ATTR)); + rule.setSyntaxOid(getValueAsString(ruleSchemaAttrs, RL_SYNTAX)); + ruleRegistry.register(schemaName, rule); + } + log.info("'" + schemaName + "': registered " + good + " attributeTypes (skipped " + + skipped.size() + ")"); + if (! skipped.isEmpty()) + { + int i = 0; + + Collections.sort(skipped); + for (Iterator it = skipped.iterator(); it.hasNext(); i++) + { + final String skip = (String)it.next(); + + log.error("skipped attributeType[" + i + "]: " + skip); + } + } + } + + private String[] getValueAsStringArray(final Attributes atSchemaAttrs, + final String attrName) throws NamingException + { + final Attribute attr; + final String[] arr; + final NamingEnumeration enm; + + attr = atSchemaAttrs.get(attrName); + if (attr == null) + return EMPTY; + arr = new String[attr.size()]; + enm = attr.getAll(); + for (int i = 0; enm.hasMoreElements(); i++) + { + final String s = (String)enm.nextElement(); + + arr[i] = s; + } + return arr; + } + + private boolean getValueAsBoolean(final Attributes atSchemaAttrs, + final String attrName) throws NamingException + { + final Attribute attr; + + attr = atSchemaAttrs.get(attrName); + if (attr == null) + return false; + return Boolean.valueOf((String)attr.get()).booleanValue(); + } + + private String getValueAsString(final Attributes atSchemaAttrs, + final String attrName) throws NamingException + { + final Attribute attr; + + attr = atSchemaAttrs.get(attrName); + if (attr == null) + return null; + return (String)attr.get(); + } + +} Property changes on: apacheds\core\src\main\java\org\apache\directory\server\core\schema\SchemaFromSearchConverter.java ___________________________________________________________________ Name: svn:keywords + Id Index: apacheds/core/src/main/java/org/apache/directory/server/core/schema/SchemaProducer.java =================================================================== --- apacheds/core/src/main/java/org/apache/directory/server/core/schema/SchemaProducer.java (revision 0) +++ apacheds/core/src/main/java/org/apache/directory/server/core/schema/SchemaProducer.java (revision 0) @@ -0,0 +1,473 @@ +/* + * Copyright 2004 The Apache Software Foundation + * + * Licensed 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 org.apache.directory.shared.ldap.schema.*; + +import javax.naming.NamingException; +import java.util.Comparator; + +/** + * An abstract producer implementation which doesn't make explicit reference + * to "bootstrap". + * todo: Based on org.apache.ldap.server.schema.bootstrap.AbstractBootstrapProducer + * rev 226451 which should be recoded to use this more generic class. + */ +public abstract class SchemaProducer +{ + /** a reused empty String array */ + protected static final String[] EMPTY = new String[0]; + + protected SchemaProducer() + { + } + + protected static ConceteSchemaSyntax + newSyntax( String oid, Registries registries ) + { + return new ConceteSchemaSyntax( oid, registries.getSyntaxCheckerRegistry() ); + } + + protected static ConcreteSchemaAttributeType + newAttributeType( String oid, Registries registries ) + { + return new ConcreteSchemaAttributeType( oid, registries ); + } + + protected static ConcreteSchemaObjectClass + newObjectClass( String oid, Registries registries ) + { + return new ConcreteSchemaObjectClass( oid, registries ); + } + + protected static ConcreteSchemaMatchingRule + newMatchingRule( String oid, Registries registries ) + { + return new ConcreteSchemaMatchingRule( oid, registries ); + } + + + /** + * A mutable Syntax for the bootstrap phase that uses the + * syntaxCheckerRegistry to dynamically resolve syntax checkers. + */ + public static class ConceteSchemaSyntax extends AbstractSyntax + { + final SyntaxCheckerRegistry registry; + + + protected ConceteSchemaSyntax( String oid, SyntaxCheckerRegistry registry ) + { + super( oid ); + this.registry = registry; + } + + + public void setDescription( String description ) + { + super.setDescription( description ); + } + + + public void setHumanReadible( boolean isHumanReadible ) + { + super.setHumanReadible( isHumanReadible ); + } + + + public void setNames( String[] names ) + { + super.setNames( names ); + } + + + public SyntaxChecker getSyntaxChecker( ) throws NamingException + { + return registry.lookup( getOid() ); + } + + + public boolean isObsolete() + { + return false; + } + } + + + public static class ConcreteSchemaMatchingRule extends AbstractMatchingRule + { + final SyntaxRegistry syntaxRegistry; + final NormalizerRegistry normalizerRegistry; + final ComparatorRegistry comparatorRegistry; + String syntaxOid; + + + protected ConcreteSchemaMatchingRule( String oid, Registries registries ) + { + super( oid ); + this.syntaxRegistry = registries.getSyntaxRegistry(); + this.normalizerRegistry = registries.getNormalizerRegistry(); + this.comparatorRegistry = registries.getComparatorRegistry(); + } + + + public void setNames( String[] names ) + { + super.setNames( names ); + } + + public void setSyntaxOid( String syntaxOid ) + { + this.syntaxOid = syntaxOid; + } + + public void setDescription( String description ) + { + super.setDescription( description ); + } + + public void setObsolete( boolean isObsolete ) + { + super.setObsolete( isObsolete ); + } + + + // accessors + + + public Syntax getSyntax() throws NamingException + { + return syntaxRegistry.lookup( syntaxOid ); + } + + public Comparator getComparator() throws NamingException + { + return comparatorRegistry.lookup( getOid() ); + } + + public Normalizer getNormalizer() throws NamingException + { + return normalizerRegistry.lookup( getOid() ); + } + } + + + /** + * A concrete mutable attributeType implementation for bootstrapping which + * uses registries for dynamically resolving dependent objects. + */ + public static class ConcreteSchemaAttributeType extends AbstractAttributeType + { + private static final long serialVersionUID = 4050205236738471984L; + + private final SyntaxRegistry syntaxRegistry; + private final MatchingRuleRegistry matchingRuleRegistry; + private final AttributeTypeRegistry attributeTypeRegistry; + private String superiorId; + private String equalityId; + private String substrId; + private String orderingId; + private String syntaxId; + + + protected ConcreteSchemaAttributeType( String oid, Registries registries ) + { + super( oid ); + + syntaxRegistry = registries.getSyntaxRegistry(); + matchingRuleRegistry = registries.getMatchingRuleRegistry(); + attributeTypeRegistry = registries.getAttributeTypeRegistry(); + } + + public void setSuperiorId( String superiorId ) + { + this.superiorId = superiorId; + } + + public AttributeType getSuperior() throws NamingException + { + if ( superiorId == null ) + { + return null; + } + + return this.attributeTypeRegistry.lookup( superiorId ); + } + + public void setNames( String[] names ) + { + super.setNames( names ); + } + + public MatchingRule getEquality() throws NamingException + { + if ( equalityId != null ) + { + return this.matchingRuleRegistry.lookup( equalityId ); + } + + if ( superiorId != null ) + { + return getSuperior().getEquality(); + } + + return null; + } + + public void setEqualityId( String equalityId ) + { + this.equalityId = equalityId; + } + + public MatchingRule getSubstr() throws NamingException + { + if ( substrId != null ) + { + return this.matchingRuleRegistry.lookup( substrId ); + } + + if ( superiorId != null ) + { + return getSuperior().getSubstr(); + } + + return null; + } + + public void setSubstrId( String substrId ) + { + this.substrId = substrId; + } + + public MatchingRule getOrdering() throws NamingException + { + if ( orderingId != null ) + { + return this.matchingRuleRegistry.lookup( orderingId ); + } + + if ( superiorId != null ) + { + return getSuperior().getOrdering(); + } + + return null; + } + + public void setOrderingId( String orderingId ) + { + this.orderingId = orderingId; + } + + public void setSyntaxId( String syntaxId ) + { + this.syntaxId = syntaxId; + } + + public Syntax getSyntax() throws NamingException + { + if ( syntaxId != null ) + { + return this.syntaxRegistry.lookup( syntaxId ); + } + + if ( superiorId != null ) + { + return getSuperior().getSyntax(); + } + + return null; + } + + public void setSingleValue( boolean singleValue ) + { + super.setSingleValue( singleValue ); + } + + public void setCollective( boolean collective ) + { + super.setCollective( collective ); + } + + public void setCanUserModify( boolean canUserModify ) + { + super.setCanUserModify( canUserModify ); + } + + public void setObsolete( boolean obsolete ) + { + super.setObsolete( obsolete ); + } + + public void setDescription( String description ) + { + super.setDescription( description ); + } + + public void setUsage( UsageEnum usage ) + { + super.setUsage( usage ); + } + + public void setLength( int length ) + { + super.setLength( length ); + } + } + + + /** + * A concrete mutable objectClass implementation for bootstrapping which + * uses registries for dynamically resolving dependent objects. + */ + public static class ConcreteSchemaObjectClass extends AbstractSchemaObject + implements ObjectClass + { + private final ObjectClassRegistry objectClassRegistry; + private final AttributeTypeRegistry attributeTypeRegistry; + + private String[] superClassIds = EMPTY; + private ObjectClass[] superClasses; + private ObjectClassTypeEnum type = ObjectClassTypeEnum.STRUCTURAL; + + private String[] mayListIds = EMPTY; + private AttributeType[] mayList; + + private String[] mustListIds = EMPTY; + private AttributeType[] mustList; + + + /** + * Creates a mutable ObjectClass for the bootstrap process. + * + * @param oid the OID of the new objectClass + * @param registries the bootstrap registries to use for resolving dependent objects + */ + protected ConcreteSchemaObjectClass( String oid, Registries registries ) + { + super( oid ); + + objectClassRegistry = registries.getObjectClassRegistry(); + attributeTypeRegistry = registries.getAttributeTypeRegistry(); + } + + + // -------------------------------------------------------------------- + // ObjectClass Accessors + // -------------------------------------------------------------------- + + + public ObjectClass[] getSuperClasses() throws NamingException + { + if ( superClasses == null ) + { + superClasses = new ObjectClass[superClassIds.length]; + } + + for( int ii = 0; ii < superClassIds.length; ii++ ) + { + superClasses[ii] = objectClassRegistry.lookup( superClassIds[ii] ); + } + + return superClasses; + } + + + public void setSuperClassIds( String[] superClassIds ) + { + this.superClassIds = superClassIds; + } + + + public ObjectClassTypeEnum getType() + { + return type; + } + + + public void setType( ObjectClassTypeEnum type ) + { + this.type = type; + } + + + public AttributeType[] getMustList() throws NamingException + { + if ( mustList == null ) + { + mustList = new AttributeType[mustListIds.length]; + } + + for( int ii = 0; ii < mustListIds.length; ii++ ) + { + mustList[ii] = attributeTypeRegistry.lookup( mustListIds[ii] ); + } + + return mustList; + } + + + public void setMustListIds( String[] mustListIds ) + { + this.mustListIds = mustListIds; + } + + + public AttributeType[] getMayList() throws NamingException + { + if ( mayList == null ) + { + mayList = new AttributeType[mayListIds.length]; + } + + for( int ii = 0; ii < mayListIds.length; ii++ ) + { + mayList[ii] = attributeTypeRegistry.lookup( mayListIds[ii] ); + } + + return mayList; + } + + + public void setMayListIds( String[] mayListIds ) + { + this.mayListIds = mayListIds; + } + + + // -------------------------------------------------------------------- + // SchemaObject Mutators + // -------------------------------------------------------------------- + + + public void setObsolete( boolean obsolete ) + { + super.setObsolete( obsolete ); + } + + public void setNames( String[] names ) + { + super.setNames( names ); + } + + public void setDescription( String description ) + { + super.setDescription( description ); + } + } +} Property changes on: apacheds\core\src\main\java\org\apache\directory\server\core\schema\SchemaProducer.java ___________________________________________________________________ Name: svn:keywords + Id