1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.directory.server.xdbm.search.evaluator;
21
22
23 import org.apache.directory.api.ldap.model.entry.Entry;
24 import org.apache.directory.api.ldap.model.exception.LdapException;
25 import org.apache.directory.api.ldap.model.filter.ScopeNode;
26 import org.apache.directory.api.ldap.model.message.SearchScope;
27 import org.apache.directory.api.ldap.model.name.Dn;
28 import org.apache.directory.server.core.api.partition.Partition;
29 import org.apache.directory.server.core.api.partition.PartitionTxn;
30 import org.apache.directory.server.i18n.I18n;
31 import org.apache.directory.server.xdbm.IndexEntry;
32 import org.apache.directory.server.xdbm.ParentIdAndRdn;
33 import org.apache.directory.server.xdbm.Store;
34 import org.apache.directory.server.xdbm.search.Evaluator;
35
36
37
38
39
40
41
42
43 public class SubtreeScopeEvaluator implements Evaluator<ScopeNode>
44 {
45
46 private final ScopeNode node;
47
48
49 private final String baseId;
50
51
52
53
54
55
56
57
58
59
60
61 private final boolean baseIsContextEntry;
62
63
64 private final boolean dereferencing;
65
66
67 private final Store db;
68
69
70
71
72
73
74
75
76
77
78 public SubtreeScopeEvaluator( PartitionTxn partitionTxn, Store db, ScopeNode node ) throws LdapException
79 {
80 this.db = db;
81 this.node = node;
82
83 if ( node.getScope() != SearchScope.SUBTREE )
84 {
85 throw new IllegalStateException( I18n.err( I18n.ERR_727 ) );
86 }
87
88 baseId = node.getBaseId();
89
90 baseIsContextEntry = db.getSuffixId( partitionTxn ) == baseId;
91
92 dereferencing = node.getDerefAliases().isDerefInSearching() || node.getDerefAliases().isDerefAlways();
93 }
94
95
96
97
98
99
100
101 private boolean isDescendant( PartitionTxn partitionTxn, String candidateId ) throws LdapException
102 {
103 String tmp = candidateId;
104
105 while ( true )
106 {
107 ParentIdAndRdn parentIdAndRdn = db.getRdnIndex().reverseLookup( partitionTxn, tmp );
108
109 if ( parentIdAndRdn == null )
110 {
111 return false;
112 }
113
114 tmp = parentIdAndRdn.getParentId();
115
116 if ( tmp.equals( Partition.ROOT_ID ) )
117 {
118 return false;
119 }
120
121 if ( tmp.equals( baseId ) )
122 {
123 return true;
124 }
125 }
126 }
127
128
129
130
131
132 @Override
133 public boolean evaluate( PartitionTxn partitionTxn, IndexEntry<?, String> indexEntry ) throws LdapException
134 {
135 String id = indexEntry.getId();
136 Entry entry = indexEntry.getEntry();
137
138
139 if ( null == entry )
140 {
141 entry = db.fetch( partitionTxn, indexEntry.getId() );
142
143 if ( null == entry )
144 {
145
146 return false;
147 }
148
149 indexEntry.setEntry( entry );
150 }
151
152
153
154
155
156
157
158
159 boolean isDescendant = baseIsContextEntry || baseId.equals( id ) || entry.getDn().isDescendantOf( node.getBaseDn() );
160
161
162
163
164
165
166 if ( !isDereferencing() )
167 {
168 return isDescendant;
169 }
170
171
172
173
174
175
176 if ( db.getAliasCache() != null )
177 {
178 Dn dn = db.getAliasCache().getIfPresent( id );
179
180 if ( dn != null )
181 {
182 return false;
183 }
184 }
185 else if ( null != db.getAliasIndex().reverseLookup( partitionTxn, id ) )
186 {
187 return false;
188 }
189
190
191
192
193
194 if ( isDescendant )
195 {
196 return true;
197 }
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212 return db.getSubAliasIndex().forward( partitionTxn, baseId, id );
213 }
214
215
216
217
218
219 @Override
220 public boolean evaluate( Entry candidate ) throws LdapException
221 {
222 throw new UnsupportedOperationException( I18n.err( I18n.ERR_721 ) );
223 }
224
225
226
227
228
229 @Override
230 public ScopeNode getExpression()
231 {
232 return node;
233 }
234
235
236
237
238
239 public String getBaseId()
240 {
241 return baseId;
242 }
243
244
245
246
247
248 public boolean isDereferencing()
249 {
250 return dereferencing;
251 }
252
253
254
255
256
257 public String toString( String tabs )
258 {
259 StringBuilder sb = new StringBuilder();
260
261 sb.append( tabs ).append( "SubstreeScopeEvaluator : " ).append( node ).append( '\n' );
262
263 return sb.toString();
264 }
265
266
267
268
269
270 public String toString()
271 {
272 return toString( "" );
273 }
274 }