001    /*
002     *   Licensed to the Apache Software Foundation (ASF) under one
003     *   or more contributor license agreements.  See the NOTICE file
004     *   distributed with this work for additional information
005     *   regarding copyright ownership.  The ASF licenses this file
006     *   to you under the Apache License, Version 2.0 (the
007     *   "License"); you may not use this file except in compliance
008     *   with the License.  You may obtain a copy of the License at
009     *
010     *     http://www.apache.org/licenses/LICENSE-2.0
011     *
012     *   Unless required by applicable law or agreed to in writing,
013     *   software distributed under the License is distributed on an
014     *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015     *   KIND, either express or implied.  See the License for the
016     *   specific language governing permissions and limitations
017     *   under the License.
018     *
019     */
020    package org.apache.directory.server.xdbm;
021    
022    
023    import java.util.Iterator;
024    import java.util.List;
025    
026    import org.apache.directory.server.core.entry.ClonedServerEntry;
027    import org.apache.directory.server.core.interceptor.context.AddOperationContext;
028    import org.apache.directory.server.core.interceptor.context.BindOperationContext;
029    import org.apache.directory.server.core.interceptor.context.ModifyOperationContext;
030    import org.apache.directory.server.core.interceptor.context.MoveAndRenameOperationContext;
031    import org.apache.directory.server.core.interceptor.context.MoveOperationContext;
032    import org.apache.directory.server.core.interceptor.context.RenameOperationContext;
033    import org.apache.directory.server.core.interceptor.context.UnbindOperationContext;
034    import org.apache.directory.server.core.partition.impl.btree.BTreePartition;
035    import org.apache.directory.server.i18n.I18n;
036    import org.apache.directory.shared.ldap.entry.ServerEntry;
037    import org.apache.directory.shared.ldap.exception.LdapAuthenticationNotSupportedException;
038    import org.apache.directory.shared.ldap.exception.LdapUnwillingToPerformException;
039    import org.apache.directory.shared.ldap.message.ResultCodeEnum;
040    import org.apache.directory.shared.ldap.name.DN;
041    import org.apache.directory.shared.ldap.name.RDN;
042    
043    
044    /**
045     * Base class for XDBM partitions that use an {@link Store}.
046     *
047     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
048     * @version $Rev$, $Date$
049     */
050    public abstract class AbstractXdbmPartition<ID> extends BTreePartition<ID>
051    {
052    
053        protected boolean optimizerEnabled = true;
054    
055        /** The store. */
056        protected Store<ServerEntry, ID> store;
057    
058    
059        protected AbstractXdbmPartition( Store<ServerEntry, ID> store )
060        {
061            this.store = store;
062        }
063    
064    
065        /**
066         * {@inheritDoc}
067         */
068        protected void doDestroy() throws Exception
069        {
070            store.destroy();
071        }
072    
073    
074        /**
075         * {@inheritDoc}
076         */
077        public final boolean isInitialized()
078        {
079            return store.isInitialized();
080        }
081    
082    
083        /**
084         * {@inheritDoc}
085         */
086        public final void sync() throws Exception
087        {
088            store.sync();
089        }
090    
091    
092        // ------------------------------------------------------------------------
093        // C O N F I G U R A T I O N   M E T H O D S
094        // ------------------------------------------------------------------------
095    
096        public boolean isOptimizerEnabled()
097        {
098            return optimizerEnabled;
099        }
100    
101    
102        public void setOptimizerEnabled( boolean optimizerEnabled )
103        {
104            this.optimizerEnabled = optimizerEnabled;
105        }
106    
107    
108        public void setSyncOnWrite( boolean syncOnWrite )
109        {
110            store.setSyncOnWrite( syncOnWrite );
111        }
112    
113    
114        public boolean isSyncOnWrite()
115        {
116            return store.isSyncOnWrite();
117        }
118    
119    
120        // ------------------------------------------------------------------------
121        // I N D E X   M E T H O D S
122        // ------------------------------------------------------------------------
123    
124        public final void addIndexOn( Index<? extends Object, ServerEntry, ID> index ) throws Exception
125        {
126            store.addIndex( index );
127        }
128    
129    
130        public final Index<String, ServerEntry, ID> getExistenceIndex()
131        {
132            return store.getPresenceIndex();
133        }
134    
135    
136        /**
137         * @org.apache.xbean.Property hidden="true"
138         */
139        public final void setPresenceIndexOn( Index<String, ServerEntry, ID> index ) throws Exception
140        {
141            store.setPresenceIndex( index );
142        }
143    
144    
145        public final Index<ID, ServerEntry, ID> getOneLevelIndex()
146        {
147            return store.getOneLevelIndex();
148        }
149    
150    
151        /**
152         * @org.apache.xbean.Property hidden="true"
153         */
154        public final void setOneLevelIndexOn( Index<ID, ServerEntry, ID> index ) throws Exception
155        {
156            store.setOneLevelIndex( index );
157        }
158    
159    
160        public final Index<String, ServerEntry, ID> getAliasIndex()
161        {
162            return store.getAliasIndex();
163        }
164    
165    
166        /**
167         * @org.apache.xbean.Property hidden="true"
168         */
169        public final void setAliasIndexOn( Index<String, ServerEntry, ID> index ) throws Exception
170        {
171            store.setAliasIndex( index );
172        }
173    
174    
175        public final Index<ID, ServerEntry, ID> getOneAliasIndex()
176        {
177            return store.getOneAliasIndex();
178        }
179    
180    
181        /**
182         * @org.apache.xbean.Property hidden="true"
183         */
184        public final void setOneAliasIndexOn( Index<ID, ServerEntry, ID> index ) throws Exception
185        {
186            store.setOneAliasIndex( index );
187        }
188    
189    
190        public final Index<ID, ServerEntry, ID> getSubAliasIndex()
191        {
192            return store.getSubAliasIndex();
193        }
194    
195    
196        /**
197         * @org.apache.xbean.Property hidden="true"
198         */
199        public final void setSubAliasIndexOn( Index<ID, ServerEntry, ID> index ) throws Exception
200        {
201            store.setSubAliasIndex( index );
202        }
203    
204    
205        public final Index<String, ServerEntry, ID> getUpdnIndex()
206        {
207            return store.getUpdnIndex();
208        }
209    
210    
211        /**
212         * @org.apache.xbean.Property hidden="true"
213         */
214        public final void setUpdnIndexOn( Index<String, ServerEntry, ID> index ) throws Exception
215        {
216            store.setUpdnIndex( index );
217        }
218    
219    
220        public final Index<String, ServerEntry, ID> getNdnIndex()
221        {
222            return store.getNdnIndex();
223        }
224    
225    
226        /**
227         * @org.apache.xbean.Property hidden="true"
228         */
229        public final void setNdnIndexOn( Index<String, ServerEntry, ID> index ) throws Exception
230        {
231            store.setNdnIndex( index );
232        }
233    
234    
235        public final Iterator<String> getUserIndices()
236        {
237            return store.userIndices();
238        }
239    
240    
241        public final Iterator<String> getSystemIndices()
242        {
243            return store.systemIndices();
244        }
245    
246    
247        public final boolean hasUserIndexOn( String id ) throws Exception
248        {
249            return store.hasUserIndexOn( id );
250        }
251    
252    
253        public final boolean hasSystemIndexOn( String id ) throws Exception
254        {
255            return store.hasSystemIndexOn( id );
256        }
257    
258    
259        /**
260         * @see org.apache.directory.server.core.partition.impl.btree.BTreePartition#getUserIndex(String)
261         */
262        public final Index<? extends Object, ServerEntry, ID> getUserIndex( String id ) throws IndexNotFoundException
263        {
264            return store.getUserIndex( id );
265        }
266    
267    
268        /**
269         * @see BTreePartition#getEntryId(String)
270         */
271        public final Index<? extends Object, ServerEntry, ID> getSystemIndex( String id ) throws IndexNotFoundException
272        {
273            return store.getSystemIndex( id );
274        }
275    
276    
277        public final ID getEntryId( String dn ) throws Exception
278        {
279            return store.getEntryId( dn );
280        }
281    
282    
283        public final String getEntryDn( ID id ) throws Exception
284        {
285            return store.getEntryDn( id );
286        }
287    
288    
289        public final ID getParentId( String dn ) throws Exception
290        {
291            return store.getParentId( dn );
292        }
293    
294    
295        public final ID getParentId( ID childId ) throws Exception
296        {
297            return store.getParentId( childId );
298        }
299    
300    
301        public final String getEntryUpdn( ID id ) throws Exception
302        {
303            return store.getEntryUpdn( id );
304        }
305    
306    
307        public final String getEntryUpdn( String dn ) throws Exception
308        {
309            return store.getEntryUpdn( dn );
310        }
311    
312    
313        public final int count() throws Exception
314        {
315            return store.count();
316        }
317    
318    
319        public final void add( AddOperationContext addContext ) throws Exception
320        {
321            store.add( ( ServerEntry ) ( ( ClonedServerEntry ) addContext.getEntry() ).getClonedEntry() );
322        }
323    
324    
325        public final ClonedServerEntry lookup( ID id ) throws Exception
326        {
327            return new ClonedServerEntry( store.lookup( id ) );
328        }
329    
330    
331        public final void delete( ID id ) throws Exception
332        {
333            store.delete( id );
334        }
335    
336    
337        public final IndexCursor<ID, ServerEntry, ID> list( ID id ) throws Exception
338        {
339            return store.list( id );
340        }
341    
342    
343        public final int getChildCount( ID id ) throws Exception
344        {
345            return store.getChildCount( id );
346        }
347    
348    
349        public final void setProperty( String propertyName, String propertyValue ) throws Exception
350        {
351            store.setProperty( propertyName, propertyValue );
352        }
353    
354    
355        public final String getProperty( String propertyName ) throws Exception
356        {
357            return store.getProperty( propertyName );
358        }
359    
360    
361        public final void modify( ModifyOperationContext modifyContext ) throws Exception
362        {
363            store.modify( modifyContext.getDn(), modifyContext.getModItems() );
364        }
365    
366    
367        public final void rename( RenameOperationContext renameContext ) throws Exception
368        {
369            store.rename( renameContext.getDn(), renameContext.getNewRdn(), renameContext.getDelOldDn() );
370        }
371    
372    
373        public final void moveAndRename( MoveAndRenameOperationContext moveAndRenameContext ) throws Exception
374        {
375            checkIsValidMove( moveAndRenameContext.getDn(), moveAndRenameContext.getParent() );
376            store.move( moveAndRenameContext.getDn(), moveAndRenameContext.getParent(), moveAndRenameContext.getNewRdn(),
377                moveAndRenameContext.getDelOldDn() );
378        }
379    
380    
381        public final void move( MoveOperationContext moveContext ) throws Exception
382        {
383            checkIsValidMove( moveContext.getDn(), moveContext.getParent() );
384            store.move( moveContext.getDn(), moveContext.getParent() );
385        }
386    
387    
388        /**
389         * 
390         * checks whether the moving of given entry is valid
391         *
392         * @param oldChildDn the entry's DN to be moved
393         * @param newParentDn new parent entry's DN
394         * @throws Exception
395         */
396        private void checkIsValidMove( DN oldChildDn, DN newParentDn ) throws Exception
397        {
398            boolean invalid = false;
399    
400            DN newParentDNClone = ( DN ) newParentDn.clone();
401            newParentDNClone.remove( newParentDNClone.size() - 1 );
402    
403            if ( newParentDn.size() >= oldChildDn.size() )
404            {
405                for ( int i = 0; i < oldChildDn.size(); i++ )
406                {
407                    RDN nameRdn = oldChildDn.getRdn( i );
408                    RDN ldapRdn = newParentDn.getRdn( i );
409    
410                    if ( nameRdn.compareTo( ldapRdn ) == 0 )
411                    {
412                        invalid = true;
413                    }
414                    else
415                    {
416                        invalid = false;
417                        break;
418                    }
419                }
420            }
421    
422            if ( invalid )
423            {
424                throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM,
425                    "cannot place an entry below itself" );
426            }
427    
428        }
429    
430    
431        public final void bind( DN bindDn, byte[] credentials, List<String> mechanisms, String saslAuthId )
432            throws Exception
433        {
434            if ( bindDn == null || credentials == null || mechanisms == null || saslAuthId == null )
435            {
436                // do nothing just using variables to prevent yellow lights : bad :)
437            }
438    
439            // does nothing
440            throw new LdapAuthenticationNotSupportedException( ResultCodeEnum.AUTH_METHOD_NOT_SUPPORTED,
441                I18n.err( I18n.ERR_702 ) );
442        }
443    
444    
445        public final void bind( BindOperationContext bindContext ) throws Exception
446        {
447            // does nothing
448            throw new LdapAuthenticationNotSupportedException( ResultCodeEnum.AUTH_METHOD_NOT_SUPPORTED,
449                I18n.err( I18n.ERR_702 ) );
450        }
451    
452    
453        public final void unbind( UnbindOperationContext unbindContext ) throws Exception
454        {
455        }
456    
457    
458        public final Index<String, ServerEntry, ID> getPresenceIndex()
459        {
460            return store.getPresenceIndex();
461        }
462    
463    
464        public final Index<ID, ServerEntry, ID> getSubLevelIndex()
465        {
466            return store.getSubLevelIndex();
467        }
468    
469    
470        /**
471         * {@inheritDoc}
472         */
473        public String toString()
474        {
475            return "Partition<" + id + ">";
476        }
477    
478    }