1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.ldap.server.partition.impl.btree;
18
19
20 import javax.naming.NamingEnumeration;
21 import javax.naming.NamingException;
22 import javax.naming.directory.Attribute;
23 import javax.naming.directory.Attributes;
24
25 import org.apache.ldap.common.message.LockableAttributesImpl;
26 import org.apache.ldap.common.schema.AttributeType;
27 import org.apache.ldap.common.schema.UsageEnum;
28 import org.apache.ldap.server.enumeration.SearchResultEnumeration;
29 import org.apache.ldap.server.schema.AttributeTypeRegistry;
30
31
32 /***
33 * An enumeration that transforms another underlying enumeration over a set of
34 * IndexRecords into an enumeration over a set of SearchResults. Note that the
35 * SearchResult created may not be complete and other parts of the system may
36 * modify it before return. This enumeration simply creates a new copy of the
37 * entry to return stuffing it with the attributes that were specified. This is
38 * all that it does now but this may change later.
39 *
40 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
41 * @version $Rev: 264732 $
42 */
43 public class BTreeSearchResultEnumeration implements SearchResultEnumeration
44 {
45 /*** Database used to lookup entries from */
46 private BTreeContextPartition partition = null;
47 /*** the attributes to return */
48 private final String [] attrIds;
49 /*** underlying enumeration over IndexRecords */
50 private final NamingEnumeration underlying;
51
52 private boolean attrIdsHasStar = false;
53 private boolean attrIdsHasPlus = false;
54 private AttributeTypeRegistry registry = null;
55
56 /***
57 * Creates an enumeration that returns entries packaged within SearchResults
58 * using the search parameters supplied to a search call.
59 *
60 * @param attrIds the returned attributes
61 * @param underlying the enumeration over IndexRecords
62 */
63 public BTreeSearchResultEnumeration( String [] attrIds,
64 NamingEnumeration underlying,
65 BTreeContextPartition db,
66 AttributeTypeRegistry registry )
67 {
68 this.partition = db;
69 this.attrIds = attrIds;
70 this.underlying = underlying;
71 this.attrIdsHasStar = containsStar( attrIds );
72 this.attrIdsHasPlus = containsPlus( attrIds );
73 this.registry = registry;
74 }
75
76
77 /***
78 * @see javax.naming.NamingEnumeration#close()
79 */
80 public void close() throws NamingException
81 {
82 underlying.close();
83 }
84
85
86 /***
87 * @see javax.naming.NamingEnumeration#hasMore()
88 */
89 public boolean hasMore() throws NamingException
90 {
91 return underlying.hasMore();
92 }
93
94
95 /***
96 * @see javax.naming.NamingEnumeration#next()
97 */
98 public Object next() throws NamingException
99 {
100 IndexRecord rec = ( IndexRecord ) underlying.next();
101 Attributes entry;
102 String name = partition.getEntryUpdn( rec.getEntryId() );
103
104 if ( null == rec.getAttributes() )
105 {
106 rec.setAttributes( partition.lookup( rec.getEntryId() ) );
107 }
108
109 if ( attrIds == null )
110 {
111 entry = ( Attributes ) rec.getAttributes().clone();
112 }
113 else if ( attrIdsHasPlus && attrIdsHasStar )
114 {
115 entry = ( Attributes ) rec.getAttributes().clone();
116 }
117 else if ( attrIdsHasPlus )
118 {
119 entry = new LockableAttributesImpl();
120
121
122 for ( int ii = 0; ii < attrIds.length; ii++ )
123 {
124 if ( attrIds[ii].equals( "+") )
125 {
126 continue;
127 }
128
129 if ( null == rec.getAttributes().get( attrIds[ii] ) )
130 {
131 continue;
132 }
133
134
135 Attribute attr = ( Attribute ) rec.getAttributes().get( attrIds[ii] ).clone();
136 entry.put( attr );
137 }
138
139
140 NamingEnumeration list = rec.getAttributes().getIDs();
141 while ( list.hasMore() )
142 {
143 String attrId = ( String ) list.next();
144 AttributeType attrType = registry.lookup( attrId );
145 if ( attrType.getUsage() == UsageEnum.USERAPPLICATIONS )
146 {
147 continue;
148 }
149
150 Attribute attr = ( Attribute ) rec.getAttributes().get( attrId ).clone();
151 entry.put( attr );
152 }
153 }
154 else if ( attrIdsHasStar )
155 {
156 entry = new LockableAttributesImpl();
157
158
159 for ( int ii = 0; ii < attrIds.length; ii++ )
160 {
161 if ( attrIds[ii].equals( "*") )
162 {
163 continue;
164 }
165
166 if ( null == rec.getAttributes().get( attrIds[ii] ) )
167 {
168 continue;
169 }
170
171
172 Attribute attr = ( Attribute ) rec.getAttributes().get( attrIds[ii] ).clone();
173 entry.put( attr );
174 }
175
176
177 NamingEnumeration list = rec.getAttributes().getIDs();
178 while ( list.hasMore() )
179 {
180 String attrId = ( String ) list.next();
181 AttributeType attrType = registry.lookup( attrId );
182 if ( attrType.getUsage() == UsageEnum.USERAPPLICATIONS )
183 {
184 Attribute attr = ( Attribute ) rec.getAttributes().get( attrId ).clone();
185 entry.put( attr );
186 }
187 }
188 }
189 else
190 {
191 entry = new LockableAttributesImpl();
192
193 for ( int ii = 0; ii < attrIds.length; ii++ )
194 {
195
196 if ( null == rec.getAttributes().get( attrIds[ii] ) )
197 {
198 continue;
199 }
200
201
202 Attribute attr = ( Attribute ) rec.getAttributes().get( attrIds[ii] ).clone();
203 entry.put( attr );
204 }
205 }
206
207 return new BTreeSearchResult( rec.getEntryId(), name, null, entry );
208 }
209
210
211 private boolean containsStar( String[] ids )
212 {
213 if ( ids == null )
214 {
215 return false;
216 }
217
218 for ( int ii = ids.length - 1; ii >= 0; ii-- )
219 {
220 if ( ids[ii].trim().equals( "*" ) )
221 {
222 return true;
223 }
224 }
225
226 return false;
227 }
228
229
230 private boolean containsPlus( String[] ids )
231 {
232 if ( ids == null )
233 {
234 return false;
235 }
236
237 for ( int ii = ids.length - 1; ii >= 0; ii-- )
238 {
239 if ( ids[ii].trim().equals( "+" ) )
240 {
241 return true;
242 }
243 }
244
245 return false;
246 }
247
248
249 /***
250 * @see java.util.Enumeration#hasMoreElements()
251 */
252 public boolean hasMoreElements()
253 {
254 return underlying.hasMoreElements();
255 }
256
257
258 /***
259 * @see java.util.Enumeration#nextElement()
260 */
261 public Object nextElement()
262 {
263 return underlying.nextElement();
264 }
265 }