1 20 21 package org.apache.directory.ldapstudio.browser.core.internal.model; 22 23 24 import java.util.ArrayList ; 25 import java.util.Arrays ; 26 import java.util.HashMap ; 27 import java.util.Iterator ; 28 import java.util.LinkedHashSet ; 29 import java.util.List ; 30 import java.util.Map ; 31 32 import org.apache.directory.ldapstudio.browser.core.BrowserCoreMessages; 33 import org.apache.directory.ldapstudio.browser.core.events.AttributeAddedEvent; 34 import org.apache.directory.ldapstudio.browser.core.events.AttributeDeletedEvent; 35 import org.apache.directory.ldapstudio.browser.core.events.AttributesInitializedEvent; 36 import org.apache.directory.ldapstudio.browser.core.events.ChildrenInitializedEvent; 37 import org.apache.directory.ldapstudio.browser.core.events.EntryAddedEvent; 38 import org.apache.directory.ldapstudio.browser.core.events.EntryDeletedEvent; 39 import org.apache.directory.ldapstudio.browser.core.events.EntryModificationEvent; 40 import org.apache.directory.ldapstudio.browser.core.events.EventRegistry; 41 import org.apache.directory.ldapstudio.browser.core.internal.search.LdapSearchPageScoreComputer; 42 import org.apache.directory.ldapstudio.browser.core.model.AttributeHierarchy; 43 import org.apache.directory.ldapstudio.browser.core.model.IAttribute; 44 import org.apache.directory.ldapstudio.browser.core.model.IConnection; 45 import org.apache.directory.ldapstudio.browser.core.model.IEntry; 46 import org.apache.directory.ldapstudio.browser.core.model.ModelModificationException; 47 import org.apache.directory.ldapstudio.browser.core.model.RDN; 48 import org.apache.directory.ldapstudio.browser.core.model.URL; 49 import org.apache.directory.ldapstudio.browser.core.model.schema.AttributeTypeDescription; 50 import org.apache.directory.ldapstudio.browser.core.model.schema.ObjectClassDescription; 51 import org.apache.directory.ldapstudio.browser.core.model.schema.Subschema; 52 import org.eclipse.search.ui.ISearchPageScoreComputer; 53 54 55 public abstract class AbstractEntry implements IEntry 56 { 57 58 public static final int HAS_CHILDREN_HINT_FLAG = 1; 59 60 public static final int IS_DIRECTORY_ENTRY_FLAG = 2; 61 62 public static final int IS_ALIAS_FLAG = 4; 63 64 public static final int IS_REFERRAL_FLAG = 8; 65 66 public static final int IS_SUBENTRY_FLAG = 16; 67 68 private volatile int flags; 69 70 71 protected AbstractEntry() 72 { 73 this.flags = HAS_CHILDREN_HINT_FLAG; 74 } 75 76 77 protected abstract void setParent( IEntry newParent ); 78 79 80 protected abstract void setRdn( RDN newRdn ); 81 82 83 public void addChild( IEntry childToAdd ) 84 { 85 86 ChildrenInfo ci = this.getJNDIConnection().getChildrenInfo( this ); 87 if ( ci == null ) 88 { 89 ci = new ChildrenInfo(); 90 this.getJNDIConnection().setChildrenInfo( this, ci ); 91 } 92 93 if ( ci.childrenSet == null ) 94 { 95 ci.childrenSet = new LinkedHashSet (); 96 } 97 ci.childrenSet.add( childToAdd ); 98 this.entryModified( new EntryAddedEvent( childToAdd.getConnection(), childToAdd ) ); 99 } 100 101 102 public void deleteChild( IEntry childToDelete ) 103 { 104 105 ChildrenInfo ci = this.getJNDIConnection().getChildrenInfo( this ); 106 107 if ( ci != null ) 108 { 109 ci.childrenSet.remove( childToDelete ); 110 if ( ci.childrenSet == null || ci.childrenSet.isEmpty() ) 111 { 112 this.getJNDIConnection().setChildrenInfo( this, null ); 113 } 114 this.entryModified( new EntryDeletedEvent( this.getJNDIConnection(), childToDelete ) ); 115 } 116 } 117 118 119 public void addAttribute( IAttribute attributeToAdd ) throws ModelModificationException 120 { 121 122 String oidString = attributeToAdd.getAttributeDescription().toOidString( getConnection().getSchema() ); 123 124 AttributeInfo ai = this.getJNDIConnection().getAttributeInfo( this ); 125 if ( ai == null ) 126 { 127 ai = new AttributeInfo(); 128 this.getJNDIConnection().setAttributeInfo( this, ai ); 129 } 130 131 if ( !this.equals( attributeToAdd.getEntry() ) ) 132 { 133 throw new ModelModificationException( BrowserCoreMessages.model__attributes_entry_is_not_myself ); 134 } 135 else if ( ai.attributeMap.containsKey( oidString.toLowerCase() ) ) 139 { 140 throw new ModelModificationException( BrowserCoreMessages.model__attribute_already_exists ); 141 } 142 else 143 { 144 ai.attributeMap.put( oidString.toLowerCase(), attributeToAdd ); 147 this.entryModified( new AttributeAddedEvent( this.getJNDIConnection(), this, attributeToAdd ) ); 148 } 149 } 150 151 152 public void deleteAttribute( IAttribute attributeToDelete ) throws ModelModificationException 153 { 154 155 String oidString = attributeToDelete.getAttributeDescription().toOidString( getConnection().getSchema() ); 156 157 AttributeInfo ai = this.getJNDIConnection().getAttributeInfo( this ); 158 159 if ( ai != null && ai.attributeMap != null && ai.attributeMap.containsKey( oidString.toLowerCase() ) ) 166 { 167 IAttribute attribute = ( IAttribute ) ai.attributeMap.get( oidString.toLowerCase() ); 168 ai.attributeMap.remove( oidString.toLowerCase() ); 169 if ( ai.attributeMap.isEmpty() ) 170 { 171 this.getJNDIConnection().setAttributeInfo( this, null ); 172 } 173 this.entryModified( new AttributeDeletedEvent( this.getJNDIConnection(), this, attribute ) ); 174 } 175 else 176 { 177 throw new ModelModificationException( BrowserCoreMessages.model__attribute_does_not_exist ); 178 } 179 } 180 181 182 public boolean isConsistent() 183 { 184 185 188 AttributeInfo ai = this.getJNDIConnection().getAttributeInfo( this ); 189 190 if ( ai == null || ai.attributeMap == null ) 191 { 192 return isDirectoryEntry(); 193 } 194 195 Iterator attributeIterator = ai.attributeMap.values().iterator(); 197 while ( attributeIterator.hasNext() ) 198 { 199 IAttribute attribute = ( IAttribute ) attributeIterator.next(); 200 if ( !attribute.isConsistent() ) 201 return false; 202 } 203 204 if ( !this.isDirectoryEntry() ) 205 { 206 if ( !ai.attributeMap.containsKey( IAttribute.OBJECTCLASS_ATTRIBUTE_OID.toLowerCase() ) ) 208 { 209 return false; 210 } 211 IAttribute ocAttribute = ( IAttribute ) ai.attributeMap.get( IAttribute.OBJECTCLASS_ATTRIBUTE_OID 212 .toLowerCase() ); 213 String [] ocValues = ocAttribute.getStringValues(); 214 boolean structuralObjectClassAvailable = false; 215 for ( int i = 0; i < ocValues.length; i++ ) 216 { 217 ObjectClassDescription ocd = this.getConnection().getSchema().getObjectClassDescription( ocValues[i] ); 218 if ( ocd.isStructural() ) 219 { 220 structuralObjectClassAvailable = true; 221 break; 222 } 223 } 224 if ( !structuralObjectClassAvailable ) 225 { 226 return false; 227 } 228 229 AttributeTypeDescription[] mustAtds = this.getSubschema().getMustAttributeTypeDescriptions(); 237 for ( int i = 0; i < mustAtds.length; i++ ) 238 { 239 AttributeTypeDescription mustAtd = mustAtds[i]; 240 if ( !ai.attributeMap.containsKey( mustAtd.getNumericOID().toLowerCase() ) ) 241 return false; 242 } 243 } 244 245 return true; 246 } 247 248 249 public boolean isDirectoryEntry() 250 { 251 return ( this.flags & IS_DIRECTORY_ENTRY_FLAG ) != 0; 252 } 253 254 255 public void setDirectoryEntry( boolean isDirectoryEntry ) 256 { 257 if ( isDirectoryEntry ) 258 this.flags = this.flags | IS_DIRECTORY_ENTRY_FLAG; 259 else 260 this.flags = this.flags & ~IS_DIRECTORY_ENTRY_FLAG; 261 } 262 263 264 public boolean isAlias() 265 { 266 if ( ( this.flags & IS_ALIAS_FLAG ) != 0 ) 267 { 268 return true; 269 } 270 271 AttributeInfo ai = this.getJNDIConnection().getAttributeInfo( this ); 272 if ( ai != null ) 273 { 274 return Arrays.asList( this.getSubschema().getObjectClassNames() ) 275 .contains( ObjectClassDescription.OC_ALIAS ); 276 } 277 278 return false; 279 } 280 281 282 public void setAlias( boolean b ) 283 { 284 if ( b ) 285 this.flags = this.flags | IS_ALIAS_FLAG; 286 else 287 this.flags = this.flags & ~IS_ALIAS_FLAG; 288 } 289 290 291 public boolean isReferral() 292 { 293 if ( ( this.flags & IS_REFERRAL_FLAG ) != 0 ) 294 { 295 return true; 296 } 297 298 AttributeInfo ai = this.getJNDIConnection().getAttributeInfo( this ); 299 if ( ai != null ) 300 { 301 return Arrays.asList( this.getSubschema().getObjectClassNames() ).contains( 302 ObjectClassDescription.OC_REFERRAL ); 303 } 304 305 return false; 306 } 307 308 309 public void setReferral( boolean b ) 310 { 311 if ( b ) 312 this.flags = this.flags | IS_REFERRAL_FLAG; 313 else 314 this.flags = this.flags & ~IS_REFERRAL_FLAG; 315 } 316 317 318 public boolean isSubentry() 319 { 320 if ( ( this.flags & IS_SUBENTRY_FLAG ) != 0 ) 321 { 322 return true; 323 } 324 325 AttributeInfo ai = this.getJNDIConnection().getAttributeInfo( this ); 326 if ( ai != null ) 327 { 328 return Arrays.asList( this.getSubschema().getObjectClassNames() ).contains( 329 ObjectClassDescription.OC_SUBENTRY ); 330 } 331 332 return false; 333 } 334 335 336 public void setSubentry( boolean b ) 337 { 338 if ( b ) 339 this.flags = this.flags | IS_SUBENTRY_FLAG; 340 else 341 this.flags = this.flags & ~IS_SUBENTRY_FLAG; 342 } 343 344 345 350 private void entryModified( EntryModificationEvent event ) 351 { 352 EventRegistry.fireEntryUpdated( event, this ); 353 } 354 355 356 public RDN getRdn() 357 { 358 return this.getDn().getRdn(); 359 } 360 361 362 public boolean isAttributesInitialized() 363 { 364 AttributeInfo ai = this.getJNDIConnection().getAttributeInfo( this ); 365 return ai != null && ai.attributesInitialzed; 366 } 367 368 369 public void setAttributesInitialized( boolean b ) 370 { 371 372 AttributeInfo ai = this.getJNDIConnection().getAttributeInfo( this ); 373 if ( ai == null && b ) 374 { 375 ai = new AttributeInfo(); 376 this.getJNDIConnection().setAttributeInfo( this, ai ); 377 } 378 379 if ( ai != null ) 380 { 381 ai.attributesInitialzed = b; 382 } 383 384 if ( ai != null && !b ) 385 { 386 ai.attributeMap.clear(); 387 this.getJNDIConnection().setAttributeInfo( this, null ); 388 } 389 390 this.entryModified( new AttributesInitializedEvent( this ) ); 391 } 392 393 394 public IAttribute[] getAttributes() 395 { 396 AttributeInfo ai = this.getJNDIConnection().getAttributeInfo( this ); 397 if ( ai == null || ai.attributeMap == null ) 398 { 399 return null; 400 } 401 else 402 { 403 return ( IAttribute[] ) ai.attributeMap.values().toArray( new IAttribute[0] ); 404 } 405 } 406 407 408 public IAttribute getAttribute( String attributeDescription ) 409 { 410 AttributeInfo ai = this.getJNDIConnection().getAttributeInfo( this ); 411 if ( ai == null || ai.attributeMap == null ) 412 { 413 return null; 414 } 415 else 416 { 417 AttributeDescription ad = new AttributeDescription( attributeDescription ); 418 String oidString = ad.toOidString( getConnection().getSchema() ); 419 return ( IAttribute ) ai.attributeMap.get( oidString.toLowerCase() ); 420 } 421 } 422 423 424 public AttributeHierarchy getAttributeWithSubtypes( String attributeDescription ) 425 { 426 427 AttributeInfo ai = this.getJNDIConnection().getAttributeInfo( this ); 428 if ( ai == null || ai.attributeMap == null ) 429 { 430 return null; 431 } 432 else 433 { 434 List attributeList = new ArrayList (); 435 436 IAttribute myAttribute = getAttribute( attributeDescription ); 437 if ( myAttribute != null ) 438 { 439 attributeList.add( myAttribute ); 440 } 441 442 AttributeDescription ad = new AttributeDescription( attributeDescription ); 443 Map clonedAttributeMap = new HashMap ( ai.attributeMap ); 444 Iterator iterator = clonedAttributeMap.values().iterator(); 445 while ( iterator.hasNext() ) 446 { 447 IAttribute attribute = ( IAttribute ) iterator.next(); 448 449 AttributeDescription other = attribute.getAttributeDescription(); 450 if ( other.isSubtypeOf( ad, getConnection().getSchema() ) ) 451 { 452 attributeList.add( attribute ); 453 } 454 } 455 456 if ( attributeList.isEmpty() ) 457 { 458 return null; 459 } 460 else 461 { 462 IAttribute[] attributes = ( IAttribute[] ) attributeList.toArray( new IAttribute[attributeList.size()] ); 463 AttributeHierarchy ah = new AttributeHierarchy( this, attributeDescription, attributes ); 464 return ah; 465 } 466 } 467 } 468 469 470 public Subschema getSubschema() 471 { 472 AttributeInfo ai = this.getJNDIConnection().getAttributeInfo( this ); 473 if ( ai == null ) 474 { 475 ai = new AttributeInfo(); 476 this.getJNDIConnection().setAttributeInfo( this, ai ); 477 } 478 if ( ai.subschema == null ) 479 { 480 ai.subschema = new Subschema( this ); 481 } 482 483 return ai.subschema; 484 } 485 486 487 public void setChildrenInitialized( boolean b ) 488 { 489 ChildrenInfo ci = this.getJNDIConnection().getChildrenInfo( this ); 490 if ( ci == null && b ) 491 { 492 ci = new ChildrenInfo(); 493 this.getJNDIConnection().setChildrenInfo( this, ci ); 494 } 495 496 if ( ci != null ) 497 { 498 ci.childrenInitialzed = b; 499 } 500 501 if ( ci != null && !b ) 502 { 503 if ( ci.childrenSet != null ) 504 { 505 ci.childrenSet.clear(); 506 } 507 this.getJNDIConnection().setChildrenInfo( this, null ); 508 } 509 510 this.entryModified( new ChildrenInitializedEvent( this ) ); 511 } 512 513 514 public boolean isChildrenInitialized() 515 { 516 ChildrenInfo ci = this.getJNDIConnection().getChildrenInfo( this ); 517 return ci != null && ci.childrenInitialzed; 518 } 519 520 521 public IEntry[] getChildren() 522 { 523 int count = getChildrenCount(); 524 if ( count < 0 ) 525 { 526 return null; 527 } 528 else if ( count == 0 ) 529 { 530 return new IEntry[0]; 531 } 532 else 533 { 534 IEntry[] children = new IEntry[count]; 535 ChildrenInfo ci = this.getJNDIConnection().getChildrenInfo( this ); 536 int i = 0; 537 if ( ci.childrenSet != null ) 538 { 539 Iterator it = ci.childrenSet.iterator(); 540 for ( ; it.hasNext(); i++ ) 541 { 542 children[i] = ( IEntry ) it.next(); 543 } 544 } 545 return children; 546 } 547 } 548 549 550 public int getChildrenCount() 551 { 552 if ( isSubentry() ) 553 { 554 return 0; 555 } 556 ChildrenInfo ci = this.getJNDIConnection().getChildrenInfo( this ); 557 if ( ci == null ) 558 { 559 return -1; 560 } 561 else 562 { 563 return ci.childrenSet == null ? 0 : ci.childrenSet.size(); 564 } 565 } 566 567 568 public void setHasMoreChildren( boolean b ) 569 { 570 ChildrenInfo ci = this.getJNDIConnection().getChildrenInfo( this ); 571 if ( ci == null ) 572 { 573 ci = new ChildrenInfo(); 574 this.getJNDIConnection().setChildrenInfo( this, ci ); 575 } 576 ci.hasMoreChildren = b; 577 578 this.entryModified( new ChildrenInitializedEvent( this ) ); 579 } 580 581 582 public boolean hasMoreChildren() 583 { 584 ChildrenInfo ci = this.getJNDIConnection().getChildrenInfo( this ); 585 return ci != null && ci.hasMoreChildren; 586 } 587 588 589 public void setHasChildrenHint( boolean b ) 590 { 591 if ( b ) 592 this.flags = this.flags | HAS_CHILDREN_HINT_FLAG; 593 else 594 this.flags = this.flags & ~HAS_CHILDREN_HINT_FLAG; 595 } 596 597 598 public boolean hasChildren() 599 { 600 return ( this.flags & HAS_CHILDREN_HINT_FLAG ) != 0 || this.getChildrenCount() > 0; 601 } 602 603 604 public String getChildrenFilter() 605 { 606 return this.getJNDIConnection().getChildrenFilter( this ); 607 } 608 609 610 public void setChildrenFilter( String childrenFilter ) 611 { 612 this.getJNDIConnection().setChildrenFilter( this, childrenFilter ); 613 } 614 615 616 public boolean hasParententry() 617 { 618 return this.getParententry() != null; 619 } 620 621 622 private Connection getJNDIConnection() 623 { 624 return ( Connection ) this.getConnection(); 625 } 626 627 628 public String toString() 629 { 630 return this.getDn().toString(); 631 } 632 633 634 public boolean equals( Object o ) 635 { 636 637 if ( o == null || !( o instanceof IEntry ) ) 639 { 640 return false; 641 } 642 IEntry e = ( IEntry ) o; 643 644 return this.getDn() == null ? e.getDn() == null : ( this.getDn().equals( e.getDn() ) && this.getConnection() 646 .equals( e.getConnection() ) ); 647 } 648 649 650 public Object getAdapter( Class adapter ) 651 { 652 653 if ( adapter.isAssignableFrom( ISearchPageScoreComputer.class ) ) 654 { 655 return new LdapSearchPageScoreComputer(); 656 } 657 if ( adapter == IConnection.class ) 658 { 659 return this.getConnection(); 660 } 661 if ( adapter == IEntry.class ) 662 { 663 return this; 664 } 665 return null; 666 } 667 668 669 public IEntry getEntry() 670 { 671 return this; 672 } 673 674 675 public URL getUrl() 676 { 677 return new URL( getConnection(), getDn() ); 678 } 679 680 } 681 | Popular Tags |