You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by se...@apache.org on 2010/12/13 00:50:25 UTC
svn commit: r1044959 -
/directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/schema/SchemaLdifToPartitionExtractor.java
Author: seelmann
Date: Sun Dec 12 23:50:25 2010
New Revision: 1044959
URL: http://svn.apache.org/viewvc?rev=1044959&view=rev
Log:
Added a schema extractor that adds LDIF entries directly to a partition. This can be used for bootstrapping the schema partition in case the schema partition isn't a LDIF partition.
Added:
directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/schema/SchemaLdifToPartitionExtractor.java
Added: directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/schema/SchemaLdifToPartitionExtractor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/schema/SchemaLdifToPartitionExtractor.java?rev=1044959&view=auto
==============================================================================
--- directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/schema/SchemaLdifToPartitionExtractor.java (added)
+++ directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/schema/SchemaLdifToPartitionExtractor.java Sun Dec 12 23:50:25 2010
@@ -0,0 +1,264 @@
+/*
+ * 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.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InvalidObjectException;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.UUID;
+import java.util.regex.Pattern;
+
+import org.apache.directory.server.core.interceptor.context.AddOperationContext;
+import org.apache.directory.server.core.interceptor.context.EntryOperationContext;
+import org.apache.directory.server.core.partition.Partition;
+import org.apache.directory.shared.i18n.I18n;
+import org.apache.directory.shared.ldap.constants.SchemaConstants;
+import org.apache.directory.shared.ldap.csn.Csn;
+import org.apache.directory.shared.ldap.csn.CsnFactory;
+import org.apache.directory.shared.ldap.entry.DefaultEntry;
+import org.apache.directory.shared.ldap.entry.Entry;
+import org.apache.directory.shared.ldap.exception.LdapException;
+import org.apache.directory.shared.ldap.ldif.LdapLdifException;
+import org.apache.directory.shared.ldap.ldif.LdifEntry;
+import org.apache.directory.shared.ldap.ldif.LdifReader;
+import org.apache.directory.shared.ldap.name.DN;
+import org.apache.directory.shared.ldap.schema.SchemaManager;
+import org.apache.directory.shared.ldap.schema.ldif.extractor.SchemaLdifExtractor;
+import org.apache.directory.shared.ldap.schema.ldif.extractor.impl.DefaultSchemaLdifExtractor;
+import org.apache.directory.shared.ldap.schema.ldif.extractor.impl.ResourceMap;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * An schema extractor that adds schema LDIF entries directly to the schema partition.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class SchemaLdifToPartitionExtractor implements SchemaLdifExtractor
+{
+
+ /** The base path. */
+ private static final String BASE_PATH = "";
+
+ /** The logger. */
+ private static final Logger LOG = LoggerFactory.getLogger( SchemaLdifToPartitionExtractor.class );
+
+ /**
+ * The pattern to extract the schema from LDIF files.
+ * java.util.regex.Pattern is immutable so only one instance is needed for all uses.
+ */
+ private static final Pattern EXTRACT_PATTERN = Pattern.compile( ".*schema" + "[/\\Q\\\\E]" + "ou=schema.*\\.ldif" );
+
+ private final CsnFactory csnFactory = new CsnFactory( 0 );
+
+ /** The extracted flag. */
+ private boolean extracted;
+
+ private final SchemaManager schemaManager;
+ private final Partition partition;
+
+
+ /**
+ * Creates an extractor which adds schema LDIF entries directly to the schema partition.
+ * The bootstrap schema manager must at least know the 'apachemeta' schema.
+ *
+ * @param schemaManager the bootstrap schema manager
+ * @param partition the destination partition
+ */
+ public SchemaLdifToPartitionExtractor( SchemaManager schemaManager, Partition partition ) throws LdapException
+ {
+ this.schemaManager = schemaManager;
+ this.partition = partition;
+
+ DN dn = new DN( SchemaConstants.OU_SCHEMA, schemaManager );
+ EntryOperationContext hasEntryContext = new EntryOperationContext( null, dn );
+ if ( partition.hasEntry( hasEntryContext ) )
+ {
+ LOG.info( "Schema entry 'ou=schema' exists: extracted state set to true." );
+ extracted = true;
+ }
+ else
+ {
+ LOG.info( "Schema entry 'ou=schema' does NOT exist: extracted state set to false." );
+ extracted = false;
+ }
+ }
+
+
+ /**
+ * Gets whether or not the schema has already been added to the schema partition.
+ *
+ * @return true if schema has already been added to the schema partition
+ */
+ public boolean isExtracted()
+ {
+ return extracted;
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public void extractOrCopy( boolean overwrite ) throws IOException
+ {
+ Map<String, Boolean> resources = ResourceMap.getResources( EXTRACT_PATTERN );
+
+ // must sort the map to ensure parent entries are added before children
+ resources = new TreeMap<String, Boolean>( resources );
+
+ if ( !extracted || overwrite )
+ {
+ for ( Map.Entry<String, Boolean> entry : resources.entrySet() )
+ {
+ if ( entry.getValue() )
+ {
+ addFromClassLoader( entry.getKey() );
+ }
+ else
+ {
+ File resource = new File( entry.getKey() );
+ addLdifFile( resource );
+ }
+ }
+
+ extracted = true;
+ }
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public void extractOrCopy() throws IOException
+ {
+ extractOrCopy( false );
+ }
+
+
+ /**
+ * Adds an schema entry from an LDIF file.
+ *
+ * @param source the source file to copy
+ * @throws IOException if there are IO errors or the source does not exist
+ */
+ private void addLdifFile( File source ) throws IOException
+ {
+ LOG.debug( "copyFile(): source = {}", source );
+
+ if ( !source.getParentFile().exists() )
+ {
+ throw new FileNotFoundException( I18n.err( I18n.ERR_08002, source.getAbsolutePath() ) );
+ }
+
+ FileInputStream in = new FileInputStream( source );
+ addFromStream( in, source.getAbsolutePath() );
+ }
+
+
+ /**
+ * Adds an schema entry from a class loader resource.
+ *
+ * @param resource the LDIF schema resource
+ * @throws IOException if there are IO errors
+ */
+ private void addFromClassLoader( String resource ) throws IOException
+ {
+ InputStream in = DefaultSchemaLdifExtractor.getUniqueResourceAsStream( resource,
+ "LDIF file in schema repository" );
+ addFromStream( in, resource );
+ }
+
+
+ /**
+ * Adds an schema entry from the given stream to the schema partition
+ *
+ * @param in the input stream
+ * @param source the source
+ * @throws IOException signals that an I/O exception has occurred.
+ */
+ private void addFromStream( InputStream in, String source ) throws IOException
+ {
+ try
+ {
+ LdifReader ldifReader = new LdifReader( in );
+ boolean first = true;
+ LdifEntry ldifEntry = null;
+
+ while ( ldifReader.hasNext() )
+ {
+ if ( first )
+ {
+ ldifEntry = ldifReader.next();
+
+ if ( ldifEntry.get( SchemaConstants.ENTRY_UUID_AT ) == null )
+ {
+ // No UUID, let's create one
+ UUID entryUuid = UUID.randomUUID();
+ ldifEntry.addAttribute( SchemaConstants.ENTRY_UUID_AT, entryUuid.toString() );
+ }
+ if ( ldifEntry.get( SchemaConstants.ENTRY_CSN_AT ) == null )
+ {
+ // No CSN, let's create one
+ Csn csn = csnFactory.newInstance();
+ ldifEntry.addAttribute( SchemaConstants.ENTRY_CSN_AT, csn.toString() );
+ }
+
+ first = false;
+ }
+ else
+ {
+ // throw an exception : we should not have more than one entry per schema ldif file
+ String msg = I18n.err( I18n.ERR_08003, source );
+ LOG.error( msg );
+ throw new InvalidObjectException( msg );
+ }
+ }
+
+ ldifReader.close();
+
+ // inject the entry
+ Entry entry = new DefaultEntry( schemaManager, ldifEntry.getEntry() );
+ AddOperationContext addContext = new AddOperationContext( null, entry );
+ partition.add( addContext );
+ }
+ catch ( LdapLdifException ne )
+ {
+ // throw an exception : we should not have more than one entry per schema ldif file
+ String msg = I18n.err( I18n.ERR_08004, source, ne.getLocalizedMessage() );
+ LOG.error( msg );
+ throw new IOException( msg, ne );
+ }
+ catch ( LdapException ne )
+ {
+ // throw an exception : we should not have more than one entry per schema ldif file
+ String msg = I18n.err( I18n.ERR_08004, source, ne.getLocalizedMessage() );
+ LOG.error( msg );
+ throw new IOException( msg, ne );
+ }
+ }
+
+}