1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.directory.server.core.prefs;
21
22
23 import org.apache.directory.server.constants.ApacheSchemaConstants;
24 import org.apache.directory.server.core.DirectoryService;
25 import org.apache.directory.server.core.entry.ClonedServerEntry;
26 import org.apache.directory.server.core.entry.DefaultServerAttribute;
27 import org.apache.directory.server.core.entry.ServerAttribute;
28 import org.apache.directory.server.core.entry.ServerEntry;
29 import org.apache.directory.server.core.entry.ServerModification;
30 import org.apache.directory.server.core.filtering.EntryFilteringCursor;
31 import org.apache.directory.shared.ldap.constants.SchemaConstants;
32 import org.apache.directory.shared.ldap.entry.EntryAttribute;
33 import org.apache.directory.shared.ldap.entry.Modification;
34 import org.apache.directory.shared.ldap.entry.ModificationOperation;
35 import org.apache.directory.shared.ldap.message.AliasDerefMode;
36 import org.apache.directory.shared.ldap.name.LdapDN;
37 import org.apache.directory.shared.ldap.schema.AttributeType;
38 import org.apache.directory.shared.ldap.util.PreferencesDictionary;
39
40 import javax.naming.InvalidNameException;
41 import javax.naming.NamingException;
42
43 import java.util.ArrayList;
44 import java.util.Dictionary;
45 import java.util.HashMap;
46 import java.util.List;
47 import java.util.prefs.AbstractPreferences;
48 import java.util.prefs.BackingStoreException;
49 import java.util.prefs.Preferences;
50
51
52
53
54
55
56
57
58
59
60 public class ServerSystemPreferences extends AbstractPreferences
61 {
62
63 private static final String[] EMPTY_STRINGS = new String[0];
64
65
66 private List<Modification> changes = new ArrayList<Modification>( 3 );
67
68
69 private HashMap<String, List<Modification>> keyToChange = new HashMap<String, List<Modification>>( 3 );
70
71 private LdapDN dn;
72
73 private DirectoryService directoryService;
74
75
76
77
78
79
80
81 public ServerSystemPreferences( DirectoryService directoryService )
82 {
83 super( null, "" );
84 super.newNode = false;
85
86 try
87 {
88 dn = new LdapDN( "prefNodeName=sysPrefRoot,ou=system" );
89 }
90 catch ( InvalidNameException e )
91 {
92
93 }
94
95 this.directoryService = directoryService;
96 }
97
98
99 public void close() throws NamingException
100 {
101 }
102
103
104
105
106
107
108
109
110 public ServerSystemPreferences( ServerSystemPreferences parent, String name )
111 {
112 super( parent, name );
113
114 this.directoryService = parent.directoryService;
115 LdapDN parentDn = ( ( ServerSystemPreferences ) parent() ).dn;
116 try
117 {
118 dn = new LdapDN( "prefNodeName=" + name + "," + parentDn.getUpName() );
119 dn.normalize( directoryService.getRegistries().getAttributeTypeRegistry().getNormalizerMapping() );
120
121 if ( ! directoryService.getAdminSession().exists( dn ) )
122 {
123 ServerEntry entry = directoryService.newEntry( dn );
124 entry.add( SchemaConstants.OBJECT_CLASS_AT, SchemaConstants.TOP_OC,
125 ApacheSchemaConstants.PREF_NODE_OC, SchemaConstants.EXTENSIBLE_OBJECT_OC );
126 entry.add( "prefNodeName", name );
127
128 directoryService.getAdminSession().add( entry );
129
130 super.newNode = false;
131 }
132 }
133 catch ( Exception e )
134 {
135 throw new ServerSystemPreferenceException( "Failed to set up node.", e );
136 }
137 }
138
139
140
141
142
143
144
145
146
147
148
149 public Dictionary<String, String> wrapAsDictionary()
150 {
151 return new PreferencesDictionary( this );
152 }
153
154
155
156
157
158
159 protected void flushSpi() throws BackingStoreException
160 {
161 if ( changes.isEmpty() )
162 {
163 return;
164 }
165
166 try
167 {
168 directoryService.getAdminSession().modify( dn, changes );
169 }
170 catch ( Exception e )
171 {
172 throw new BackingStoreException( e );
173 }
174
175 changes.clear();
176 keyToChange.clear();
177 }
178
179
180 protected void removeNodeSpi() throws BackingStoreException
181 {
182 try
183 {
184 directoryService.getAdminSession().delete( dn );
185 }
186 catch ( Exception e )
187 {
188 throw new BackingStoreException( e );
189 }
190
191 changes.clear();
192 keyToChange.clear();
193 }
194
195
196 protected void syncSpi() throws BackingStoreException
197 {
198 if ( changes.isEmpty() )
199 {
200 return;
201 }
202
203 try
204 {
205 directoryService.getAdminSession().modify( dn, changes );
206 }
207 catch ( Exception e )
208 {
209 throw new BackingStoreException( e );
210 }
211
212 changes.clear();
213 keyToChange.clear();
214 }
215
216
217 protected String[] childrenNamesSpi() throws BackingStoreException
218 {
219 List<String> children = new ArrayList<String>();
220 EntryFilteringCursor list;
221
222 try
223 {
224 list = directoryService.getAdminSession().list( dn, AliasDerefMode.DEREF_ALWAYS, null );
225 list.beforeFirst();
226 while ( list.next() )
227 {
228 ClonedServerEntry entry = list.get();
229 children.add( ( String ) entry.getDn().getRdn().getValue() );
230 }
231 }
232 catch ( Exception e )
233 {
234 throw new BackingStoreException( e );
235 }
236
237 return children.toArray( EMPTY_STRINGS );
238 }
239
240
241 protected String[] keysSpi() throws BackingStoreException
242 {
243 List<String> keys = new ArrayList<String>();
244
245 try
246 {
247 ServerEntry entry = directoryService.getAdminSession().lookup( dn );
248 for ( EntryAttribute attr : entry )
249 {
250 ServerAttribute sa = ( ServerAttribute ) attr;
251 String oid = sa.getAttributeType().getOid();
252
253 if ( oid.equals( SchemaConstants.OBJECT_CLASS_AT_OID ) )
254 {
255 continue;
256 }
257
258 keys.add( sa.getUpId() );
259 }
260 }
261 catch ( Exception e )
262 {
263 throw new BackingStoreException( e );
264 }
265
266 return keys.toArray( EMPTY_STRINGS );
267 }
268
269
270 protected void removeSpi( String key )
271 {
272 AttributeType at;
273 try
274 {
275 at = directoryService.getRegistries().getAttributeTypeRegistry().lookup( key );
276 ServerAttribute attr = new DefaultServerAttribute( at );
277 Modification mi = new ServerModification( ModificationOperation.REMOVE_ATTRIBUTE, attr );
278 addDelta( mi );
279 }
280 catch ( NamingException e )
281 {
282 e.printStackTrace();
283 }
284 }
285
286
287 private void addDelta( Modification mi )
288 {
289 String key = mi.getAttribute().getUpId();
290 List<Modification> deltas;
291 changes.add( mi );
292
293 if ( keyToChange.containsKey( key ) )
294 {
295 deltas = keyToChange.get( key );
296 }
297 else
298 {
299 deltas = new ArrayList<Modification>();
300 }
301
302 deltas.add( mi );
303 keyToChange.put( key, deltas );
304 }
305
306
307 protected String getSpi( String key )
308 {
309 try
310 {
311 EntryAttribute attr = directoryService.getAdminSession().lookup( dn ).get( key );
312
313 if ( keyToChange.containsKey( key ) )
314 {
315 for ( Modification mod : keyToChange.get( key ) )
316 {
317 if ( mod.getOperation() == ModificationOperation.REMOVE_ATTRIBUTE )
318 {
319 attr = null;
320 }
321 else
322 {
323 attr = mod.getAttribute();
324 }
325 }
326 }
327
328 if ( attr == null )
329 {
330 return null;
331 }
332 else
333 {
334 return attr.getString();
335 }
336 }
337 catch ( Exception e )
338 {
339 throw new ServerSystemPreferenceException( "Failed to get SPI.", e );
340 }
341 }
342
343
344 protected void putSpi( String key, String value )
345 {
346 AttributeType at;
347 try
348 {
349 at = directoryService.getRegistries().getAttributeTypeRegistry().lookup( key );
350 ServerAttribute attr = new DefaultServerAttribute( at, value );
351 Modification mi = new ServerModification( ModificationOperation.REPLACE_ATTRIBUTE, attr );
352 addDelta( mi );
353 }
354 catch ( NamingException e )
355 {
356 e.printStackTrace();
357 }
358 }
359
360
361 protected AbstractPreferences childSpi( String name )
362 {
363 return new ServerSystemPreferences( this, name );
364 }
365 }