1 17 package org.apache.ldap.server.prefs; 18 19 20 import org.apache.ldap.common.Lockable; 21 import org.apache.ldap.common.message.LockableAttributeImpl; 22 import org.apache.ldap.common.message.LockableAttributesImpl; 23 import org.apache.ldap.common.util.PreferencesDictionary; 24 import org.apache.ldap.server.jndi.CoreContextFactory; 25 26 import javax.naming.Context ; 27 import javax.naming.NameClassPair ; 28 import javax.naming.NamingEnumeration ; 29 import javax.naming.NamingException ; 30 import javax.naming.directory.*; 31 import javax.naming.ldap.InitialLdapContext ; 32 import javax.naming.ldap.LdapContext ; 33 import java.util.*; 34 import java.util.prefs.AbstractPreferences ; 35 import java.util.prefs.BackingStoreException ; 36 37 38 46 public class ServerSystemPreferences extends AbstractPreferences 47 { 48 49 private static final ModificationItem[] EMPTY_MODS = new ModificationItem[0]; 50 51 52 private static final String [] EMPTY_STRINGS = new String [0]; 53 54 55 private LdapContext ctx; 56 57 58 private ArrayList changes = new ArrayList(3); 59 60 61 private HashMap keyToChange = new HashMap(3); 62 63 64 67 public ServerSystemPreferences() 68 { 69 super( null, "" ); 70 71 super.newNode = false; 72 73 Hashtable env = new Hashtable(); 74 75 env.put( Context.INITIAL_CONTEXT_FACTORY, CoreContextFactory.class.getName() ); 76 77 env.put( Context.PROVIDER_URL, PreferencesUtils.SYSPREF_BASE ); 78 79 try 80 { 81 ctx = new InitialLdapContext ( env, null ); 82 } 83 catch ( NamingException e ) 84 { 85 e.printStackTrace(); 86 } 87 } 88 89 90 93 public ServerSystemPreferences( ServerSystemPreferences parent, String name ) 94 { 95 super( parent, name ); 96 97 LdapContext parentCtx = parent.getLdapContext(); 98 99 try 100 { 101 ctx = ( LdapContext ) parentCtx.lookup( "prefNodeName=" + name ); 102 103 super.newNode = false; 104 } 105 catch ( NamingException e ) 106 { 107 super.newNode = true; 108 } 109 110 if ( super.newNode ) 111 { 112 try 113 { 114 setUpNode( name ); 115 } 116 catch ( NamingException e ) 117 { 118 e.printStackTrace(); 119 } 120 } 121 } 122 123 124 128 129 134 public Dictionary wrapAsDictionary() 135 { 136 return new PreferencesDictionary( this ); 137 } 138 139 140 145 LdapContext getLdapContext() 146 { 147 return ctx; 148 } 149 150 151 157 private void setUpNode( String name ) throws NamingException 158 { 159 Attributes attrs = new LockableAttributesImpl(); 160 161 Attribute attr = new LockableAttributeImpl( ( Lockable ) attrs, "objectClass" ); 162 163 attr.add( "top" ); 164 165 attr.add( "prefNode" ); 166 167 attr.add( "extensibleObject" ); 168 169 attrs.put( attr ); 170 171 attr = new LockableAttributeImpl( ( Lockable ) attrs, "prefNodeName" ); 172 173 attr.add( name ); 174 175 attrs.put( attr ); 176 177 LdapContext parent = ( ( ServerSystemPreferences ) parent() ).getLdapContext(); 178 179 parent.bind( "prefNodeName=" + name, null, attrs ); 180 181 ctx = ( LdapContext ) parent.lookup( "prefNodeName=" + name ); 182 183 super.newNode = false; 184 } 185 186 187 191 192 protected void flushSpi() throws BackingStoreException 193 { 194 if ( ctx == null ) 195 { 196 throw new BackingStoreException ( "Ldap context not available for " + super.absolutePath() ); 197 } 198 199 200 if ( changes.isEmpty() ) 201 { 202 return; 203 } 204 205 try 206 { 207 ctx.modifyAttributes( "", ( ModificationItem[] ) changes.toArray( EMPTY_MODS ) ); 208 } 209 catch ( NamingException e ) 210 { 211 throw new BackingStoreException ( e ); 212 } 213 214 changes.clear(); 215 216 keyToChange.clear(); 217 } 218 219 220 protected void removeNodeSpi() throws BackingStoreException 221 { 222 try 223 { 224 ctx.destroySubcontext( "" ); 225 } 226 catch ( NamingException e ) 227 { 228 throw new BackingStoreException ( e ); 229 } 230 231 ctx = null; 232 233 changes.clear(); 234 235 keyToChange.clear(); 236 } 237 238 239 protected void syncSpi() throws BackingStoreException 240 { 241 if ( ctx == null ) 242 { 243 throw new BackingStoreException ( "Ldap context not available for " + super.absolutePath() ); 244 } 245 246 247 if ( changes.isEmpty() ) 248 { 249 return; 250 } 251 252 try 253 { 254 ctx.modifyAttributes( "", ( ModificationItem[] ) changes.toArray( EMPTY_MODS ) ); 255 } 256 catch ( NamingException e ) 257 { 258 throw new BackingStoreException ( e ); 259 } 260 261 changes.clear(); 262 263 keyToChange.clear(); 264 } 265 266 267 protected String [] childrenNamesSpi() throws BackingStoreException 268 { 269 ArrayList children = new ArrayList(); 270 271 NamingEnumeration list = null; 272 273 try 274 { 275 list = ctx.list( "" ); 276 277 while ( list.hasMore() ) 278 { 279 NameClassPair ncp = ( NameClassPair ) list.next(); 280 281 children.add( ncp.getName() ); 282 } 283 } 284 catch ( NamingException e ) 285 { 286 throw new BackingStoreException ( e ); 287 } 288 289 return ( String [] ) children.toArray( EMPTY_STRINGS ); 290 } 291 292 293 protected String [] keysSpi() throws BackingStoreException 294 { 295 Attributes attrs = null; 296 297 ArrayList keys = new ArrayList(); 298 299 try 300 { 301 attrs = ctx.getAttributes( "" ); 302 303 NamingEnumeration ids = attrs.getIDs(); 304 305 while ( ids.hasMore() ) 306 { 307 String id = ( String ) ids.next(); 308 309 if ( id.equals( "objectClass" ) || id.equals( "prefNodeName" ) ) 310 { 311 continue; 312 } 313 314 keys.add( id ); 315 } 316 } 317 catch ( NamingException e ) 318 { 319 throw new BackingStoreException ( e ); 320 } 321 322 return ( String [] ) keys.toArray( EMPTY_STRINGS ); 323 } 324 325 326 protected void removeSpi( String key ) 327 { 328 Attribute attr = new BasicAttribute( key ); 329 330 ModificationItem mi = new ModificationItem( DirContext.REMOVE_ATTRIBUTE, attr ); 331 332 addDelta( mi ); 333 } 334 335 336 private void addDelta( ModificationItem mi ) 337 { 338 String key = mi.getAttribute().getID(); 339 340 List deltas = null; 341 342 changes.add( mi ); 343 344 if ( keyToChange.containsKey( key ) ) 345 { 346 deltas = ( List ) keyToChange.get( key ); 347 } 348 else 349 { 350 deltas = new ArrayList(); 351 } 352 353 deltas.add( mi ); 354 355 keyToChange.put( key, deltas ); 356 } 357 358 359 protected String getSpi( String key ) 360 { 361 String value = null; 362 363 try 364 { 365 Attribute attr = ctx.getAttributes( "" ).get( key ); 366 367 if ( keyToChange.containsKey( key ) ) 368 { 369 List mods = ( List ) keyToChange.get( key ); 370 371 for ( int ii = 0; ii < mods.size(); ii++ ) 372 { 373 ModificationItem mi = ( ModificationItem ) mods.get( ii ); 374 375 if ( mi.getModificationOp() == DirContext.REMOVE_ATTRIBUTE ) 376 { 377 attr = null; 378 } 379 else 380 { 381 attr = mi.getAttribute(); 382 } 383 } 384 } 385 386 if ( attr == null ) 387 { 388 return null; 389 } 390 391 value = ( String ) attr.get(); 392 } 393 catch ( NamingException e ) 394 { 395 e.printStackTrace(); 396 } 397 398 return value; 399 } 400 401 402 protected void putSpi( String key, String value ) 403 { 404 Attribute attr = new BasicAttribute( key ); 405 406 attr.add( value ); 407 408 ModificationItem mi = new ModificationItem( DirContext.REPLACE_ATTRIBUTE, attr ); 409 410 addDelta( mi ); 411 } 412 413 414 protected AbstractPreferences childSpi( String name ) 415 { 416 return new ServerSystemPreferences( this, name ); 417 } 418 } 419 | Popular Tags |