View Javadoc

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.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             // add all listed attributes
122             for ( int ii = 0; ii < attrIds.length; ii++ )
123             {
124                 if ( attrIds[ii].equals( "+") )
125                 {
126                     continue;
127                 }
128                 // there is no attribute by that name in the entry so we continue
129                 if ( null == rec.getAttributes().get( attrIds[ii] ) )
130                 {
131                     continue;
132                 }
133 
134                 // clone attribute to stuff into the new resultant entry
135                 Attribute attr = ( Attribute ) rec.getAttributes().get( attrIds[ii] ).clone();
136                 entry.put( attr );
137             }
138 
139             // add all operational attributes
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             // add all listed operational attributes
159             for ( int ii = 0; ii < attrIds.length; ii++ )
160             {
161                 if ( attrIds[ii].equals( "*") )
162                 {
163                     continue;
164                 }
165                 // there is no attribute by that name in the entry so we continue
166                 if ( null == rec.getAttributes().get( attrIds[ii] ) )
167                 {
168                     continue;
169                 }
170 
171                 // clone attribute to stuff into the new resultant entry
172                 Attribute attr = ( Attribute ) rec.getAttributes().get( attrIds[ii] ).clone();
173                 entry.put( attr );
174             }
175 
176             // add all user attributes
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                 // there is no attribute by that name in the entry so we continue
196                 if ( null == rec.getAttributes().get( attrIds[ii] ) )
197                 {
198                     continue;
199                 }
200 
201                 // clone attribute to stuff into the new resultant entry
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 }