You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by ak...@apache.org on 2004/09/30 06:35:02 UTC
svn commit: rev 47553 - incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db
Author: akarasulu
Date: Wed Sep 29 21:35:00 2004
New Revision: 47553
Removed:
incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/DatabaseEnabled.java
incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/EnumeratorDependent.java
incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/LeafEvaluatorImpl.java
incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/NegationEnumeratorImpl.java
incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/ScopeEnumeratorImpl.java
incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/ScopeEvaluatorImpl.java
incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/SubstringEnumeratorImpl.java
incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/SubstringEvaluatorImpl.java
Modified:
incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/ConjunctionEnumerator.java
incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/DupsEnumeration.java
incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/EnumeratorImpl.java
incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/EnumeratorMonitorAdapter.java
incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/LeafEvaluator.java
incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/NegationEnumerator.java
incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/ScopeEnumerator.java
incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/ScopeEvaluator.java
incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/SubstringEnumerator.java
incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/SubstringEvaluator.java
Log:
Removed a bunch of do nothing interfaces that extended Evaluator and Enumerator
and renamed the Impl class to the old name of the deleted interface.
Modified: incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/ConjunctionEnumerator.java
==============================================================================
--- incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/ConjunctionEnumerator.java (original)
+++ incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/ConjunctionEnumerator.java Wed Sep 29 21:35:00 2004
@@ -1,3 +1,19 @@
+/*
+ * 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.eve.db;
@@ -15,6 +31,8 @@
* An enumerator implementation which creates a NamingEnumeration over the
* candidates satisfying a filter expression of AND'ed filter sub-expressions.
*
+ * @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
+ * @version $Rev$
*/
public class ConjunctionEnumerator implements Enumerator
{
Modified: incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/DupsEnumeration.java
==============================================================================
--- incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/DupsEnumeration.java (original)
+++ incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/DupsEnumeration.java Wed Sep 29 21:35:00 2004
@@ -38,8 +38,7 @@
* @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
* @version $Rev$
*/
-public class DupsEnumeration
- implements NamingEnumeration
+public class DupsEnumeration implements NamingEnumeration
{
/** Marker for whether or not next() will return successfully */
private boolean hasMore = true;
Modified: incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/EnumeratorImpl.java
==============================================================================
--- incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/EnumeratorImpl.java (original)
+++ incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/EnumeratorImpl.java Wed Sep 29 21:35:00 2004
@@ -59,11 +59,11 @@
LeafEvaluator leafEvaluator )
{
this.db = db;
- scopeEnumerator = new ScopeEnumeratorImpl();
- substringEnumerator = new SubstringEnumeratorImpl();
+ scopeEnumerator = new ScopeEnumerator();
+ substringEnumerator = new SubstringEnumerator();
conjunctionEnumerator = new ConjunctionEnumerator( this, topEvaluator );
disjunctionEnumerator = new DisjunctionEnumerator( this );
- negationEnumerator = new NegationEnumeratorImpl();
+ negationEnumerator = new NegationEnumerator();
}
Modified: incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/EnumeratorMonitorAdapter.java
==============================================================================
--- incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/EnumeratorMonitorAdapter.java (original)
+++ incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/EnumeratorMonitorAdapter.java Wed Sep 29 21:35:00 2004
@@ -19,8 +19,7 @@
/**
* Document me.
*
- * @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory
- * Project</a>
+ * @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
* @version $Rev$
*/
public class EnumeratorMonitorAdapter implements EnumeratorMonitor
Modified: incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/LeafEvaluator.java
==============================================================================
--- incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/LeafEvaluator.java (original)
+++ incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/LeafEvaluator.java Wed Sep 29 21:35:00 2004
@@ -17,12 +17,291 @@
package org.apache.eve.db;
+import java.math.BigInteger;
+import java.util.Comparator;
+
+import javax.naming.NamingException;
+import javax.naming.NamingEnumeration;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+
+import org.apache.ldap.common.filter.ExprNode;
+import org.apache.ldap.common.filter.LeafNode;
+import org.apache.ldap.common.filter.ScopeNode;
+import org.apache.ldap.common.filter.SimpleNode;
+import org.apache.ldap.common.schema.Normalizer;
+import org.apache.ldap.common.filter.PresenceNode;
+import org.apache.ldap.common.NotImplementedException;
+
+import org.apache.eve.schema.NormalizerRegistry;
+import org.apache.eve.schema.ComparatorRegistry;
+
+
/**
- * Interface for leaf node evaluation.
+ * Evaluates LeafNode assertions on candidates using a database.
*
* @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
* @version $Rev$
*/
-public interface LeafEvaluator extends Evaluator
+public class LeafEvaluator implements Evaluator
{
-}
\ No newline at end of file
+ /** Database used to evaluate leaf with */
+ private Database db;
+ /** Normalizer registry for up value normalization */
+ private NormalizerRegistry normalizerRegistry;
+ /** Comparator registry for comparing normalized values */
+ private ComparatorRegistry comparatorRegistry;
+ /** Substring node evaluator we depend on */
+ private SubstringEvaluator substringEvaluator;
+ /** ScopeNode evaluator we depend on */
+ private ScopeEvaluator scopeEvaluator;
+
+
+
+ public LeafEvaluator( Database db,
+ ScopeEvaluator scopeEvaluator,
+ NormalizerRegistry normalizerRegistry,
+ ComparatorRegistry comparatorRegistry,
+ SubstringEvaluator substringEvaluator )
+ {
+ this.db = db;
+ this.scopeEvaluator = scopeEvaluator;
+ this.normalizerRegistry = normalizerRegistry;
+ this.comparatorRegistry = comparatorRegistry;
+ this.substringEvaluator = substringEvaluator;
+ }
+
+
+ /**
+ * @see org.apache.eve.db.Evaluator#evaluate(ExprNode, IndexRecord)
+ */
+ public boolean evaluate( ExprNode node, IndexRecord record )
+ throws NamingException
+ {
+ if ( node instanceof ScopeNode )
+ {
+ return scopeEvaluator.evaluate( node, record );
+ }
+
+ switch( ( ( LeafNode ) node ).getAssertionType() )
+ {
+ case( LeafNode.APPROXIMATE ):
+ return evalEquality( ( SimpleNode ) node, record );
+ case( LeafNode.EQUALITY ):
+ return evalEquality( ( SimpleNode ) node, record );
+ case( LeafNode.EXTENSIBLE ):
+ throw new NotImplementedException();
+ case( LeafNode.GREATEREQ ):
+ return evalGreater( ( SimpleNode ) node, record, true );
+ case( LeafNode.LESSEQ ):
+ return evalGreater( ( SimpleNode ) node, record, false );
+ case( LeafNode.PRESENCE ):
+ String attrId = ( ( PresenceNode ) node ).getAttribute();
+ return evalPresence( attrId, record );
+ case( LeafNode.SUBSTRING ):
+ return substringEvaluator.evaluate( node, record );
+ default:
+ throw new NamingException( "Unrecognized leaf node type: "
+ + ( ( LeafNode ) node ).getAssertionType() );
+ }
+ }
+
+
+ /**
+ * Evaluates a simple greater than or less than attribute value assertion on
+ * a perspective candidate.
+ *
+ * @param node the greater than or less than node to evaluate
+ * @param record the IndexRecord of the perspective candidate
+ * @param isGreater true if it is a greater than or equal to comparison,
+ * false if it is a less than or equal to comparison.
+ * @return the ava evaluation on the perspective candidate
+ * @throws NamingException if there is a database access failure
+ */
+ private boolean evalGreater( SimpleNode node, IndexRecord record,
+ boolean isGreater ) throws NamingException
+ {
+ String attrId = node.getAttribute();
+ BigInteger id = record.getEntryId();
+
+ if ( db.hasUserIndexOn( attrId ) )
+ {
+ Index idx = db.getUserIndex( attrId );
+
+ if ( isGreater )
+ {
+ return idx.hasValue( node.getValue(), id, true );
+ }
+
+ return idx.hasValue( node.getValue(), id, false );
+ }
+
+ // resusitate entry if need be
+ if ( null == record.getAttributes() )
+ {
+ record.setAttributes( db.lookup( id ) );
+ }
+
+ // get the attribute associated with the node
+ Attribute attr = record.getAttributes().get( attrId );
+
+ // If we do not have the attribute just return false
+ if ( null == attr )
+ {
+ return false;
+ }
+
+ /*
+ * We need to iterate through all values and for each value we normalize
+ * and use the comparator to determine if a match exists.
+ */
+ Normalizer normalizer = normalizerRegistry.getEquality( attrId );
+ Comparator comparator = comparatorRegistry.getEquality( attrId );
+ Object filterValue = normalizer.normalize( node.getValue() );
+ NamingEnumeration list = attr.getAll();
+
+ /*
+ * Cheaper to not check isGreater in one loop - better to separate
+ * out into two loops which you choose to execute based on isGreater
+ */
+ if ( isGreater )
+ {
+ while ( list.hasMore() )
+ {
+ Object value = normalizer.normalize( list.next() );
+
+ // Found a value that is greater than or equal to the ava value
+ if ( 0 >= comparator.compare( value, filterValue ) )
+ {
+ return true;
+ }
+ }
+ }
+ else
+ {
+ while ( list.hasMore() )
+ {
+ Object value = normalizer.normalize( list.next() );
+
+ // Found a value that is less than or equal to the ava value
+ if ( 0 <= comparator.compare( value, filterValue ) )
+ {
+ return true;
+ }
+ }
+ }
+
+ // no match so return false
+ return false;
+ }
+
+
+ /**
+ * Evaluates a simple presence attribute value assertion on a perspective
+ * candidate.
+ *
+ * @param attrId the name of the attribute tested for presence
+ * @param rec the IndexRecord of the perspective candidate
+ * @return the ava evaluation on the perspective candidate
+ * @throws NamingException if there is a database access failure
+ */
+ private boolean evalPresence( String attrId, IndexRecord rec )
+ throws NamingException
+ {
+ if ( db.hasUserIndexOn( attrId ) )
+ {
+ Index idx = db.getExistanceIndex();
+ return idx.hasValue( attrId, rec.getEntryId() );
+ }
+
+ // resusitate entry if need be
+ if ( null == rec.getAttributes() )
+ {
+ rec.setAttributes( db.lookup( rec.getEntryId() ) );
+ }
+
+ // get the attribute associated with the node
+ Attributes attrs = rec.getAttributes();
+ return null != attrs.get( attrId );
+ }
+
+
+ /**
+ * Evaluates a simple equality attribute value assertion on a perspective
+ * candidate.
+ *
+ * @param node the equality node to evaluate
+ * @param rec the IndexRecord of the perspective candidate
+ * @return the ava evaluation on the perspective candidate
+ * @throws NamingException if there is a database access failure
+ */
+ private boolean evalEquality( SimpleNode node, IndexRecord rec )
+ throws NamingException
+ {
+ if ( db.hasUserIndexOn( node.getAttribute() ) )
+ {
+ Index idx = db.getUserIndex( node.getAttribute() );
+ return idx.hasValue( node.getValue(), rec.getEntryId() );
+ }
+
+ Normalizer normalizer = normalizerRegistry.getEquality( node.getAttribute() );
+ Comparator comparator = comparatorRegistry.getEquality( node.getAttribute() );
+
+ /*
+ * Get the attribute and if it is not set in rec then resusitate it
+ * from the master table and set it in rec for use later if at all.
+ * Before iterating through all values for a match check to see if the
+ * AVA value is contained or the normalized form of the AVA value is
+ * contained.
+ */
+
+ // resusitate entry if need be
+ if ( null == rec.getAttributes() )
+ {
+ rec.setAttributes( db.lookup( rec.getEntryId() ) );
+ }
+
+ // get the attribute associated with the node
+ Attribute attr = rec.getAttributes().get( node.getAttribute() );
+
+ // If we do not have the attribute just return false
+ if ( null == attr )
+ {
+ return false;
+ }
+
+ // check if AVA value exists in attribute
+ if ( attr.contains( node.getValue() ) )
+ {
+ return true;
+ }
+
+ // get the normalized AVA filter value
+ Object filterValue = normalizer.normalize( node.getValue() );
+
+ // check if the normalized value is present
+ if ( attr.contains( filterValue ) )
+ {
+ return true;
+ }
+
+ /*
+ * We need to now iterate through all values because we could not get
+ * a lookup to work. For each value we normalize and use the comparator
+ * to determine if a match exists.
+ */
+ NamingEnumeration list = attr.getAll();
+ while ( list.hasMore() )
+ {
+ Object value = normalizer.normalize( list.next() );
+
+ if ( 0 == comparator.compare( value, filterValue ) )
+ {
+ return true;
+ }
+ }
+
+ // no match so return false
+ return false;
+ }
+}
Modified: incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/NegationEnumerator.java
==============================================================================
--- incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/NegationEnumerator.java (original)
+++ incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/NegationEnumerator.java Wed Sep 29 21:35:00 2004
@@ -17,13 +17,79 @@
package org.apache.eve.db;
+import javax.naming.NamingException;
+import javax.naming.NamingEnumeration;
+
+import org.apache.ldap.common.filter.ExprNode;
+import org.apache.ldap.common.filter.LeafNode;
+import org.apache.ldap.common.filter.BranchNode;
+
+
/**
- * Creates Enumerations over a set of entry candidates based on a negated
- * expression.
+ * Creates a naming enumeration over the set of candidates accepted by a negated
+ * filter expression.
*
* @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
* @version $Rev$
*/
-public interface NegationEnumerator extends Enumerator
+public class NegationEnumerator implements Enumerator
{
+ /** Database this conjunction is applied upon */
+ private Database db = null;
+ /** Top level expression evaluator */
+ private Evaluator evaluator;
+
+
+ /**
+ * Creates a negation branch node enumerator.
+ *
+ * @param db the database to use for enumerations
+ * @param evaluator the top level evaluator
+ */
+ public NegationEnumerator( Database db, Evaluator evaluator )
+ {
+ this.db = db;
+ this.evaluator = evaluator;
+ }
+
+
+ /**
+ * @see Enumerator#enumerate(ExprNode)
+ */
+ public NamingEnumeration enumerate( ExprNode node ) throws NamingException
+ {
+ Index idx = null;
+ final BranchNode bnode = ( BranchNode ) node;
+ NamingEnumeration childEnumeration = null;
+ NamingEnumeration enumeration = null;
+
+ // Iterates over entire set of index values
+ if ( bnode.getChild().isLeaf() )
+ {
+ LeafNode child = ( LeafNode ) bnode.getChild();
+ idx = db.getUserIndex( child.getAttribute() );
+ childEnumeration = idx.listIndices();
+ }
+ // Iterates over the entire set of entries
+ else
+ {
+ idx = db.getNdnIndex();
+ childEnumeration = idx.listIndices();
+ }
+
+
+ IndexAssertion assertion = new IndexAssertion()
+ {
+ public boolean assertCandidate( IndexRecord rec ) throws NamingException
+ {
+ // NOTICE THE ! HERE
+ // The candidate is valid if it does not pass assertion. A
+ // candidate that passes assertion is therefore invalid.
+ return ! evaluator.evaluate( bnode.getChild(), rec );
+ }
+ };
+
+ enumeration = new IndexAssertionEnumeration( childEnumeration, assertion, true );
+ return enumeration;
+ }
}
Modified: incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/ScopeEnumerator.java
==============================================================================
--- incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/ScopeEnumerator.java (original)
+++ incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/ScopeEnumerator.java Wed Sep 29 21:35:00 2004
@@ -17,12 +17,221 @@
package org.apache.eve.db;
+import java.math.BigInteger;
+
+import javax.naming.NamingException;
+import javax.naming.NamingEnumeration;
+import javax.naming.directory.SearchControls;
+
+import org.apache.ldap.common.filter.ExprNode;
+import org.apache.ldap.common.filter.ScopeNode;
+import org.apache.ldap.common.util.SingletonEnumeration;
+
+
/**
- * Creates Enumerations over a set of entry candidates based on scope.
+ * Enumerates candidates based on scope.
*
* @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
* @version $Rev$
*/
-public interface ScopeEnumerator extends Enumerator
+public class ScopeEnumerator implements Enumerator
{
+ /** Database used to enumerate based on scope */
+ private Database db = null;
+ /** Filter scope expression evaluator */
+ private ScopeEvaluator evaluator = null;
+
+
+ public ScopeEnumerator( Database db, ScopeEvaluator evaluator )
+ {
+ this.db = db;
+ this.evaluator = evaluator;
+ }
+
+
+ /**
+ * Builds an enumeration over all entries that satisfy the constraints of
+ * the scope assertion node.
+ *
+ * @param node the scope node
+ * @return the candidates that are within scope
+ * @throws NamingException if any system indices fail
+ * @see Enumerator#enumerate(ExprNode)
+ */
+ public NamingEnumeration enumerate( ExprNode node ) throws NamingException
+ {
+ final ScopeNode snode = ( ScopeNode ) node;
+ final BigInteger id = db.getEntryId( snode.getBaseDn() );
+
+ switch( snode.getScope() )
+ {
+ case( SearchControls.OBJECT_SCOPE ):
+ final IndexRecord record = new IndexRecord();
+ record.setEntryId( id );
+ record.setIndexKey( snode.getBaseDn() );
+ return new SingletonEnumeration( record );
+ case( SearchControls.ONELEVEL_SCOPE ):
+ return enumerateChildren( snode.getBaseDn(),
+ snode.getDerefAliases().derefInSearching() );
+ case( SearchControls.SUBTREE_SCOPE ):
+ return enumerateDescendants( snode );
+ default:
+ throw new NamingException( "Unrecognized search scope!" );
+ }
+ }
+
+
+ /**
+ * Constructs an enumeration over all entries within one level scope even
+ * when aliases are enabled while searching.
+ *
+ * @param dn the base dn
+ * @param deref whether or not we dereference while searching
+ * @return the enumeration of all entries in direct or alias extended one
+ * level scope to the base
+ * @throws NamingException if any failures occur while accessing system
+ * indices.
+ */
+ private NamingEnumeration enumerateChildren( String dn, boolean deref )
+ throws NamingException
+ {
+ Index idx = db.getHeirarchyIndex();
+ final BigInteger id = db.getEntryId( dn );
+ final NamingEnumeration children = idx.listIndices( id );
+
+ /*
+ * If alias dereferencing is not enabled while searching then we just
+ * return the enumeration of the base entry's children.
+ */
+ if ( ! deref )
+ {
+ return children;
+ }
+
+ /* ====================================================================
+ * From here on Dereferencing while searching is enabled
+ * ====================================================================
+ *
+ * Dereferencing in search is enabled so we need to wrap the child
+ * listing with an assertion enumeration to weed out aliases that will
+ * not be returned. Next we need to compose an enumeration which
+ * combines the list of non-alias child entries with those entries that
+ * are brought into one level scope by aliases.
+ */
+
+ // List all entries brought into one level scope at base by aliases
+ idx = db.getOneAliasIndex();
+ NamingEnumeration aliasIntroduced = idx.listIndices( id );
+
+ // Still need to use assertion enum to weed out aliases
+ NamingEnumeration nonAliasChildren = new IndexAssertionEnumeration(
+ children, new AssertNotAlias() );
+
+ // Combine both into one enumeration
+ NamingEnumeration [] all = {nonAliasChildren, aliasIntroduced};
+ return new DisjunctionEnumeration( all );
+ }
+
+
+ /**
+ * Constructs an enumeration over all entries within subtree scope even
+ * when aliases are enabled while searching.
+ *
+ * @param node the scope node
+ * @return the enumeration of all entries in direct or alias extended
+ * subtree scope to the base
+ * @throws NamingException if any failures occur while accessing system
+ * indices.
+ */
+ private NamingEnumeration enumerateDescendants( final ScopeNode node )
+ throws NamingException
+ {
+ Index idx = null;
+
+ /*
+ * If we do not dereference while searching then we simply return any
+ * entry that is not a descendant of the base.
+ */
+ if ( ! node.getDerefAliases().derefInSearching() )
+ {
+ // Gets a NamingEnumeration over all elements
+ idx = db.getNdnIndex();
+ NamingEnumeration underlying = idx.listIndices();
+ return new IndexAssertionEnumeration( underlying,
+ new AssertDescendant( node ) );
+ }
+
+ // Create an assertion to assert or evaluate an expression
+ IndexAssertion assertion = new IndexAssertion()
+ {
+ public boolean assertCandidate( IndexRecord rec )
+ throws NamingException
+ {
+ return evaluator.evaluate( node, rec );
+ }
+ };
+
+ // Gets a NamingEnumeration over all elements
+ idx = db.getNdnIndex();
+ NamingEnumeration underlying = idx.listIndices();
+ return new IndexAssertionEnumeration( underlying, assertion );
+ }
+
+
+ /**
+ * Asserts an entry is a descendant.
+ */
+ class AssertDescendant implements IndexAssertion
+ {
+ /** Scope node with base and alias info */
+ private final ScopeNode scope;
+
+
+ /**
+ * Creates a assertion using a ScopeNode to determine the search base.
+ *
+ * @param node the scope node with search base
+ */
+ AssertDescendant( final ScopeNode node )
+ {
+ scope = node;
+ }
+
+
+ /**
+ * Returns true if the candidate with id is a descendant of the base,
+ * false otherwise.
+ *
+ * @see IndexAssertion#assertCandidate(IndexRecord)
+ */
+ public boolean assertCandidate( IndexRecord record ) throws NamingException
+ {
+ String dn = db.getEntryDn( record.getEntryId() );
+ return dn.endsWith( scope.getBaseDn() );
+ }
+ }
+
+
+ /**
+ * Asserts an entry is NOT an alias.
+ */
+ class AssertNotAlias implements IndexAssertion
+ {
+ /**
+ * Returns true if the candidate is not an alias, false otherwise.
+ *
+ * @see IndexAssertion#assertCandidate(IndexRecord)
+ */
+ public boolean assertCandidate( IndexRecord record ) throws NamingException
+ {
+ Index aliasIdx = db.getAliasIndex();
+
+ if ( null == aliasIdx.reverseLookup( record.getEntryId() ) )
+ {
+ return true;
+ }
+
+ return false;
+ }
+ }
}
Modified: incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/ScopeEvaluator.java
==============================================================================
--- incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/ScopeEvaluator.java (original)
+++ incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/ScopeEvaluator.java Wed Sep 29 21:35:00 2004
@@ -1,5 +1,193 @@
/*
- * Copyright 2004 The Apache Software Foundation
+ * Apache License
+ * Version 2.0, January 2004
+ * http://www.apache.org/licenses/
+ *
+ * TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+ *
+ * 1. Definitions.
+ *
+ * "License" shall mean the terms and conditions for use, reproduction,
+ * and distribution as defined by Sections 1 through 9 of this document.
+ *
+ * "Licensor" shall mean the copyright owner or entity authorized by
+ * the copyright owner that is granting the License.
+ *
+ * "Legal Entity" shall mean the union of the acting entity and all
+ * other entities that control, are controlled by, or are under common
+ * control with that entity. For the purposes of this definition,
+ * "control" means (i) the power, direct or indirect, to cause the
+ * direction or management of such entity, whether by contract or
+ * otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ * outstanding shares, or (iii) beneficial ownership of such entity.
+ *
+ * "You" (or "Your") shall mean an individual or Legal Entity
+ * exercising permissions granted by this License.
+ *
+ * "Source" form shall mean the preferred form for making modifications,
+ * including but not limited to software source code, documentation
+ * source, and configuration files.
+ *
+ * "Object" form shall mean any form resulting from mechanical
+ * transformation or translation of a Source form, including but
+ * not limited to compiled object code, generated documentation,
+ * and conversions to other media types.
+ *
+ * "Work" shall mean the work of authorship, whether in Source or
+ * Object form, made available under the License, as indicated by a
+ * copyright notice that is included in or attached to the work
+ * (an example is provided in the Appendix below).
+ *
+ * "Derivative Works" shall mean any work, whether in Source or Object
+ * form, that is based on (or derived from) the Work and for which the
+ * editorial revisions, annotations, elaborations, or other modifications
+ * represent, as a whole, an original work of authorship. For the purposes
+ * of this License, Derivative Works shall not include works that remain
+ * separable from, or merely link (or bind by name) to the interfaces of,
+ * the Work and Derivative Works thereof.
+ *
+ * "Contribution" shall mean any work of authorship, including
+ * the original version of the Work and any modifications or additions
+ * to that Work or Derivative Works thereof, that is intentionally
+ * submitted to Licensor for inclusion in the Work by the copyright owner
+ * or by an individual or Legal Entity authorized to submit on behalf of
+ * the copyright owner. For the purposes of this definition, "submitted"
+ * means any form of electronic, verbal, or written communication sent
+ * to the Licensor or its representatives, including but not limited to
+ * communication on electronic mailing lists, source code control systems,
+ * and issue tracking systems that are managed by, or on behalf of, the
+ * Licensor for the purpose of discussing and improving the Work, but
+ * excluding communication that is conspicuously marked or otherwise
+ * designated in writing by the copyright owner as "Not a Contribution."
+ *
+ * "Contributor" shall mean Licensor and any individual or Legal Entity
+ * on behalf of whom a Contribution has been received by Licensor and
+ * subsequently incorporated within the Work.
+ *
+ * 2. Grant of Copyright License. Subject to the terms and conditions of
+ * this License, each Contributor hereby grants to You a perpetual,
+ * worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ * copyright license to reproduce, prepare Derivative Works of,
+ * publicly display, publicly perform, sublicense, and distribute the
+ * Work and such Derivative Works in Source or Object form.
+ *
+ * 3. Grant of Patent License. Subject to the terms and conditions of
+ * this License, each Contributor hereby grants to You a perpetual,
+ * worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ * (except as stated in this section) patent license to make, have made,
+ * use, offer to sell, sell, import, and otherwise transfer the Work,
+ * where such license applies only to those patent claims licensable
+ * by such Contributor that are necessarily infringed by their
+ * Contribution(s) alone or by combination of their Contribution(s)
+ * with the Work to which such Contribution(s) was submitted. If You
+ * institute patent litigation against any entity (including a
+ * cross-claim or counterclaim in a lawsuit) alleging that the Work
+ * or a Contribution incorporated within the Work constitutes direct
+ * or contributory patent infringement, then any patent licenses
+ * granted to You under this License for that Work shall terminate
+ * as of the date such litigation is filed.
+ *
+ * 4. Redistribution. You may reproduce and distribute copies of the
+ * Work or Derivative Works thereof in any medium, with or without
+ * modifications, and in Source or Object form, provided that You
+ * meet the following conditions:
+ *
+ * (a) You must give any other recipients of the Work or
+ * Derivative Works a copy of this License; and
+ *
+ * (b) You must cause any modified files to carry prominent notices
+ * stating that You changed the files; and
+ *
+ * (c) You must retain, in the Source form of any Derivative Works
+ * that You distribute, all copyright, patent, trademark, and
+ * attribution notices from the Source form of the Work,
+ * excluding those notices that do not pertain to any part of
+ * the Derivative Works; and
+ *
+ * (d) If the Work includes a "NOTICE" text file as part of its
+ * distribution, then any Derivative Works that You distribute must
+ * include a readable copy of the attribution notices contained
+ * within such NOTICE file, excluding those notices that do not
+ * pertain to any part of the Derivative Works, in at least one
+ * of the following places: within a NOTICE text file distributed
+ * as part of the Derivative Works; within the Source form or
+ * documentation, if provided along with the Derivative Works; or,
+ * within a display generated by the Derivative Works, if and
+ * wherever such third-party notices normally appear. The contents
+ * of the NOTICE file are for informational purposes only and
+ * do not modify the License. You may add Your own attribution
+ * notices within Derivative Works that You distribute, alongside
+ * or as an addendum to the NOTICE text from the Work, provided
+ * that such additional attribution notices cannot be construed
+ * as modifying the License.
+ *
+ * You may add Your own copyright statement to Your modifications and
+ * may provide additional or different license terms and conditions
+ * for use, reproduction, or distribution of Your modifications, or
+ * for any such Derivative Works as a whole, provided Your use,
+ * reproduction, and distribution of the Work otherwise complies with
+ * the conditions stated in this License.
+ *
+ * 5. Submission of Contributions. Unless You explicitly state otherwise,
+ * any Contribution intentionally submitted for inclusion in the Work
+ * by You to the Licensor shall be under the terms and conditions of
+ * this License, without any additional terms or conditions.
+ * Notwithstanding the above, nothing herein shall supersede or modify
+ * the terms of any separate license agreement you may have executed
+ * with Licensor regarding such Contributions.
+ *
+ * 6. Trademarks. This License does not grant permission to use the trade
+ * names, trademarks, service marks, or product names of the Licensor,
+ * except as required for reasonable and customary use in describing the
+ * origin of the Work and reproducing the content of the NOTICE file.
+ *
+ * 7. Disclaimer of Warranty. Unless required by applicable law or
+ * agreed to in writing, Licensor provides the Work (and each
+ * Contributor provides its Contributions) on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied, including, without limitation, any warranties or conditions
+ * of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ * PARTICULAR PURPOSE. You are solely responsible for determining the
+ * appropriateness of using or redistributing the Work and assume any
+ * risks associated with Your exercise of permissions under this License.
+ *
+ * 8. Limitation of Liability. In no event and under no legal theory,
+ * whether in tort (including negligence), contract, or otherwise,
+ * unless required by applicable law (such as deliberate and grossly
+ * negligent acts) or agreed to in writing, shall any Contributor be
+ * liable to You for damages, including any direct, indirect, special,
+ * incidental, or consequential damages of any character arising as a
+ * result of this License or out of the use or inability to use the
+ * Work (including but not limited to damages for loss of goodwill,
+ * work stoppage, computer failure or malfunction, or any and all
+ * other commercial damages or losses), even if such Contributor
+ * has been advised of the possibility of such damages.
+ *
+ * 9. Accepting Warranty or Additional Liability. While redistributing
+ * the Work or Derivative Works thereof, You may choose to offer,
+ * and charge a fee for, acceptance of support, warranty, indemnity,
+ * or other liability obligations and/or rights consistent with this
+ * License. However, in accepting such obligations, You may act only
+ * on Your own behalf and on Your sole responsibility, not on behalf
+ * of any other Contributor, and only if You agree to indemnify,
+ * defend, and hold each Contributor harmless for any liability
+ * incurred by, or claims asserted against, such Contributor by reason
+ * of your accepting any such warranty or additional liability.
+ *
+ * END OF TERMS AND CONDITIONS
+ *
+ * APPENDIX: How to apply the Apache License to your work.
+ *
+ * To apply the Apache License to your work, attach the following
+ * boilerplate notice, with the fields enclosed by brackets "[]"
+ * replaced with your own identifying information. (Don't include
+ * the brackets!) The text should be enclosed in the appropriate
+ * comment syntax for the file format. We also recommend that a
+ * file or class name and description of purpose be included on the
+ * same "printed page" as the copyright notice for easier
+ * identification within third-party archives.
+ *
+ * Copyright [yyyy] [name of copyright owner]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,15 +202,200 @@
* limitations under the License.
*
*/
+
+/*
+ * $Id: ScopeEvaluator.java,v 1.3 2003/10/15 01:59:46 akarasulu Exp $
+ *
+ * -- (c) LDAPd Group --
+ * -- Please refer to the LICENSE.txt file in the root directory of --
+ * -- any LDAPd project for copyright and distribution information. --
+ *
+ * Created on Oct 9, 2003
+ */
package org.apache.eve.db;
+import java.math.BigInteger;
+
+import javax.naming.NamingException;
+import javax.naming.directory.SearchControls;
+
+import org.apache.ldap.common.filter.ExprNode;
+import org.apache.ldap.common.filter.ScopeNode;
+import org.apache.ldap.common.message.DerefAliasesEnum;
+
+
/**
- * Evaluator interface for handling scope node evaluations.
+ * Evaluates ScopeNode assertions on candidates using a database.
*
* @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
* @version $Rev$
*/
-public interface ScopeEvaluator extends Evaluator
+public class ScopeEvaluator implements Evaluator
{
-}
\ No newline at end of file
+ /** Database used to evaluate scope with */
+ private Database db;
+
+
+ /**
+ * Creates a scope node evaluator for search expressions.
+ *
+ * @param db the database used to evaluate scope node
+ */
+ public ScopeEvaluator( Database db )
+ {
+ this.db = db;
+ }
+
+
+ /**
+ * @see org.apache.eve.db.Evaluator#evaluate(ExprNode, IndexRecord)
+ */
+ public boolean evaluate( ExprNode node, IndexRecord record )
+ throws NamingException
+ {
+ ScopeNode snode = ( ScopeNode ) node;
+
+ switch( snode.getScope() )
+ {
+ case( SearchControls.OBJECT_SCOPE ):
+ String dn = db.getEntryDn( record.getEntryId() );
+ return dn.equals( snode.getBaseDn() );
+ case( SearchControls.ONELEVEL_SCOPE ):
+ return assertOneLevelScope( snode, record.getEntryId() );
+ case( SearchControls.SUBTREE_SCOPE ):
+ return assertSubtreeScope( snode, record.getEntryId() );
+ default:
+ throw new NamingException( "Unrecognized search scope!" );
+ }
+ }
+
+
+ /**
+ * Asserts whether or not a candidate has one level scope while taking
+ * alias dereferencing into account.
+ *
+ * @param node the scope node containing the base and alias handling mode
+ * @param id the candidate to assert which can be any db entry's id
+ * @return true if the candidate is within one level scope whether or not
+ * alias dereferencing is enabled.
+ * @throws NamingException if the index lookups fail.
+ */
+ public boolean assertSubtreeScope( final ScopeNode node,
+ final BigInteger id ) throws NamingException
+ {
+ String dn = db.getEntryDn( id );
+ DerefAliasesEnum mode = node.getDerefAliases();
+ Object baseId = db.getEntryId( node.getBaseDn() );
+ boolean isDescendant = dn.endsWith( node.getBaseDn() );
+
+ /*
+ * The candidate id could be any entry in the db. If search
+ * dereferencing is not enabled then we return the results of the
+ * descendant test.
+ */
+ if ( ! mode.derefInSearching() )
+ {
+ return isDescendant;
+ }
+
+ /*
+ * From here down alias dereferencing is enabled. We determine if the
+ * candidate id is an alias, if so we reject it since aliases should
+ * not be returned.
+ */
+ Index idx = db.getAliasIndex();
+ if ( null != idx.reverseLookup( id ) )
+ {
+ return false;
+ }
+
+ /*
+ * The candidate is NOT an alias at this point. So if it is a
+ * descendant we just return it since it is in normal subtree scope.
+ */
+ if ( isDescendant )
+ {
+ return true;
+ }
+
+ /*
+ * At this point the candidate is not a descendant and it is not an
+ * alias. We need to check if the candidate is in extended subtree
+ * scope by performing a lookup on the subtree alias index. This index
+ * stores a tuple mapping the baseId to the ids of objects brought
+ * into subtree scope of the base by an alias:
+ *
+ * ( baseId, aliasedObjId )
+ *
+ * If the candidate id is an object brought into subtree scope then
+ * the lookup returns true accepting the candidate. Otherwise the
+ * candidate is rejected with a false return because it is not in scope.
+ */
+ idx = db.getSubAliasIndex();
+ return idx.hasValue( baseId, id );
+ }
+
+
+ /**
+ * Asserts whether or not a candidate has one level scope while taking
+ * alias dereferencing into account.
+ *
+ * @param node the scope node containing the base and alias handling mode
+ * @param id the candidate to assert which can be any db entry's id
+ * @return true if the candidate is within one level scope whether or not
+ * alias dereferencing is enabled.
+ * @throws NamingException if the index lookups fail.
+ */
+ public boolean assertOneLevelScope( final ScopeNode node,
+ final BigInteger id ) throws NamingException
+ {
+ DerefAliasesEnum mode = node.getDerefAliases();
+ Object baseId = db.getEntryId( node.getBaseDn() );
+ Index idx = db.getHeirarchyIndex();
+ boolean isChild = idx.hasValue( baseId, id );
+
+ /*
+ * The candidate id could be any entry in the db. If search
+ * dereferencing is not enabled then we return the results of the child
+ * test.
+ */
+ if ( ! mode.derefInSearching() )
+ {
+ return isChild;
+ }
+
+ /*
+ * From here down alias dereferencing is enabled. We determine if the
+ * candidate id is an alias, if so we reject it since aliases should
+ * not be returned.
+ */
+ idx = db.getAliasIndex();
+ if ( null != idx.reverseLookup( id ) )
+ {
+ return false;
+ }
+
+ /*
+ * The candidate is NOT an alias at this point. So if it is a child we
+ * just return it since it is in normal one level scope.
+ */
+ if ( isChild )
+ {
+ return true;
+ }
+
+ /*
+ * At this point the candidate is not a child and it is not an alias.
+ * We need to check if the candidate is in extended one level scope by
+ * performing a lookup on the one level alias index. This index stores
+ * a tuple mapping the baseId to the id of objects brought into the
+ * one level scope of the base by an alias: ( baseId, aliasedObjId )
+ * If the candidate id is an object brought into one level scope then
+ * the lookup returns true accepting the candidate. Otherwise the
+ * candidate is rejected with a false return because it is not in scope.
+ */
+ idx = db.getOneAliasIndex();
+ return idx.hasValue( baseId, id );
+ }
+}
Modified: incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/SubstringEnumerator.java
==============================================================================
--- incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/SubstringEnumerator.java (original)
+++ incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/SubstringEnumerator.java Wed Sep 29 21:35:00 2004
@@ -1,5 +1,193 @@
/*
- * Copyright 2004 The Apache Software Foundation
+ * Apache License
+ * Version 2.0, January 2004
+ * http://www.apache.org/licenses/
+ *
+ * TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+ *
+ * 1. Definitions.
+ *
+ * "License" shall mean the terms and conditions for use, reproduction,
+ * and distribution as defined by Sections 1 through 9 of this document.
+ *
+ * "Licensor" shall mean the copyright owner or entity authorized by
+ * the copyright owner that is granting the License.
+ *
+ * "Legal Entity" shall mean the union of the acting entity and all
+ * other entities that control, are controlled by, or are under common
+ * control with that entity. For the purposes of this definition,
+ * "control" means (i) the power, direct or indirect, to cause the
+ * direction or management of such entity, whether by contract or
+ * otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ * outstanding shares, or (iii) beneficial ownership of such entity.
+ *
+ * "You" (or "Your") shall mean an individual or Legal Entity
+ * exercising permissions granted by this License.
+ *
+ * "Source" form shall mean the preferred form for making modifications,
+ * including but not limited to software source code, documentation
+ * source, and configuration files.
+ *
+ * "Object" form shall mean any form resulting from mechanical
+ * transformation or translation of a Source form, including but
+ * not limited to compiled object code, generated documentation,
+ * and conversions to other media types.
+ *
+ * "Work" shall mean the work of authorship, whether in Source or
+ * Object form, made available under the License, as indicated by a
+ * copyright notice that is included in or attached to the work
+ * (an example is provided in the Appendix below).
+ *
+ * "Derivative Works" shall mean any work, whether in Source or Object
+ * form, that is based on (or derived from) the Work and for which the
+ * editorial revisions, annotations, elaborations, or other modifications
+ * represent, as a whole, an original work of authorship. For the purposes
+ * of this License, Derivative Works shall not include works that remain
+ * separable from, or merely link (or bind by name) to the interfaces of,
+ * the Work and Derivative Works thereof.
+ *
+ * "Contribution" shall mean any work of authorship, including
+ * the original version of the Work and any modifications or additions
+ * to that Work or Derivative Works thereof, that is intentionally
+ * submitted to Licensor for inclusion in the Work by the copyright owner
+ * or by an individual or Legal Entity authorized to submit on behalf of
+ * the copyright owner. For the purposes of this definition, "submitted"
+ * means any form of electronic, verbal, or written communication sent
+ * to the Licensor or its representatives, including but not limited to
+ * communication on electronic mailing lists, source code control systems,
+ * and issue tracking systems that are managed by, or on behalf of, the
+ * Licensor for the purpose of discussing and improving the Work, but
+ * excluding communication that is conspicuously marked or otherwise
+ * designated in writing by the copyright owner as "Not a Contribution."
+ *
+ * "Contributor" shall mean Licensor and any individual or Legal Entity
+ * on behalf of whom a Contribution has been received by Licensor and
+ * subsequently incorporated within the Work.
+ *
+ * 2. Grant of Copyright License. Subject to the terms and conditions of
+ * this License, each Contributor hereby grants to You a perpetual,
+ * worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ * copyright license to reproduce, prepare Derivative Works of,
+ * publicly display, publicly perform, sublicense, and distribute the
+ * Work and such Derivative Works in Source or Object form.
+ *
+ * 3. Grant of Patent License. Subject to the terms and conditions of
+ * this License, each Contributor hereby grants to You a perpetual,
+ * worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ * (except as stated in this section) patent license to make, have made,
+ * use, offer to sell, sell, import, and otherwise transfer the Work,
+ * where such license applies only to those patent claims licensable
+ * by such Contributor that are necessarily infringed by their
+ * Contribution(s) alone or by combination of their Contribution(s)
+ * with the Work to which such Contribution(s) was submitted. If You
+ * institute patent litigation against any entity (including a
+ * cross-claim or counterclaim in a lawsuit) alleging that the Work
+ * or a Contribution incorporated within the Work constitutes direct
+ * or contributory patent infringement, then any patent licenses
+ * granted to You under this License for that Work shall terminate
+ * as of the date such litigation is filed.
+ *
+ * 4. Redistribution. You may reproduce and distribute copies of the
+ * Work or Derivative Works thereof in any medium, with or without
+ * modifications, and in Source or Object form, provided that You
+ * meet the following conditions:
+ *
+ * (a) You must give any other recipients of the Work or
+ * Derivative Works a copy of this License; and
+ *
+ * (b) You must cause any modified files to carry prominent notices
+ * stating that You changed the files; and
+ *
+ * (c) You must retain, in the Source form of any Derivative Works
+ * that You distribute, all copyright, patent, trademark, and
+ * attribution notices from the Source form of the Work,
+ * excluding those notices that do not pertain to any part of
+ * the Derivative Works; and
+ *
+ * (d) If the Work includes a "NOTICE" text file as part of its
+ * distribution, then any Derivative Works that You distribute must
+ * include a readable copy of the attribution notices contained
+ * within such NOTICE file, excluding those notices that do not
+ * pertain to any part of the Derivative Works, in at least one
+ * of the following places: within a NOTICE text file distributed
+ * as part of the Derivative Works; within the Source form or
+ * documentation, if provided along with the Derivative Works; or,
+ * within a display generated by the Derivative Works, if and
+ * wherever such third-party notices normally appear. The contents
+ * of the NOTICE file are for informational purposes only and
+ * do not modify the License. You may add Your own attribution
+ * notices within Derivative Works that You distribute, alongside
+ * or as an addendum to the NOTICE text from the Work, provided
+ * that such additional attribution notices cannot be construed
+ * as modifying the License.
+ *
+ * You may add Your own copyright statement to Your modifications and
+ * may provide additional or different license terms and conditions
+ * for use, reproduction, or distribution of Your modifications, or
+ * for any such Derivative Works as a whole, provided Your use,
+ * reproduction, and distribution of the Work otherwise complies with
+ * the conditions stated in this License.
+ *
+ * 5. Submission of Contributions. Unless You explicitly state otherwise,
+ * any Contribution intentionally submitted for inclusion in the Work
+ * by You to the Licensor shall be under the terms and conditions of
+ * this License, without any additional terms or conditions.
+ * Notwithstanding the above, nothing herein shall supersede or modify
+ * the terms of any separate license agreement you may have executed
+ * with Licensor regarding such Contributions.
+ *
+ * 6. Trademarks. This License does not grant permission to use the trade
+ * names, trademarks, service marks, or product names of the Licensor,
+ * except as required for reasonable and customary use in describing the
+ * origin of the Work and reproducing the content of the NOTICE file.
+ *
+ * 7. Disclaimer of Warranty. Unless required by applicable law or
+ * agreed to in writing, Licensor provides the Work (and each
+ * Contributor provides its Contributions) on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied, including, without limitation, any warranties or conditions
+ * of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ * PARTICULAR PURPOSE. You are solely responsible for determining the
+ * appropriateness of using or redistributing the Work and assume any
+ * risks associated with Your exercise of permissions under this License.
+ *
+ * 8. Limitation of Liability. In no event and under no legal theory,
+ * whether in tort (including negligence), contract, or otherwise,
+ * unless required by applicable law (such as deliberate and grossly
+ * negligent acts) or agreed to in writing, shall any Contributor be
+ * liable to You for damages, including any direct, indirect, special,
+ * incidental, or consequential damages of any character arising as a
+ * result of this License or out of the use or inability to use the
+ * Work (including but not limited to damages for loss of goodwill,
+ * work stoppage, computer failure or malfunction, or any and all
+ * other commercial damages or losses), even if such Contributor
+ * has been advised of the possibility of such damages.
+ *
+ * 9. Accepting Warranty or Additional Liability. While redistributing
+ * the Work or Derivative Works thereof, You may choose to offer,
+ * and charge a fee for, acceptance of support, warranty, indemnity,
+ * or other liability obligations and/or rights consistent with this
+ * License. However, in accepting such obligations, You may act only
+ * on Your own behalf and on Your sole responsibility, not on behalf
+ * of any other Contributor, and only if You agree to indemnify,
+ * defend, and hold each Contributor harmless for any liability
+ * incurred by, or claims asserted against, such Contributor by reason
+ * of your accepting any such warranty or additional liability.
+ *
+ * END OF TERMS AND CONDITIONS
+ *
+ * APPENDIX: How to apply the Apache License to your work.
+ *
+ * To apply the Apache License to your work, attach the following
+ * boilerplate notice, with the fields enclosed by brackets "[]"
+ * replaced with your own identifying information. (Don't include
+ * the brackets!) The text should be enclosed in the appropriate
+ * comment syntax for the file format. We also recommend that a
+ * file or class name and description of purpose be included on the
+ * same "printed page" as the copyright notice for easier
+ * identification within third-party archives.
+ *
+ * Copyright [yyyy] [name of copyright owner]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,16 +202,125 @@
* limitations under the License.
*
*/
+
+/*
+ * $Id: SubstringEnumerator.java,v 1.2 2003/10/17 00:10:46 akarasulu Exp $
+ *
+ * -- (c) LDAPd Group --
+ * -- Please refer to the LICENSE.txt file in the root directory of --
+ * -- any LDAPd project for copyright and distribution information. --
+ *
+ * Created on Oct 13, 2003
+ */
package org.apache.eve.db;
+import javax.naming.NamingException;
+import javax.naming.NamingEnumeration;
+
+import org.apache.regexp.RE;
+import org.apache.regexp.RESyntaxException;
+
+import org.apache.ldap.common.filter.ExprNode;
+import org.apache.ldap.common.filter.SubstringNode;
+
+
/**
- * Creates Enumerations over a set of entry candidates based on a substring
- * assertions.
+ * Enumerator that creates a NamingEnumeration over the set of candidates that
+ * satisfy a substring filter expression.
*
* @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
* @version $Rev$
*/
-public interface SubstringEnumerator extends Enumerator
+public class SubstringEnumerator implements Enumerator
{
-}
+ /** Database used */
+ private Database db = null;
+ /** Evaluator used is an Avalon dependent object */
+ private SubstringEvaluator evaluator = null;
+
+
+ /**
+ * Creates a SubstringEnumerator for a database.
+ *
+ * @param db the database
+ * @param evaluator a substring evaluator
+ */
+ public SubstringEnumerator( Database db, SubstringEvaluator evaluator )
+ {
+ this.db = db;
+ this.evaluator = evaluator;
+ }
+
+
+ // ------------------------------------------------------------------------
+ // SubstringEnumerator Methods
+ // ------------------------------------------------------------------------
+
+
+ /**
+ * @see Enumerator#enumerate(
+ * org.apache.ldap.common.filter.ExprNode)
+ */
+ public NamingEnumeration enumerate( final ExprNode node )
+ throws NamingException
+ {
+ RE regex = null;
+ Index idx = null;
+ final SubstringNode snode = ( SubstringNode ) node;
+
+ if ( db.hasUserIndexOn( snode.getAttribute() ) )
+ {
+ /*
+ * Build out regex in this block so we do not do it twice in the
+ * evaluator if there is no index on the attribute of the substr ava
+ */
+ try
+ {
+ regex = snode.getRegex();
+ }
+ catch ( RESyntaxException e )
+ {
+ NamingException ne = new NamingException( "SubstringNode '"
+ + node + "' had incorrect syntax" );
+ ne.setRootCause( e );
+ throw ne;
+ }
+
+ /*
+ * Get the user index and return an index enumeration using the the
+ * compiled regular expression. Try to constrain even further if
+ * an initial term is available in the substring expression.
+ */
+ idx = db.getUserIndex( snode.getAttribute() );
+ if ( null == snode.getInitial() )
+ {
+ return idx.listIndices( regex );
+ }
+ else
+ {
+ return idx.listIndices( regex, snode.getInitial() );
+ }
+ }
+
+ /*
+ * From this point on we are dealing with an enumeration over entries
+ * based on an attribute that is not indexed. We have no choice but
+ * to perform a full table scan but need to leverage an index for the
+ * underlying enumeration. We know that all entries are listed under
+ * the ndn index and so this will enumerate over all entries as the
+ * underlying enumeration. An evaluator in an assertion is used to
+ * constrain the result set.
+ */
+ NamingEnumeration underlying = db.getNdnIndex().listIndices();
+ IndexAssertion assertion = new IndexAssertion()
+ {
+ public boolean assertCandidate( final IndexRecord record ) throws NamingException
+ {
+ return evaluator.evaluate( node, record );
+ }
+ };
+
+ return new IndexAssertionEnumeration( underlying, assertion );
+ }
+}
\ No newline at end of file
Modified: incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/SubstringEvaluator.java
==============================================================================
--- incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/SubstringEvaluator.java (original)
+++ incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/SubstringEvaluator.java Wed Sep 29 21:35:00 2004
@@ -16,11 +16,152 @@
*/
package org.apache.eve.db;
+
+import javax.naming.NamingException;
+import javax.naming.NamingEnumeration;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+
+import org.apache.regexp.RE;
+import org.apache.regexp.RESyntaxException;
+
+import org.apache.ldap.common.filter.ExprNode;
+import org.apache.ldap.common.schema.Normalizer;
+import org.apache.ldap.common.filter.SubstringNode;
+
+import org.apache.eve.schema.NormalizerRegistry;
+
+
/**
- *
+ * Evaluates substring filter assertions on an entry.
+ *
* @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
* @version $Rev$
*/
-public interface SubstringEvaluator extends Evaluator
+public class SubstringEvaluator implements Evaluator
{
-}
\ No newline at end of file
+ /** Database used while evaluating candidates */
+ private Database db;
+ /** Normalizer registry for up value normalization */
+ private NormalizerRegistry normalizerRegistry;
+
+
+ public SubstringEvaluator( Database db, NormalizerRegistry normReg )
+ {
+ this.db = db;
+ this.normalizerRegistry = normReg;
+ }
+
+
+ /**
+ * @see org.apache.eve.db.Evaluator#evaluate(ExprNode, IndexRecord)
+ */
+ public boolean evaluate( ExprNode node, IndexRecord record )
+ throws NamingException
+ {
+ RE regex = null;
+ SubstringNode snode = ( SubstringNode ) node;
+
+ if ( db.hasUserIndexOn( snode.getAttribute() ) )
+ {
+ Index idx = db.getUserIndex( snode.getAttribute() );
+
+ /*
+ * Note that this is using the reverse half of the index giving a
+ * considerable performance improvement on this kind of operation.
+ * Otherwise we would have to scan the entire index if there were
+ * no reverse lookups.
+ */
+
+ NamingEnumeration list = idx.listReverseIndices( record.getEntryId() );
+
+ // compile the regular expression to search for a matching attribute
+ try
+ {
+ regex = snode.getRegex();
+ }
+ catch ( RESyntaxException e )
+ {
+ NamingException ne = new NamingException( "SubstringNode '"
+ + node + "' had " + "incorrect syntax" );
+ ne.setRootCause( e );
+ throw ne;
+ }
+
+ // cycle through the attribute values testing for a match
+ while ( list.hasMore() )
+ {
+ IndexRecord rec = ( IndexRecord ) list.next();
+
+ // once match is found cleanup and return true
+ if ( regex.match( ( String ) rec.getIndexKey() ) )
+ {
+ list.close();
+ return true;
+ }
+ }
+
+ // we fell through so a match was not found - assertion was false.
+ return false;
+ }
+
+ // --------------------------------------------------------------------
+ // Index not defined beyond this point
+ // --------------------------------------------------------------------
+
+ Attribute attr = null;
+ Normalizer normalizer = normalizerRegistry.getSubstring( snode.getAttribute() );
+
+ // resusitate the entry if it has not been and set entry in IndexRecord
+ if ( null == record.getAttributes() )
+ {
+ Attributes attrs = db.lookup( record.getEntryId() );
+ record.setAttributes( attrs );
+ }
+
+ // get the attribute
+ attr = record.getAttributes().get( snode.getAttribute() );
+
+ // if the attribute does not exist just return false
+ if ( null == attr )
+ {
+ return false;
+ }
+
+ // compile the regular expression to search for a matching attribute
+ try
+ {
+ regex = snode.getRegex();
+ }
+ catch ( RESyntaxException e )
+ {
+ NamingException ne = new NamingException( "SubstringNode '"
+ + node + "' had " + "incorrect syntax" );
+ ne.setRootCause( e );
+ throw ne;
+ }
+
+ /*
+ * Cycle through the attribute values testing normalized version
+ * obtained from using the substring matching rule's normalizer.
+ * The test uses the comparator obtained from the appropriate
+ * substring matching rule.
+ */
+ NamingEnumeration list = attr.getAll();
+ while ( list.hasMore() )
+ {
+ String value = ( String )
+ normalizer.normalize( list.next() );
+
+ // Once match is found cleanup and return true
+ if ( regex.match( value ) )
+ {
+ list.close();
+ return true;
+ }
+ }
+
+ // we fell through so a match was not found - assertion was false.
+ return false;
+ }
+}