1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.ldap.server.subtree;
18
19
20 import org.apache.ldap.common.util.NamespaceTools;
21 import org.apache.ldap.common.name.LdapName;
22 import org.apache.ldap.common.subtree.SubtreeSpecification;
23 import org.apache.ldap.server.schema.OidRegistry;
24
25 import javax.naming.Name;
26 import javax.naming.NamingException;
27 import javax.naming.directory.Attribute;
28 import java.util.Iterator;
29
30
31 /***
32 * An evaluator used to determine if an entry is included in the collection
33 * represented by a subtree specification.
34 *
35 * @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
36 * @version $Rev$
37 */
38 public class SubtreeEvaluator
39 {
40 /*** A refinement filter evaluator */
41 private final RefinementEvaluator evaluator;
42
43
44 /***
45 * Creates a subtreeSpecification evaluatior which can be used to determine
46 * if an entry is included within the collection of a subtree.
47 *
48 * @param registry a registry used to lookup objectClass names for OIDs
49 */
50 public SubtreeEvaluator( OidRegistry registry )
51 {
52 RefinementLeafEvaluator leafEvaluator = new RefinementLeafEvaluator( registry );
53 evaluator = new RefinementEvaluator( leafEvaluator );
54 }
55
56
57 /***
58 * Determines if an entry is selected by a subtree specification.
59 *
60 * @param subtree the subtree specification
61 * @param apDn the distinguished name of the administrative point containing the subentry
62 * @param entryDn the distinguished name of the candidate entry
63 * @param objectClasses the objectClasses of the candidate entry
64 * @return true if the entry is selected by the specification, false if it is not
65 * @throws javax.naming.NamingException if errors are encountered while evaluating selection
66 */
67 public boolean evaluate( SubtreeSpecification subtree, Name apDn, Name entryDn, Attribute objectClasses )
68 throws NamingException
69 {
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86 Name apRelativeRdn;
87 if ( ! NamespaceTools.isDescendant( apDn, entryDn ) )
88 {
89 return false;
90 }
91 else if ( apDn.equals( entryDn ) )
92 {
93 apRelativeRdn = new LdapName();
94 }
95 else
96 {
97 apRelativeRdn = NamespaceTools.getRelativeName( apDn, entryDn );
98 }
99
100
101
102
103
104
105
106 Name baseRelativeRdn;
107 if ( subtree.getBase() != null && subtree.getBase().size() == 0 )
108 {
109 baseRelativeRdn = apRelativeRdn;
110 }
111 else if ( apRelativeRdn.equals( subtree.getBase() ) )
112 {
113 baseRelativeRdn = new LdapName();
114 }
115 else if ( ! NamespaceTools.isDescendant( subtree.getBase(), apRelativeRdn ) )
116 {
117 return false;
118 }
119 else
120 {
121 baseRelativeRdn = NamespaceTools.getRelativeName( subtree.getBase(), apRelativeRdn );
122 }
123
124
125
126
127
128
129
130
131
132 if ( subtree.getMaxBaseDistance() != SubtreeSpecification.UNBOUNDED_MAX )
133 {
134 if ( subtree.getMaxBaseDistance() < baseRelativeRdn.size() )
135 {
136 return false;
137 }
138 }
139
140 if ( subtree.getMinBaseDistance() > 0 )
141 {
142 if ( baseRelativeRdn.size() < subtree.getMinBaseDistance() )
143 {
144 return false;
145 }
146 }
147
148
149
150
151
152
153
154
155 Iterator list = subtree.getChopBeforeExclusions().iterator();
156 while ( list.hasNext() )
157 {
158 Name chopBefore = ( Name ) list.next();
159 if ( NamespaceTools.isDescendant( chopBefore, baseRelativeRdn ) )
160 {
161 return false;
162 }
163 }
164
165 list = subtree.getChopAfterExclusions().iterator();
166 while ( list.hasNext() )
167 {
168 Name chopAfter = ( Name ) list.next();
169 if ( NamespaceTools.isDescendant( chopAfter, baseRelativeRdn ) && ! chopAfter.equals( baseRelativeRdn ) )
170 {
171 return false;
172 }
173 }
174
175
176
177
178
179
180 if ( subtree.getRefinement() != null )
181 {
182 return evaluator.evaluate( subtree.getRefinement(), objectClasses );
183 }
184
185
186
187
188
189
190 return true;
191 }
192 }