Return-Path: Delivered-To: apmail-directory-commits-archive@www.apache.org Received: (qmail 5371 invoked from network); 13 Aug 2010 21:47:01 -0000 Received: from unknown (HELO mail.apache.org) (140.211.11.3) by 140.211.11.9 with SMTP; 13 Aug 2010 21:47:01 -0000 Received: (qmail 75354 invoked by uid 500); 13 Aug 2010 21:47:01 -0000 Delivered-To: apmail-directory-commits-archive@directory.apache.org Received: (qmail 75295 invoked by uid 500); 13 Aug 2010 21:47:01 -0000 Mailing-List: contact commits-help@directory.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@directory.apache.org Delivered-To: mailing list commits@directory.apache.org Received: (qmail 75288 invoked by uid 99); 13 Aug 2010 21:47:01 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 13 Aug 2010 21:47:01 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 13 Aug 2010 21:47:00 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 4E69D23889EB; Fri, 13 Aug 2010 21:45:43 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r985376 [1/2] - in /directory/shared/branches/shared-codec-merge/ldap-schema-loader/src/main: java/org/apache/directory/shared/ldap/schema/loader/ldif/SingleLdifSchemaLoader.java resources/ resources/schema-all.ldif Date: Fri, 13 Aug 2010 21:45:43 -0000 To: commits@directory.apache.org From: kayyagari@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20100813214543.4E69D23889EB@eris.apache.org> Author: kayyagari Date: Fri Aug 13 21:45:42 2010 New Revision: 985376 URL: http://svn.apache.org/viewvc?rev=985376&view=rev Log: o a new schema loader which loads the schema from a single monolithic ldif file o ldif file containing all the schemas Added: directory/shared/branches/shared-codec-merge/ldap-schema-loader/src/main/java/org/apache/directory/shared/ldap/schema/loader/ldif/SingleLdifSchemaLoader.java directory/shared/branches/shared-codec-merge/ldap-schema-loader/src/main/resources/ directory/shared/branches/shared-codec-merge/ldap-schema-loader/src/main/resources/schema-all.ldif Added: directory/shared/branches/shared-codec-merge/ldap-schema-loader/src/main/java/org/apache/directory/shared/ldap/schema/loader/ldif/SingleLdifSchemaLoader.java URL: http://svn.apache.org/viewvc/directory/shared/branches/shared-codec-merge/ldap-schema-loader/src/main/java/org/apache/directory/shared/ldap/schema/loader/ldif/SingleLdifSchemaLoader.java?rev=985376&view=auto ============================================================================== --- directory/shared/branches/shared-codec-merge/ldap-schema-loader/src/main/java/org/apache/directory/shared/ldap/schema/loader/ldif/SingleLdifSchemaLoader.java (added) +++ directory/shared/branches/shared-codec-merge/ldap-schema-loader/src/main/java/org/apache/directory/shared/ldap/schema/loader/ldif/SingleLdifSchemaLoader.java Fri Aug 13 21:45:42 2010 @@ -0,0 +1,391 @@ +/* + * 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.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.RandomAccessFile; +import java.net.URL; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.directory.shared.ldap.entry.Entry; +import org.apache.directory.shared.ldap.exception.LdapException; +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; + + +/** + * A schema loader based on a single monolithic ldif file containing all the schema partition elements + * + * Warn: this works, but not a super performer. Need to profile to see how much time the regex matching + * is taking (this is definitely the hotspot) + * NOT DOCUMENTED atm + * + * @author Apache Directory Project + */ +public class SingleLdifSchemaLoader extends AbstractSchemaLoader +{ + + private static final Logger LOG = LoggerFactory.getLogger( SingleLdifSchemaLoader.class ); + + private RandomAccessFile schemaFile; + + private Map markerMap = new HashMap(); + + private LdifReader ldifParser = new LdifReader(); + + + public SingleLdifSchemaLoader() + { + try + { + URL resource = getClass().getClassLoader().getResource( "schema-all.ldif" ); + + LOG.debug( "URL of the all schema ldif file {}", resource ); + + File tempSchemaFile = File.createTempFile( "all-schema", ".ldif" ); + LOG.debug( "storing the all schema file at {}", tempSchemaFile.getAbsolutePath() ); + + InputStream in = resource.openStream(); + OutputStream out = new FileOutputStream( tempSchemaFile ); + + byte[] buf = new byte[1024 * 1024]; + while ( true ) + { + int read = in.read( buf ); + if ( read > 0 ) + { + out.write( buf, 0, read ); + continue; + } + + break; + } + + in.close(); + out.close(); + + schemaFile = new RandomAccessFile( tempSchemaFile, "r" ); + + initializeSchemas(); + } + catch ( Exception e ) + { + throw new RuntimeException( e ); + } + } + + + private void initializeSchemas() throws Exception + { + Pattern schemaStartPattern = Pattern.compile( "dn:\\s*cn=[a-z0-9-_]*\\s*,\\s*ou\\s*=\\s*schema" ); + + String readLine = null; + + SchemaMarker prevMarker = null; + + while ( true ) + { + int startLineOffset = ( int ) schemaFile.getFilePointer(); + + readLine = schemaFile.readLine(); + + if ( readLine == null ) + { + break; + } + + Matcher matcher = schemaStartPattern.matcher( readLine ); + if ( matcher.matches() ) + { + if ( prevMarker != null ) + { + prevMarker.setEnd( startLineOffset ); + } + + LdifEntry entry = readLdif( readLine ); + Schema schema = getSchema( entry.getEntry() ); + schemaMap.put( schema.getSchemaName(), schema ); + + SchemaMarker marker = new SchemaMarker( startLineOffset ); + markerMap.put( schema.getSchemaName(), marker ); + prevMarker = marker; + } + } + + prevMarker.setEnd( ( int ) schemaFile.getFilePointer() ); + } + + + private LdifEntry readLdif( String startLine ) throws Exception + { + StringBuilder sb = new StringBuilder( startLine ); + sb.append( '\n' ); + + while ( true ) + { + startLine = schemaFile.readLine(); + if ( startLine.length() == 0 ) + { + break; + } + else + { + sb.append( startLine ); + sb.append( '\n' ); + } + } + + return ldifParser.parseLdif( sb.toString() ).get( 0 ); + } + + + private List getMatchingEntries( Pattern regex, int endOffset ) throws LdapException + { + + try + { + List entries = new ArrayList(); + String s = null; + + // a perf improvement hack + boolean matchesFound = false; + + while ( ( s = schemaFile.readLine() ) != null ) + { + Matcher matcher = regex.matcher( s ); + if ( matcher.matches() ) + { + matchesFound = true; + entries.add( readLdif( s ).getEntry() ); + } + else if ( matchesFound ) + { + break; + } + + if ( schemaFile.getFilePointer() >= endOffset ) + { + break; + } + } + + return entries; + } + catch ( Exception e ) + { + throw new LdapException( e.getMessage(), e ); + } + + } + + + private Pattern getPattern( Schema schema, String schemaObjectTypeRdn ) + { + Pattern regex = Pattern.compile( + "dn:\\s*m-oid=[0-9\\.]*" + ",ou=" + schemaObjectTypeRdn + ",cn=" + schema.getSchemaName() + ",ou=schema", + Pattern.CASE_INSENSITIVE ); + + return regex; + } + + + private List loadSchemaObjects( String schemaObjectType, Schema... schemas ) throws LdapException, + IOException + { + List scObjTypeList = new ArrayList(); + + if ( schemas == null ) + { + return scObjTypeList; + } + + for ( Schema schema : schemas ) + { + SchemaMarker marker = markerMap.get( schema.getSchemaName() ); + schemaFile.seek( marker.getStart() ); + + Pattern scObjEntryRegex = getPattern( schema, schemaObjectType ); + + scObjTypeList.addAll( getMatchingEntries( scObjEntryRegex, marker.getEnd() ) ); + } + + return scObjTypeList; + } + + + /** + * {@inheritDoc} + */ + public List loadAttributeTypes( Schema... schemas ) throws LdapException, IOException + { + + return loadSchemaObjects( "attributetypes", schemas ); + } + + + /** + * {@inheritDoc} + */ + public List loadComparators( Schema... schemas ) throws LdapException, IOException + { + return loadSchemaObjects( "comparators", schemas ); + } + + + /** + * {@inheritDoc} + */ + public List loadDitContentRules( Schema... schemas ) throws LdapException, IOException + { + return loadSchemaObjects( "ditContentRules", schemas ); + } + + + /** + * {@inheritDoc} + */ + public List loadDitStructureRules( Schema... schemas ) throws LdapException, IOException + { + return loadSchemaObjects( "ditStructureRules", schemas ); + } + + + /** + * {@inheritDoc} + */ + public List loadMatchingRules( Schema... schemas ) throws LdapException, IOException + { + return loadSchemaObjects( "matchingRules", schemas ); + } + + + /** + * {@inheritDoc} + */ + public List loadMatchingRuleUses( Schema... schemas ) throws LdapException, IOException + { + return loadSchemaObjects( "matchingRuleUse", schemas ); + } + + + /** + * {@inheritDoc} + */ + public List loadNameForms( Schema... schemas ) throws LdapException, IOException + { + return loadSchemaObjects( "nameForms", schemas ); + } + + + /** + * {@inheritDoc} + */ + public List loadNormalizers( Schema... schemas ) throws LdapException, IOException + { + return loadSchemaObjects( "normalizers", schemas ); + } + + + /** + * {@inheritDoc} + */ + public List loadObjectClasses( Schema... schemas ) throws LdapException, IOException + { + return loadSchemaObjects( "objectClasses", schemas ); + } + + + /** + * {@inheritDoc} + */ + public List loadSyntaxes( Schema... schemas ) throws LdapException, IOException + { + return loadSchemaObjects( "syntaxes", schemas ); + } + + + /** + * {@inheritDoc} + */ + public List loadSyntaxCheckers( Schema... schemas ) throws LdapException, IOException + { + return loadSchemaObjects( "syntaxCheckers", schemas ); + } + + + // a simple manual test method + public static void main( String[] args ) throws Exception + { + SingleLdifSchemaLoader loader = new SingleLdifSchemaLoader(); + + Schema schema = loader.getSchema( "inetorgperson" ); + + System.out.println( schema ); + + List attrList = loader.loadAttributeTypes( schema ); + assert ( 9 == attrList.size() ); + } + +} + +class SchemaMarker +{ + private int start; + private int end; + + + public SchemaMarker( int start ) + { + this.start = start; + } + + + public void setEnd( int end ) + { + this.end = end; + } + + + public int getStart() + { + return start; + } + + + public int getEnd() + { + return end; + } +}