1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
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
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
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
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
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 }