View Javadoc
1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    * 
10   *    http://www.apache.org/licenses/LICENSE-2.0
11   * 
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License.
18   * 
19   */
20  package org.apache.directory.server.core.api.partition;
21  
22  
23  import java.io.IOException;
24  import java.io.OutputStream;
25  
26  import javax.naming.InvalidNameException;
27  
28  import org.apache.directory.api.ldap.model.entry.Entry;
29  import org.apache.directory.api.ldap.model.exception.LdapException;
30  import org.apache.directory.api.ldap.model.exception.LdapInvalidDnException;
31  import org.apache.directory.api.ldap.model.exception.LdapOtherException;
32  import org.apache.directory.api.ldap.model.name.Dn;
33  import org.apache.directory.api.ldap.model.schema.SchemaManager;
34  import org.apache.directory.api.util.Strings;
35  import org.apache.directory.server.core.api.DnFactory;
36  import org.apache.directory.server.i18n.I18n;
37  
38  
39  /**
40   * A {@link Partition} that helps users to implement their own partition.
41   * Most methods are implemented by default.  Please look at the description of
42   * each methods for the detail of implementations.
43   *
44   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
45   */
46  public abstract class AbstractPartition implements Partition
47  {
48      /** <tt>true</tt> if and only if this partition is initialized. */
49      protected boolean initialized;
50  
51      /** The partition ContextEntry */
52      protected Entry contextEntry;
53  
54      /** The SchemaManager instance */
55      protected SchemaManager schemaManager;
56  
57      /** The DnFactory to use to create DN */
58      protected DnFactory dnFactory;
59  
60      /** The partition ID */
61      protected String id;
62  
63      /** The root Dn for this partition */
64      protected Dn suffixDn;
65  
66      /** the value of last successful add/update operation's CSN */
67      private String contextCsn;
68      
69      /** a flag to detect the change in context CSN */
70      protected volatile boolean ctxCsnChanged = false;
71  
72      /**
73       * {@inheritDoc}
74       */
75      @Override
76      public void initialize() throws LdapException
77      {
78          if ( initialized )
79          {
80              // Already initialized.
81              return;
82          }
83  
84          try
85          {
86              doInit();
87              initialized = true;
88          }
89          catch ( Exception e )
90          {
91              throw new LdapOtherException( e.getMessage(), e );
92          }
93          finally
94          {
95              if ( !initialized )
96              {
97                  try
98                  {
99                      destroy( null );
100                 }
101                 catch ( Exception e )
102                 {
103                     throw new LdapOtherException( e.getMessage(), e );
104                 }
105             }
106         }
107     }
108 
109 
110     /**
111      * {@inheritDoc}
112      */
113     @Override
114     public void repair() throws LdapException
115     {
116         // Do nothing. It will be handled by the implementation classes
117     }
118 
119 
120     /**
121      * Override this method to put your initialization code.
122      * 
123      * @param partitionTxn The transaction to use
124      * @throws LdapException If the destroy call failed
125      */
126     protected abstract void doDestroy( PartitionTxn partitionTxn ) throws LdapException;
127 
128 
129     /**
130      * Override this method to put your initialization code.
131      * 
132      * @throws LdapException If the initialization failed
133      * @throws InvalidNameException If the initialization failed
134      */
135     protected abstract void doInit() throws InvalidNameException, LdapException;
136 
137 
138     /**
139      * Override this method to implement a repair method
140      * 
141      * @throws LdapException If the repair failed
142      */
143     protected abstract void doRepair() throws LdapException;
144 
145 
146     /**
147      * Calls <code>doDestroy()</code> where you have to put your destroy code in,
148      * and clears default properties.  Once this method is invoked, <code>isInitialized()</code>
149      * will return <tt>false</tt>.
150      */
151     @Override
152     public final void destroy( PartitionTxn partitionTxn ) throws LdapException
153     {
154         try
155         {
156             doDestroy( partitionTxn );
157         }
158         finally
159         {
160             initialized = false;
161         }
162     }
163 
164 
165     /**
166      * {@inheritDoc}
167      */
168     @Override
169     public final boolean isInitialized()
170     {
171         return initialized;
172     }
173 
174 
175     /**
176      * {@inheritDoc}
177      */
178     @Override
179     public void setSchemaManager( SchemaManager schemaManager )
180     {
181         this.schemaManager = schemaManager;
182     }
183 
184 
185     /**
186      * {@inheritDoc}
187      */
188     @Override
189     public final SchemaManager getSchemaManager()
190     {
191         return schemaManager;
192     }
193 
194 
195     /**
196      * {@inheritDoc}
197      */
198     @Override
199     public final String getId()
200     {
201         return id;
202     }
203 
204 
205     /**
206      * {@inheritDoc}
207      */
208     @Override
209     public void setId( String id )
210     {
211         checkInitialized( "id" );
212         this.id = id;
213     }
214 
215 
216     /**
217      * {@inheritDoc}
218      */
219     @Override
220     public final Dn getSuffixDn()
221     {
222         return suffixDn;
223     }
224 
225 
226     /**
227      * {@inheritDoc}
228      */
229     @Override
230     public void setSuffixDn( Dn suffixDn ) throws LdapInvalidDnException
231     {
232         checkInitialized( "suffixDn" );
233 
234         if ( suffixDn.isSchemaAware() )
235         {
236             this.suffixDn = suffixDn;
237         }
238         else
239         {
240             this.suffixDn = new Dn( schemaManager, suffixDn );
241         }
242     }
243 
244 
245     /**
246      * {@inheritDoc}
247      */
248     @Override
249     public void dumpIndex( PartitionTxn partitionTxn, OutputStream stream, String name ) throws IOException
250     {
251         stream.write( Strings.getBytesUtf8( "Nothing to dump for index " + name ) );
252     }
253 
254 
255     /**
256      * Check that the operation is done on an initialized store
257      * 
258      * @param property The property that was initialized
259      */
260     protected void checkInitialized( String property )
261     {
262         if ( initialized )
263         {
264             throw new IllegalStateException( I18n.err( I18n.ERR_576, property ) );
265         }
266     }
267 
268 
269     /**
270      * @return the contextEntry
271      */
272     public Entry getContextEntry()
273     {
274         return contextEntry;
275     }
276 
277 
278     /**
279      * @param contextEntry the contextEntry to set
280      */
281     public void setContextEntry( Entry contextEntry )
282     {
283         this.contextEntry = contextEntry;
284     }
285 
286 
287     /**
288      * {@inheritDoc}
289      */
290     @Override
291     public String getContextCsn( PartitionTxn partitionTxn )
292     {
293         return contextCsn;
294     }
295 
296     
297     /**
298      * Replaces the current context CSN with the given CSN value if they are not same and
299      * sets the ctxCsnChanged flag to true.
300      * 
301      * @param csn the CSN value
302      */
303     protected void setContextCsn( String csn )
304     {
305         if ( !csn.equals( contextCsn ) )
306         {
307             contextCsn = csn;
308             ctxCsnChanged = true;
309         }
310     }
311 
312 
313     /**
314      * {@inheritDoc}
315      */
316     @Override
317     public void sync() throws LdapException
318     {
319         // Do nothing by default
320     }
321 }