blob: c0d51dae8288a0fb2cf2174509bb31a2d357dc5b [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.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;
}
}