1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.ldap.server.partition;
18
19 import java.util.ArrayList;
20 import java.util.List;
21
22 import javax.naming.Name;
23 import javax.naming.NameNotFoundException;
24 import javax.naming.NamingEnumeration;
25 import javax.naming.NamingException;
26 import javax.naming.OperationNotSupportedException;
27 import javax.naming.directory.Attribute;
28 import javax.naming.directory.Attributes;
29 import javax.naming.directory.ModificationItem;
30
31 import org.apache.ldap.common.name.LdapName;
32 import org.apache.ldap.server.configuration.ContextPartitionConfiguration;
33 import org.apache.ldap.server.jndi.ContextFactoryConfiguration;
34
35 /***
36 * A {@link ContextPartition} that helps users to implement their own partition.
37 * Most methods are implemented by default. Please look at the description of
38 * each methods for the detail of implementations.
39 *
40 * @author The Apache Directory Project
41 * @version $Rev: 264732 $, $Date: 2005-08-30 04:04:51 -0400 (Tue, 30 Aug 2005) $
42 */
43 public abstract class AbstractContextPartition implements ContextPartition
44 {
45 /*** {@link ContextFactoryConfiguration} specified at {@link #init(ContextFactoryConfiguration, ContextPartitionConfiguration)}. */
46 private ContextFactoryConfiguration factoryCfg;
47 /*** {@link ContextPartitionConfiguration} specified at {@link #init(ContextFactoryConfiguration, ContextPartitionConfiguration)}. */
48 private ContextPartitionConfiguration cfg;
49 /*** <tt>true</tt> if and only if this partition is initialized. */
50 private boolean initialized;
51
52 protected AbstractContextPartition()
53 {
54 }
55
56 /***
57 * Sets up default properties(<tt>factoryConfiguration</tt> and <tt>configuration</tt>) and
58 * calls {@link #doInit()} where you have to put your initialization code in.
59 * {@link #isInitialized()} will return <tt>true</tt> if {@link #doInit()} returns
60 * without any errors. {@link #destroy()} is called automatically as a clean-up process
61 * if {@link #doInit()} throws an exception.
62 */
63 public final void init( ContextFactoryConfiguration factoryCfg, ContextPartitionConfiguration cfg ) throws NamingException
64 {
65 if( initialized )
66 {
67
68 return;
69 }
70
71 this.factoryCfg = factoryCfg;
72 this.cfg = cfg;
73 try{
74 doInit();
75 initialized = true;
76 }
77 finally
78 {
79 if( !initialized )
80 {
81 destroy();
82 }
83 }
84 }
85
86 /***
87 * Override this method to put your initialization code.
88 */
89 protected void doInit() throws NamingException
90 {
91 }
92
93 /***
94 * Calls {@link #doDestroy()} where you have to put your destroy code in,
95 * and clears default properties. Once this method is invoked, {@link #isInitialized()}
96 * will return <tt>false</tt>.
97 */
98 public final void destroy()
99 {
100 if( cfg == null )
101 {
102
103 return;
104 }
105
106 try
107 {
108 doDestroy();
109 }
110 finally
111 {
112 initialized = false;
113 factoryCfg = null;
114 cfg = null;
115 }
116 }
117
118 /***
119 * Override this method to put your initialization code.
120 */
121 protected void doDestroy()
122 {
123 }
124
125 /***
126 * Returns <tt>true</tt> if this context partition is initialized successfully.
127 */
128 public final boolean isInitialized()
129 {
130 return initialized;
131 }
132
133 /***
134 * Returns {@link ContextFactoryConfiguration} that is provided from
135 * {@link #init(ContextFactoryConfiguration, ContextPartitionConfiguration)}.
136 */
137 public final ContextFactoryConfiguration getFactoryConfiguration()
138 {
139 return factoryCfg;
140 }
141
142 /***
143 * Returns {@link ContextPartitionConfiguration} that is provided from
144 * {@link #init(ContextFactoryConfiguration, ContextPartitionConfiguration)}.
145 */
146 public final ContextPartitionConfiguration getConfiguration()
147 {
148 return cfg;
149 }
150
151 public final Name getSuffix( boolean normalized ) throws NamingException
152 {
153 if( normalized )
154 {
155 return getConfiguration().getNormalizedSuffix(
156 getFactoryConfiguration().getGlobalRegistries().getMatchingRuleRegistry() );
157 }
158 else
159 {
160 return new LdapName( getConfiguration().getSuffix() );
161 }
162 }
163
164 public final boolean isSuffix( Name name ) throws NamingException
165 {
166 return getSuffix( true ).equals( name ) || getSuffix( false ).equals( name );
167 }
168
169 /***
170 * This method does nothing by default.
171 */
172 public void sync() throws NamingException
173 {
174 }
175
176 /***
177 * This method calls {@link #lookup(Name)} and return <tt>true</tt>
178 * if it returns an entry by default. Please override this method if
179 * there is more effective way for your implementation.
180 */
181 public boolean hasEntry( Name name ) throws NamingException
182 {
183 try
184 {
185 return lookup( name ) != null;
186 }
187 catch( NameNotFoundException e )
188 {
189 return false;
190 }
191 }
192
193 /***
194 * This method calls {@link ContextPartition#lookup(Name, String[])}
195 * with null <tt>attributeIds</tt> by default. Please override
196 * this method if there is more effective way for your implementation.
197 */
198 public Attributes lookup( Name name ) throws NamingException
199 {
200 return lookup( name, null );
201 }
202
203 /***
204 * This method forwards the request to
205 * {@link ContextPartition#modify(Name, ModificationItem[])} after
206 * translating parameters to {@link ModificationItem}<tt>[]</tt> by default.
207 * Please override this method if there is more effactive way for your
208 * implementation.
209 */
210 public void modify( Name name, int modOp, Attributes mods ) throws NamingException
211 {
212 List items = new ArrayList( mods.size() );
213 NamingEnumeration e = mods.getAll();
214 while( e.hasMore() )
215 {
216 items.add( new ModificationItem( modOp, ( Attribute ) e.next() ) );
217 }
218
219 ModificationItem[] itemsArray = new ModificationItem[ items.size() ];
220 itemsArray = ( ModificationItem[] ) items.toArray( itemsArray );
221 modify( name, itemsArray );
222 }
223
224 /***
225 * This method calls {@link ContextPartition#move(Name, Name)} and
226 * {@link ContextPartition#modifyRn(Name, String, boolean)} subsequently
227 * by default. Please override this method if there is more effactive
228 * way for your implementation.
229 */
230 public void move( Name oldName, Name newParentName, String newRn, boolean deleteOldRn ) throws NamingException
231 {
232 Name newName = ( Name ) newParentName.clone();
233 newName.add( newRn );
234 move( oldName, newParentName );
235 modifyRn( newName, newRn, deleteOldRn );
236 }
237
238 /***
239 * This method throws {@link OperationNotSupportedException} by default.
240 * Please override this method to implement move operation.
241 */
242 public void move( Name oldName, Name newParentName ) throws NamingException
243 {
244 throw new OperationNotSupportedException( "Moving an entry to other parent entry is not supported." );
245 }
246 }