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;
18  
19  
20  import org.apache.ldap.common.exception.LdapContextNotEmptyException;
21  import org.apache.ldap.common.exception.LdapNameNotFoundException;
22  import org.apache.ldap.common.filter.ExprNode;
23  import org.apache.ldap.common.message.LockableAttributesImpl;
24  import org.apache.ldap.common.schema.AttributeType;
25  import org.apache.ldap.common.util.ArrayUtils;
26  import org.apache.ldap.server.db.Database;
27  import org.apache.ldap.server.db.SearchEngine;
28  import org.apache.ldap.server.db.SearchResultEnumeration;
29  import org.apache.ldap.server.db.gui.PartitionViewer;
30  
31  import javax.naming.Name;
32  import javax.naming.NamingEnumeration;
33  import javax.naming.NamingException;
34  import javax.naming.directory.Attribute;
35  import javax.naming.directory.Attributes;
36  import javax.naming.directory.ModificationItem;
37  import javax.naming.directory.SearchControls;
38  import java.math.BigInteger;
39  import java.util.HashSet;
40  import java.util.Map;
41  
42  
43  /***
44   * An Abstract BackingStore using a formal database and a search engine.  All
45   * the common code between a SystemBackingStore and a DefaultBackingStore
46   * will be added to this super class.
47   *
48   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
49   * @version $Rev: 164290 $
50   */
51  public abstract class AbstractContextPartition implements ContextPartition
52  {
53      /*** ===================================================================
54  
55       The following OID branch is reserved for the directory TLP once it
56       graduates the incubator:
57  
58         1.2.6.1.4.1.18060.1.1
59  
60       The following branch is reserved for the apache directory server:
61  
62         1.2.6.1.4.1.18060.1.1.1
63  
64        The following branch is reserved for use by apache directory server Syntaxes:
65  
66          1.2.6.1.4.1.18060.1.1.1.1
67  
68        The following branch is reserved for use by apache directory server MatchingRules:
69  
70          1.2.6.1.4.1.18060.1.1.1.2
71  
72        The following branch is reserved for use by apache directory server AttributeTypes:
73  
74          1.2.6.1.4.1.18060.1.1.1.3
75  
76            * 1.2.6.1.4.1.18060.1.1.1.3.1 - apacheNdn
77            * 1.2.6.1.4.1.18060.1.1.1.3.2 - apacheUpdn
78            * 1.2.6.1.4.1.18060.1.1.1.3.3 - apacheExistance
79            * 1.2.6.1.4.1.18060.1.1.1.3.4 - apacheHierarchy
80            * 1.2.6.1.4.1.18060.1.1.1.3.5 - apacheOneAlias
81            * 1.2.6.1.4.1.18060.1.1.1.3.6 - apacheSubAlias
82            * 1.2.6.1.4.1.18060.1.1.1.3.7 - apacheAlias
83  
84        The following branch is reserved for use by apache directory server ObjectClasses:
85  
86          1.2.6.1.4.1.18060.1.1.1.4
87  
88      ==================================================================== */
89  
90  
91      /*** Private OID (1.2.6.1.4.1.18060.1.1.1.3.1) for _ndn op attrib */
92      public static final String NDN_OID       = "1.2.6.1.4.1.18060.1.1.1.3.1" ;
93      /*** Private OID (1.2.6.1.4.1.18060.1.1.1.3.2) for _updn op attrib */
94      public static final String UPDN_OID      = "1.2.6.1.4.1.18060.1.1.1.3.2" ;
95      /*** Private OID (1.2.6.1.4.1.18060.1.1.1.3.3) for _existance op attrib */
96      public static final String EXISTANCE_OID = "1.2.6.1.4.1.18060.1.1.1.3.3" ;
97      /*** Private OID (1.2.6.1.4.1.18060.1.1.1.3.4) for _hierarchy op attrib */
98      public static final String HIERARCHY_OID = "1.2.6.1.4.1.18060.1.1.1.3.4" ;
99      /*** Private OID (1.2.6.1.4.1.18060.1.1.1.3.5) for _oneAlias index */
100     public static final String ONEALIAS_OID  = "1.2.6.1.4.1.18060.1.1.1.3.5" ;
101     /*** Private OID (1.2.6.1.4.1.18060.1.1.1.3.6) for _subAlias index */
102     public static final String SUBALIAS_OID  = "1.2.6.1.4.1.18060.1.1.1.3.6" ;
103     /*** Private OID (1.2.6.1.4.1.18060.1.1.1.3.7) for _alias index */
104     public static final String ALIAS_OID     = "1.2.6.1.4.1.18060.1.1.1.3.7" ;
105 
106     /***
107      * the database used for this backing store which is also initialized during
108      * configuration time
109      */
110     private Database db = null;
111     
112     /***
113      * the search engine used to search the database
114      */
115     private SearchEngine engine = null;
116 
117 
118     // ------------------------------------------------------------------------
119     // C O N S T R U C T O R S
120     // ------------------------------------------------------------------------
121 
122 
123     /***
124      * Creates a context partition with a new database and a search engine.
125      *
126      * @param db the dedicated database for this backing store
127      * @param searchEngine the search engine for this backing store
128      */
129     public AbstractContextPartition( Database db, SearchEngine searchEngine,
130                                      AttributeType[] indexAttributes )
131         throws NamingException
132     {
133         this.db = db;
134         this.engine = searchEngine;
135 
136         HashSet sysOidSet = new HashSet();
137         sysOidSet.add( EXISTANCE_OID );
138         sysOidSet.add( HIERARCHY_OID );
139         sysOidSet.add( UPDN_OID );
140         sysOidSet.add( NDN_OID );
141         sysOidSet.add( ONEALIAS_OID );
142         sysOidSet.add( SUBALIAS_OID );
143         sysOidSet.add( ALIAS_OID );
144 
145         for ( int ii = 0; ii < indexAttributes.length; ii ++ )
146         {
147             String oid = indexAttributes[ii].getOid();
148 
149             // check if attribute is a system attribute
150             if ( sysOidSet.contains( oid ) )
151             {
152                 if ( oid.equals( EXISTANCE_OID ) )
153                 {
154                     db.setExistanceIndexOn( indexAttributes[ii] );
155                 }
156                 else if ( oid.equals( HIERARCHY_OID ) )
157                 {
158                     db.setHierarchyIndexOn( indexAttributes[ii] );
159                 }
160                 else if ( oid.equals( UPDN_OID ) )
161                 {
162                     db.setUpdnIndexOn( indexAttributes[ii] );
163                 }
164                 else if ( oid.equals( NDN_OID ) )
165                 {
166                     db.setNdnIndexOn( indexAttributes[ii] );
167                 }
168                 else if ( oid.equals( ONEALIAS_OID ) )
169                 {
170                     db.setOneAliasIndexOn( indexAttributes[ii] );
171                 }
172                 else if ( oid.equals( SUBALIAS_OID ) )
173                 {
174                     db.setSubAliasIndexOn( indexAttributes[ii] );
175                 }
176                 else if ( oid.equals( ALIAS_OID ) )
177                 {
178                     db.setAliasIndexOn( indexAttributes[ii] );
179                 }
180                 else
181                 {
182                     throw new NamingException( "Unidentified system index "
183                         + oid );
184                 }
185             }
186             else
187             {
188                 db.addIndexOn( indexAttributes[ii] );
189             }
190         }
191     }
192 
193 
194     // ------------------------------------------------------------------------
195     // Public Accessors - not declared in any interfaces just for this class
196     // ------------------------------------------------------------------------
197 
198 
199     /***
200      * Gets the Database used by this ContextPartition.
201      *
202      * @return the database used
203      */
204     public Database getDb()
205     {
206         return db;
207     }
208 
209 
210     /***
211      * Gets the DefaultSearchEngine used by this ContextPartition to search the
212      * Database. 
213      *
214      * @return the search engine
215      */
216     public SearchEngine getEngine()
217     {
218         return engine;
219     }
220 
221 
222     // ------------------------------------------------------------------------
223     // BackingStore Interface Method Implementations
224     // ------------------------------------------------------------------------
225 
226 
227     /***
228      * @see org.apache.ldap.server.BackingStore#delete( Name )
229      */
230     public void delete( Name dn ) throws NamingException
231     {
232         BigInteger id = db.getEntryId( dn.toString() );
233 
234         // don't continue if id is null
235         if ( id == null )
236         {
237             throw new LdapNameNotFoundException( "Could not find entry at '"
238                     + dn + "' to delete it!");
239         }
240 
241         if ( db.getChildCount( id ) > 0 )
242         {
243             LdapContextNotEmptyException cnee = new LdapContextNotEmptyException(
244                 "[66] Cannot delete entry " + dn + " it has children!" );
245             cnee.setRemainingName( dn );
246             throw cnee;
247         }
248         
249         db.delete( id );
250     }
251     
252 
253     /***
254      * @see org.apache.ldap.server.BackingStore#add( String, Name, Attributes )
255      */
256     public void add( String updn, Name dn, Attributes entry ) throws NamingException
257     {
258         db.add( updn, dn, entry );
259     }
260 
261 
262     /***
263      * @see org.apache.ldap.server.BackingStore#modify( Name, int, Attributes )
264      */
265     public void modify( Name dn, int modOp, Attributes mods ) throws NamingException
266     {
267         db.modify( dn, modOp, mods );
268     }
269 
270 
271     /***
272      * @see org.apache.ldap.server.BackingStore#modify( Name,ModificationItem[] )
273      */
274     public void modify( Name dn, ModificationItem[] mods ) throws NamingException
275     {
276         db.modify( dn, mods );
277     }
278 
279 
280     /***
281      * @see org.apache.ldap.server.BackingStore#list( Name )
282      */
283     public NamingEnumeration list( Name base ) throws NamingException
284     {
285         SearchResultEnumeration list;
286         list = new SearchResultEnumeration( ArrayUtils.EMPTY_STRING_ARRAY,
287                 db.list( db.getEntryId( base.toString() ) ), db );
288         return list;
289     }
290     
291     
292     /***
293      * @see org.apache.ldap.server.BackingStore#search(Name, Map, ExprNode, SearchControls)
294      */
295     public NamingEnumeration search( Name base, Map env, ExprNode filter,
296                                      SearchControls searchCtls )
297         throws NamingException
298     {
299         String [] attrIds = searchCtls.getReturningAttributes();
300         NamingEnumeration underlying = null;
301         
302         underlying = engine.search( base, env, filter, searchCtls );
303         
304         return new SearchResultEnumeration( attrIds, underlying, db );
305     }
306 
307 
308     /***
309      * @see org.apache.ldap.server.BackingStore#lookup( Name )
310      */
311     public Attributes lookup( Name dn ) throws NamingException
312     {
313         return db.lookup( db.getEntryId( dn.toString() ) );
314     }
315 
316 
317     /***
318      * @see BackingStore#lookup(Name,String[])
319      */
320     public Attributes lookup( Name dn, String [] attrIds ) throws NamingException
321     {
322         if ( attrIds == null || attrIds.length == 0 )
323         {
324             return lookup( dn );
325         }
326 
327         Attributes entry = lookup( dn );
328         Attributes retval = new LockableAttributesImpl();
329 
330         for ( int ii = 0; ii < attrIds.length; ii++ )
331         {
332             Attribute attr = entry.get( attrIds[0] );
333 
334             if ( attr != null )
335             {
336                 retval.put( attr );
337             }
338         }
339 
340         return retval;
341     }
342 
343 
344     /***
345      * @see org.apache.ldap.server.BackingStore#hasEntry( Name )
346      */
347     public boolean hasEntry( Name dn ) throws NamingException
348     {
349         return null != db.getEntryId( dn.toString() );
350     }
351 
352 
353     /***
354      * @see BackingStore#modifyRn( Name, String, boolean )
355      */
356     public void modifyRn( Name dn, String newRdn, boolean deleteOldRdn ) throws NamingException
357     {
358         db.modifyRdn( dn, newRdn, deleteOldRdn );
359     }
360 
361 
362     /***
363      * @see org.apache.ldap.server.BackingStore#move( Name, Name )
364      */
365     public void move( Name oldChildDn, Name newParentDn ) throws NamingException
366     {
367         db.move( oldChildDn, newParentDn );
368     }
369     
370 
371     /***
372      * @see org.apache.ldap.server.BackingStore#move( Name, Name, String, boolean )
373      */
374     public void move( Name oldChildDn, Name newParentDn, String newRdn,
375         boolean deleteOldRdn ) throws NamingException
376     {
377         db.move( oldChildDn, newParentDn, newRdn, deleteOldRdn );
378     }
379 
380 
381     public void sync() throws NamingException
382     {
383         db.sync();
384     }
385 
386 
387     public void close() throws NamingException
388     {
389         db.close();
390     }
391 
392 
393     public boolean isClosed()
394     {
395         return db.isClosed();
396     }
397 
398 
399     public void inspect() throws Exception
400     {
401         PartitionViewer viewer = new PartitionViewer( db, engine );
402         viewer.execute();
403     }
404 }