| /* |
| * 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.shared.ldap.schema.loader.ldif; |
| |
| |
| import java.io.File; |
| import java.io.FileNotFoundException; |
| import java.io.FilenameFilter; |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import org.apache.directory.shared.i18n.I18n; |
| import org.apache.directory.shared.ldap.constants.SchemaConstants; |
| import org.apache.directory.shared.ldap.entry.Entry; |
| import org.apache.directory.shared.ldap.ldif.LdifEntry; |
| import org.apache.directory.shared.ldap.ldif.LdifReader; |
| import org.apache.directory.shared.ldap.schema.registries.AbstractSchemaLoader; |
| import org.apache.directory.shared.ldap.schema.registries.Schema; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| |
| /** |
| * Loads schema data from LDIF files containing entries representing schema |
| * objects, using the meta schema format. |
| * |
| * This class is used only for tests. |
| * |
| * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> |
| * @version $Revision$ |
| */ |
| public class LdifSchemaLoader extends AbstractSchemaLoader |
| { |
| /** ldif file extension used */ |
| private static final String LDIF_EXT = "ldif"; |
| |
| /** ou=schema LDIF file name */ |
| private static final String OU_SCHEMA_LDIF = "ou=schema." + LDIF_EXT; |
| |
| /** static class logger */ |
| private static final Logger LOG = LoggerFactory.getLogger( LdifSchemaLoader.class ); |
| |
| /** Speedup for DEBUG mode */ |
| private static final boolean IS_DEBUG = LOG.isDebugEnabled(); |
| |
| /** directory containing the schema LDIF file for ou=schema */ |
| private final File baseDirectory; |
| |
| /** a filter for listing all the LDIF files within a directory */ |
| private final FilenameFilter ldifFilter = new FilenameFilter() |
| { |
| public boolean accept( File file, String name ) |
| { |
| return name.endsWith( LDIF_EXT ); |
| } |
| }; |
| |
| |
| /** |
| * Creates a new LDIF based SchemaLoader. The constructor checks to make |
| * sure the supplied base directory exists and contains a schema.ldif file |
| * and if not complains about it. |
| * |
| * @param baseDirectory the schema LDIF base directory |
| * @throws Exception if the base directory does not exist or does not |
| * a valid schema.ldif file |
| */ |
| public LdifSchemaLoader( File baseDirectory ) throws Exception |
| { |
| this.baseDirectory = baseDirectory; |
| |
| if ( !baseDirectory.exists() ) |
| { |
| String msg = "Provided baseDirectory '" + baseDirectory.getAbsolutePath() + "' does not exist."; |
| LOG.error( msg ); |
| throw new IllegalArgumentException( msg ); |
| } |
| |
| File schemaLdif = new File( baseDirectory, OU_SCHEMA_LDIF ); |
| |
| if ( !schemaLdif.exists() ) |
| { |
| String msg = I18n.err( I18n.ERR_10004, schemaLdif.getAbsolutePath() ); |
| LOG.error( msg ); |
| throw new FileNotFoundException( msg ); |
| } |
| |
| if ( IS_DEBUG ) |
| { |
| LOG.debug( "Using '{}' as the base schema load directory.", baseDirectory ); |
| } |
| |
| initializeSchemas(); |
| } |
| |
| |
| /** |
| * Scans for LDIF files just describing the various schema contained in |
| * the schema repository. |
| * |
| * @throws Exception |
| */ |
| private void initializeSchemas() throws Exception |
| { |
| if ( IS_DEBUG ) |
| { |
| LOG.debug( "Initializing schema" ); |
| } |
| |
| File schemaDirectory = new File( baseDirectory, SchemaConstants.OU_SCHEMA ); |
| String[] ldifFiles = schemaDirectory.list( ldifFilter ); |
| |
| for ( String ldifFile : ldifFiles ) |
| { |
| File file = new File( schemaDirectory, ldifFile ); |
| |
| try |
| { |
| LdifReader reader = new LdifReader( file ); |
| LdifEntry entry = reader.next(); |
| reader.close(); |
| Schema schema = getSchema( entry.getEntry() ); |
| |
| if ( schema == null ) |
| { |
| // The entry was not a schema, skip it |
| continue; |
| } |
| |
| schemaMap.put( schema.getSchemaName(), schema ); |
| |
| if ( IS_DEBUG ) |
| { |
| LOG.debug( "Schema Initialized ... \n{}", schema ); |
| } |
| } |
| catch ( Exception e ) |
| { |
| LOG.error( I18n.err( I18n.ERR_10003, ldifFile ), e ); |
| throw e; |
| } |
| } |
| } |
| |
| |
| /** |
| * {@inheritDoc} |
| * |
| public List<Throwable> loadWithDependencies( Schema schema, Registries registries, boolean check ) throws Exception |
| { |
| // Relax the controls at first |
| List<Throwable> errors = new ArrayList<Throwable>(); |
| boolean wasRelaxed = registries.isRelaxed(); |
| registries.setRelaxed( true ); |
| |
| Stack<String> beenthere = new Stack<String>(); |
| Map<String,Schema> notLoaded = new HashMap<String,Schema>(); |
| notLoaded.put( schema.getSchemaName(), schema ); |
| super.loadDepsFirst( schema, beenthere, notLoaded, schema, registries ); |
| |
| // At the end, check the registries if required |
| if ( check ) |
| { |
| errors = registries.checkRefInteg(); |
| } |
| |
| // Restore the Registries isRelaxed flag |
| registries.setRelaxed( wasRelaxed ); |
| |
| return errors; |
| } |
| |
| |
| /** |
| * Loads a single schema if it has not been loaded already. If the schema |
| * load request was made because some other schema depends on this one then |
| * the schema is checked to see if it is disabled. If disabled it is |
| * enabled with a write to disk and then loaded. Listeners are notified that |
| * the schema has been loaded. |
| * |
| * {@inheritDoc} |
| * |
| public void load( Schema schema, Registries registries, boolean isDepLoad ) throws Exception |
| { |
| // 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 ) |
| { |
| enableSchema( schema ); |
| } |
| |
| if ( registries.isSchemaLoaded( schema.getSchemaName() ) ) |
| { |
| LOG.info( "Will not attempt to load already loaded '{}' " + |
| "schema: \n{}", schema.getSchemaName(), schema ); |
| return; |
| } |
| |
| LOG.info( "Loading {} schema: \n{}", schema.getSchemaName(), schema ); |
| |
| registries.schemaLoaded( schema ); |
| |
| loadComparators( schema ); |
| loadNormalizers( schema, registries ); |
| loadSyntaxCheckers( schema, registries ); |
| loadSyntaxes( schema, registries ); |
| loadMatchingRules( schema, registries ); |
| loadAttributeTypes( schema, registries ); |
| loadObjectClasses( schema, registries ); |
| loadMatchingRuleUses( schema, registries ); |
| loadDitContentRules( schema, registries ); |
| loadNameForms( schema, registries ); |
| loadDitStructureRules( schema, registries ); |
| |
| notifyListenerOrRegistries( schema, registries ); |
| } |
| |
| |
| /** |
| * Utility method to get the file for a schema directory. |
| * |
| * @param schema the schema to get the file for |
| * @return the file for the specific schema directory |
| */ |
| private final File getSchemaDirectory( Schema schema ) |
| { |
| return new File( new File( baseDirectory, SchemaConstants.OU_SCHEMA ), "cn=" + schema.getSchemaName() ); |
| } |
| |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public List<Entry> loadComparators( Schema... schemas ) throws Exception |
| { |
| List<Entry> comparatorList = new ArrayList<Entry>(); |
| |
| if ( schemas == null ) |
| { |
| return comparatorList; |
| } |
| |
| for ( Schema schema : schemas ) |
| { |
| File comparatorsDirectory = new File( getSchemaDirectory( schema ), SchemaConstants.COMPARATORS_PATH ); |
| |
| if ( !comparatorsDirectory.exists() ) |
| { |
| return comparatorList; |
| } |
| |
| File[] comparators = comparatorsDirectory.listFiles( ldifFilter ); |
| |
| for ( File ldifFile : comparators ) |
| { |
| LdifReader reader = new LdifReader( ldifFile ); |
| LdifEntry entry = reader.next(); |
| reader.close(); |
| |
| comparatorList.add( entry.getEntry() ); |
| } |
| } |
| |
| return comparatorList; |
| } |
| |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public List<Entry> loadSyntaxCheckers( Schema... schemas ) throws Exception |
| { |
| List<Entry> syntaxCheckerList = new ArrayList<Entry>(); |
| |
| if ( schemas == null ) |
| { |
| return syntaxCheckerList; |
| } |
| |
| for ( Schema schema : schemas ) |
| { |
| File syntaxCheckersDirectory = new File( getSchemaDirectory( schema ), SchemaConstants.SYNTAX_CHECKERS_PATH ); |
| |
| if ( !syntaxCheckersDirectory.exists() ) |
| { |
| return syntaxCheckerList; |
| } |
| |
| File[] syntaxCheckerFiles = syntaxCheckersDirectory.listFiles( ldifFilter ); |
| |
| for ( File ldifFile : syntaxCheckerFiles ) |
| { |
| LdifReader reader = new LdifReader( ldifFile ); |
| LdifEntry entry = reader.next(); |
| reader.close(); |
| |
| syntaxCheckerList.add( entry.getEntry() ); |
| } |
| } |
| |
| return syntaxCheckerList; |
| } |
| |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public List<Entry> loadNormalizers( Schema... schemas ) throws Exception |
| { |
| List<Entry> normalizerList = new ArrayList<Entry>(); |
| |
| if ( schemas == null ) |
| { |
| return normalizerList; |
| } |
| |
| for ( Schema schema : schemas ) |
| { |
| File normalizersDirectory = new File( getSchemaDirectory( schema ), SchemaConstants.NORMALIZERS_PATH ); |
| |
| if ( !normalizersDirectory.exists() ) |
| { |
| return normalizerList; |
| } |
| |
| File[] normalizerFiles = normalizersDirectory.listFiles( ldifFilter ); |
| |
| for ( File ldifFile : normalizerFiles ) |
| { |
| LdifReader reader = new LdifReader( ldifFile ); |
| LdifEntry entry = reader.next(); |
| reader.close(); |
| |
| normalizerList.add( entry.getEntry() ); |
| } |
| } |
| |
| return normalizerList; |
| } |
| |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public List<Entry> loadMatchingRules( Schema... schemas ) throws Exception |
| { |
| List<Entry> matchingRuleList = new ArrayList<Entry>(); |
| |
| if ( schemas == null ) |
| { |
| return matchingRuleList; |
| } |
| |
| for ( Schema schema : schemas ) |
| { |
| File matchingRulesDirectory = new File( getSchemaDirectory( schema ), SchemaConstants.MATCHING_RULES_PATH ); |
| |
| if ( !matchingRulesDirectory.exists() ) |
| { |
| return matchingRuleList; |
| } |
| |
| File[] matchingRuleFiles = matchingRulesDirectory.listFiles( ldifFilter ); |
| |
| for ( File ldifFile : matchingRuleFiles ) |
| { |
| LdifReader reader = new LdifReader( ldifFile ); |
| LdifEntry entry = reader.next(); |
| reader.close(); |
| |
| matchingRuleList.add( entry.getEntry() ); |
| } |
| } |
| |
| return matchingRuleList; |
| } |
| |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public List<Entry> loadSyntaxes( Schema... schemas ) throws Exception |
| { |
| List<Entry> syntaxList = new ArrayList<Entry>(); |
| |
| if ( schemas == null ) |
| { |
| return syntaxList; |
| } |
| |
| for ( Schema schema : schemas ) |
| { |
| File syntaxesDirectory = new File( getSchemaDirectory( schema ), SchemaConstants.SYNTAXES_PATH ); |
| |
| if ( !syntaxesDirectory.exists() ) |
| { |
| return syntaxList; |
| } |
| |
| File[] syntaxFiles = syntaxesDirectory.listFiles( ldifFilter ); |
| |
| for ( File ldifFile : syntaxFiles ) |
| { |
| LdifReader reader = new LdifReader( ldifFile ); |
| LdifEntry entry = reader.next(); |
| reader.close(); |
| |
| syntaxList.add( entry.getEntry() ); |
| } |
| } |
| |
| return syntaxList; |
| } |
| |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public List<Entry> loadAttributeTypes( Schema... schemas ) throws Exception |
| { |
| List<Entry> attributeTypeList = new ArrayList<Entry>(); |
| |
| if ( schemas == null ) |
| { |
| return attributeTypeList; |
| } |
| |
| for ( Schema schema : schemas ) |
| { |
| // check that the attributeTypes directory exists for the schema |
| File attributeTypesDirectory = new File( getSchemaDirectory( schema ), SchemaConstants.ATTRIBUTES_TYPE_PATH ); |
| |
| if ( !attributeTypesDirectory.exists() ) |
| { |
| return attributeTypeList; |
| } |
| |
| // get list of attributeType LDIF schema files in attributeTypes |
| File[] attributeTypeFiles = attributeTypesDirectory.listFiles( ldifFilter ); |
| |
| for ( File ldifFile : attributeTypeFiles ) |
| { |
| LdifReader reader = new LdifReader( ldifFile ); |
| LdifEntry entry = reader.next(); |
| reader.close(); |
| |
| attributeTypeList.add( entry.getEntry() ); |
| } |
| } |
| |
| return attributeTypeList; |
| } |
| |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public List<Entry> loadMatchingRuleUses( Schema... schemas ) throws Exception |
| { |
| List<Entry> matchingRuleUseList = new ArrayList<Entry>(); |
| |
| if ( schemas == null ) |
| { |
| return matchingRuleUseList; |
| } |
| |
| for ( Schema schema : schemas ) |
| { |
| File matchingRuleUsesDirectory = new File( getSchemaDirectory( schema ), |
| SchemaConstants.MATCHING_RULE_USE_PATH ); |
| |
| if ( !matchingRuleUsesDirectory.exists() ) |
| { |
| return matchingRuleUseList; |
| } |
| |
| File[] matchingRuleUseFiles = matchingRuleUsesDirectory.listFiles( ldifFilter ); |
| |
| for ( File ldifFile : matchingRuleUseFiles ) |
| { |
| LdifReader reader = new LdifReader( ldifFile ); |
| LdifEntry entry = reader.next(); |
| reader.close(); |
| |
| matchingRuleUseList.add( entry.getEntry() ); |
| } |
| } |
| |
| return matchingRuleUseList; |
| } |
| |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public List<Entry> loadNameForms( Schema... schemas ) throws Exception |
| { |
| List<Entry> nameFormList = new ArrayList<Entry>(); |
| |
| if ( schemas == null ) |
| { |
| return nameFormList; |
| } |
| |
| for ( Schema schema : schemas ) |
| { |
| File nameFormsDirectory = new File( getSchemaDirectory( schema ), SchemaConstants.NAME_FORMS_PATH ); |
| |
| if ( !nameFormsDirectory.exists() ) |
| { |
| return nameFormList; |
| } |
| |
| File[] nameFormFiles = nameFormsDirectory.listFiles( ldifFilter ); |
| |
| for ( File ldifFile : nameFormFiles ) |
| { |
| LdifReader reader = new LdifReader( ldifFile ); |
| LdifEntry entry = reader.next(); |
| reader.close(); |
| |
| nameFormList.add( entry.getEntry() ); |
| } |
| } |
| |
| return nameFormList; |
| } |
| |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public List<Entry> loadDitContentRules( Schema... schemas ) throws Exception |
| { |
| List<Entry> ditContentRuleList = new ArrayList<Entry>(); |
| |
| if ( schemas == null ) |
| { |
| return ditContentRuleList; |
| } |
| |
| for ( Schema schema : schemas ) |
| { |
| File ditContentRulesDirectory = new File( getSchemaDirectory( schema ), |
| SchemaConstants.DIT_CONTENT_RULES_PATH ); |
| |
| if ( !ditContentRulesDirectory.exists() ) |
| { |
| return ditContentRuleList; |
| } |
| |
| File[] ditContentRuleFiles = ditContentRulesDirectory.listFiles( ldifFilter ); |
| |
| for ( File ldifFile : ditContentRuleFiles ) |
| { |
| LdifReader reader = new LdifReader( ldifFile ); |
| LdifEntry entry = reader.next(); |
| reader.close(); |
| |
| ditContentRuleList.add( entry.getEntry() ); |
| } |
| } |
| |
| return ditContentRuleList; |
| } |
| |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public List<Entry> loadDitStructureRules( Schema... schemas ) throws Exception |
| { |
| List<Entry> ditStructureRuleList = new ArrayList<Entry>(); |
| |
| if ( schemas == null ) |
| { |
| return ditStructureRuleList; |
| } |
| |
| for ( Schema schema : schemas ) |
| { |
| File ditStructureRulesDirectory = new File( getSchemaDirectory( schema ), |
| SchemaConstants.DIT_STRUCTURE_RULES_PATH ); |
| |
| if ( !ditStructureRulesDirectory.exists() ) |
| { |
| return ditStructureRuleList; |
| } |
| |
| File[] ditStructureRuleFiles = ditStructureRulesDirectory.listFiles( ldifFilter ); |
| |
| for ( File ldifFile : ditStructureRuleFiles ) |
| { |
| LdifReader reader = new LdifReader( ldifFile ); |
| LdifEntry entry = reader.next(); |
| reader.close(); |
| |
| ditStructureRuleList.add( entry.getEntry() ); |
| } |
| } |
| |
| return ditStructureRuleList; |
| } |
| |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public List<Entry> loadObjectClasses( Schema... schemas ) throws Exception |
| { |
| List<Entry> objectClassList = new ArrayList<Entry>(); |
| |
| if ( schemas == null ) |
| { |
| return objectClassList; |
| } |
| |
| for ( Schema schema : schemas ) |
| { |
| // get objectClasses directory, check if exists, return if not |
| File objectClassesDirectory = new File( getSchemaDirectory( schema ), SchemaConstants.OBJECT_CLASSES_PATH ); |
| |
| if ( !objectClassesDirectory.exists() ) |
| { |
| return objectClassList; |
| } |
| |
| // get list of objectClass LDIF files from directory and load |
| File[] objectClassFiles = objectClassesDirectory.listFiles( ldifFilter ); |
| |
| for ( File ldifFile : objectClassFiles ) |
| { |
| LdifReader reader = new LdifReader( ldifFile ); |
| LdifEntry entry = reader.next(); |
| reader.close(); |
| |
| objectClassList.add( entry.getEntry() ); |
| } |
| } |
| |
| return objectClassList; |
| } |
| } |