KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > ldap > server > db > ScopeEnumerator


1 /*
2  * Copyright 2004 The Apache Software Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */

17 package org.apache.ldap.server.db;
18
19
20 import org.apache.ldap.common.filter.ExprNode;
21 import org.apache.ldap.common.filter.ScopeNode;
22 import org.apache.ldap.common.util.SingletonEnumeration;
23
24 import javax.naming.NamingEnumeration JavaDoc;
25 import javax.naming.NamingException JavaDoc;
26 import javax.naming.directory.SearchControls JavaDoc;
27 import java.math.BigInteger JavaDoc;
28
29
30 /**
31  * Enumerates candidates based on scope.
32  *
33  * @author <a HREF="mailto:dev@directory.apache.org">Apache Directory Project</a>
34  * @version $Rev: 169198 $
35  */

36 public class ScopeEnumerator implements Enumerator
37 {
38     /** Database used to enumerate based on scope */
39     private Database db = null;
40     /** Filter scope expression evaluator */
41     private ScopeEvaluator evaluator = null;
42
43
44     public ScopeEnumerator( Database db, ScopeEvaluator evaluator )
45     {
46         this.db = db;
47         this.evaluator = evaluator;
48     }
49
50
51     /**
52      * Builds an enumeration over all entries that satisfy the constraints of
53      * the scope assertion node.
54      *
55      * @param node the scope node
56      * @return the candidates that are within scope
57      * @throws NamingException if any system indices fail
58      * @see org.apache.ldap.server.db.Enumerator#enumerate(ExprNode)
59      */

60     public NamingEnumeration JavaDoc enumerate( ExprNode node ) throws NamingException JavaDoc
61     {
62         final ScopeNode snode = ( ScopeNode ) node;
63         final BigInteger JavaDoc id = db.getEntryId( snode.getBaseDn() );
64
65         switch( snode.getScope() )
66         {
67         case( SearchControls.OBJECT_SCOPE ):
68             final IndexRecord record = new IndexRecord();
69             record.setEntryId( id );
70             record.setIndexKey( snode.getBaseDn() );
71             return new SingletonEnumeration( record );
72         case( SearchControls.ONELEVEL_SCOPE ):
73             return enumerateChildren( snode.getBaseDn(),
74                 snode.getDerefAliases().derefInSearching() );
75         case( SearchControls.SUBTREE_SCOPE ):
76             return enumerateDescendants( snode );
77         default:
78             throw new NamingException JavaDoc( "Unrecognized search scope!" );
79         }
80     }
81
82
83     /**
84      * Constructs an enumeration over all entries within one level scope even
85      * when aliases are enabled while searching.
86      *
87      * @param dn the base dn
88      * @param deref whether or not we dereference while searching
89      * @return the enumeration of all entries in direct or alias extended one
90      * level scope to the base
91      * @throws NamingException if any failures occur while accessing system
92      * indices.
93      */

94     private NamingEnumeration JavaDoc enumerateChildren( String JavaDoc dn, boolean deref )
95         throws NamingException JavaDoc
96     {
97         Index idx = db.getHierarchyIndex();
98         final BigInteger JavaDoc id = db.getEntryId( dn );
99         final NamingEnumeration JavaDoc children = idx.listIndices( id );
100         
101         /*
102          * If alias dereferencing is not enabled while searching then we just
103          * return the enumeration of the base entry's children.
104          */

105         if ( ! deref )
106         {
107            return children;
108         }
109
110         /* ====================================================================
111          * From here on Dereferencing while searching is enabled
112          * ====================================================================
113          *
114          * Dereferencing in search is enabled so we need to wrap the child
115          * listing with an assertion enumeration to weed out aliases that will
116          * not be returned. Next we need to compose an enumeration which
117          * combines the list of non-alias child entries with those entries that
118          * are brought into one level scope by aliases.
119          */

120
121         // List all entries brought into one level scope at base by aliases
122
idx = db.getOneAliasIndex();
123         NamingEnumeration JavaDoc aliasIntroduced = idx.listIndices( id );
124         
125         // Still need to use assertion enum to weed out aliases
126
NamingEnumeration JavaDoc nonAliasChildren = new IndexAssertionEnumeration(
127             children, new AssertNotAlias() );
128         
129         // Combine both into one enumeration
130
NamingEnumeration JavaDoc [] all = {nonAliasChildren, aliasIntroduced};
131         return new DisjunctionEnumeration( all );
132     }
133     
134
135     /**
136      * Constructs an enumeration over all entries within subtree scope even
137      * when aliases are enabled while searching.
138      *
139      * @param node the scope node
140      * @return the enumeration of all entries in direct or alias extended
141      * subtree scope to the base
142      * @throws NamingException if any failures occur while accessing system
143      * indices.
144      */

145     private NamingEnumeration JavaDoc enumerateDescendants( final ScopeNode node )
146         throws NamingException JavaDoc
147     {
148         Index idx = null;
149
150         /*
151          * If we do not dereference while searching then we simply return any
152          * entry that is not a descendant of the base.
153          */

154         if ( ! node.getDerefAliases().derefInSearching() )
155         {
156             // Gets a NamingEnumeration over all elements
157
idx = db.getNdnIndex();
158             NamingEnumeration JavaDoc underlying = idx.listIndices();
159             return new IndexAssertionEnumeration( underlying,
160                 new AssertDescendant( node ) );
161         }
162
163         // Create an assertion to assert or evaluate an expression
164
IndexAssertion assertion = new IndexAssertion()
165         {
166             public boolean assertCandidate( IndexRecord rec )
167                 throws NamingException JavaDoc
168             {
169                 return evaluator.evaluate( node, rec );
170             }
171         };
172
173         // Gets a NamingEnumeration over all elements
174
idx = db.getNdnIndex();
175         NamingEnumeration JavaDoc underlying = idx.listIndices();
176         return new IndexAssertionEnumeration( underlying, assertion );
177     }
178
179
180     /**
181      * Asserts an entry is a descendant.
182      */

183     class AssertDescendant implements IndexAssertion
184     {
185         /** Scope node with base and alias info */
186         private final ScopeNode scope;
187
188         
189         /**
190          * Creates a assertion using a ScopeNode to determine the search base.
191          *
192          * @param node the scope node with search base
193          */

194         AssertDescendant( final ScopeNode node )
195         {
196             scope = node;
197         }
198
199
200         /**
201          * Returns true if the candidate with id is a descendant of the base,
202          * false otherwise.
203          *
204          * @see org.apache.ldap.server.db.IndexAssertion#assertCandidate(IndexRecord)
205          */

206         public boolean assertCandidate( IndexRecord record ) throws NamingException JavaDoc
207         {
208             String JavaDoc dn = db.getEntryDn( record.getEntryId() );
209             return dn.endsWith( scope.getBaseDn() );
210         }
211     }
212
213
214     /**
215      * Asserts an entry is NOT an alias.
216      */

217     class AssertNotAlias implements IndexAssertion
218     {
219         /**
220          * Returns true if the candidate is not an alias, false otherwise.
221          *
222          * @see IndexAssertion#assertCandidate(IndexRecord)
223          */

224         public boolean assertCandidate( IndexRecord record ) throws NamingException JavaDoc
225         {
226             Index aliasIdx = db.getAliasIndex();
227                
228             if ( null == aliasIdx.reverseLookup( record.getEntryId() ) )
229             {
230                 return true;
231             }
232                
233             return false;
234         }
235     }
236 }
237
Popular Tags