001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * https://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 * 019 */ 020package org.apache.directory.api.ldap.model.schema; 021 022import org.apache.directory.api.i18n.I18n; 023 024/** 025 * An attributeType specification. attributeType specifications describe the 026 * nature of attributes within the directory. The attributeType specification's 027 * properties are accessible through this interface. 028 * <p> 029 * According to ldapbis [MODELS]: 030 * </p> 031 * 032 * <pre> 033 * 4.1.2. Attribute Types 034 * 035 * Attribute Type definitions are written according to the ABNF: 036 * 037 * AttributeTypeDescription = LPAREN WSP 038 * numericoid ; object identifier 039 * [ SP "NAME" SP qdescrs ] ; short names (descriptors) 040 * [ SP "DESC" SP qdstring ] ; description 041 * [ SP "OBSOLETE" ] ; not active 042 * [ SP "SUP" SP oid ] ; supertype 043 * [ SP "EQUALITY" SP oid ] ; equality matching rule 044 * [ SP "ORDERING" SP oid ] ; ordering matching rule 045 * [ SP "SUBSTR" SP oid ] ; substrings matching rule 046 * [ SP "SYNTAX" SP noidlen ] ; value syntax 047 * [ SP "SINGLE-VALUE" ] ; single-value 048 * [ SP "COLLECTIVE" ] ; collective 049 * [ SP "NO-USER-MODIFICATION" ]; not user modifiable 050 * [ SP "USAGE" SP usage ] ; usage 051 * extensions WSP RPAREN ; extensions 052 * 053 * usage = "userApplications" / ; user 054 * "directoryOperation" / ; directory operational 055 * "distributedOperation" / ; DSA-shared operational 056 * "dSAOperation" ; DSA-specific operational 057 * 058 * where: 059 * [numericoid] is object identifier assigned to this attribute type; 060 * NAME [qdescrs] are short names (descriptors) identifying this 061 * attribute type; 062 * DESC [qdstring] is a short descriptive string; 063 * OBSOLETE indicates this attribute type is not active; 064 * SUP oid specifies the direct supertype of this type; 065 * EQUALITY, ORDERING, SUBSTRING provide the oid of the equality, 066 * ordering, and substrings matching rules, respectively; 067 * SYNTAX identifies value syntax by object identifier and may suggest 068 * a minimum upper bound; 069 * COLLECTIVE indicates this attribute type is collective [X.501]; 070 * NO-USER-MODIFICATION indicates this attribute type is not user 071 * modifiable; 072 * USAGE indicates the application of this attribute type; and 073 * [extensions] describe extensions. 074 * 075 * Each attribute type description must contain at least one of the SUP 076 * or SYNTAX fields. 077 * 078 * Usage of userApplications, the default, indicates that attributes of 079 * this type represent user information. That is, they are user 080 * attributes. 081 * 082 * COLLECTIVE requires usage userApplications. Use of collective 083 * attribute types in LDAP is not discussed in this technical 084 * specification. 085 * 086 * A usage of directoryOperation, distributedOperation, or dSAOperation 087 * indicates that attributes of this type represent operational and/or 088 * administrative information. That is, they are operational attributes. 089 * 090 * directoryOperation usage indicates that the attribute of this type is 091 * a directory operational attribute. distributedOperation usage 092 * indicates that the attribute of this DSA-shared usage operational 093 * attribute. dSAOperation usage indicates that the attribute of this 094 * type is a DSA-specific operational attribute. 095 * 096 * NO-USER-MODIFICATION requires an operational usage. 097 * 098 * Note that the [AttributeTypeDescription] does not list the matching 099 * rules which can be used with that attribute type in an extensibleMatch 100 * search filter. This is done using the 'matchingRuleUse' attribute 101 * described in Section 4.1.4. 102 * 103 * This document refines the schema description of X.501 by requiring 104 * that the SYNTAX field in an [AttributeTypeDescription] be a string 105 * representation of an object identifier for the LDAP string syntax 106 * definition with an optional indication of the suggested minimum bound 107 * of a value of this attribute. 108 * 109 * A suggested minimum upper bound on the number of characters in a value 110 * with a string-based syntax, or the number of bytes in a value for all 111 * other syntaxes, may be indicated by appending this bound count inside 112 * of curly braces following the syntax's OBJECT IDENTIFIER in an 113 * 114 * Attribute Type Description. This bound is not part of the syntax name 115 * itself. For instance, "1.3.6.4.1.1466.0{64}" suggests that server 116 * implementations should allow a string to be 64 characters long, 117 * although they may allow longer strings. Note that a single character 118 * of the Directory String syntax may be encoded in more than one octet 119 * since UTF-8 is a variable-length encoding. 120 * </pre> 121 * 122 * @see <a href="http://www.faqs.org/rfcs/rfc2252.html">RFC 2252 Section 4.2</a> 123 * @see <a 124 * href="http://www.ietf.org/internet-drafts/draft-ietf-ldapbis-models-11.txt"> 125 * ldapbis [MODELS]</a> 126 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 127 */ 128public class AttributeType extends AbstractSchemaObject implements Cloneable 129{ 130 /** The mandatory serialVersionUID */ 131 public static final long serialVersionUID = 1L; 132 133 /** The syntax OID associated with this AttributeType */ 134 protected String syntaxOid; 135 136 /** The syntax associated with the syntaxID */ 137 protected LdapSyntax syntax; 138 139 /** The equality OID associated with this AttributeType */ 140 protected String equalityOid; 141 142 /** The equality MatchingRule associated with the equalityID */ 143 protected MatchingRule equality; 144 145 /** The substring OID associated with this AttributeType */ 146 protected String substringOid; 147 148 /** The substring MatchingRule associated with the substringID */ 149 protected MatchingRule substring; 150 151 /** The ordering OID associated with this AttributeType */ 152 protected String orderingOid; 153 154 /** The ordering MatchingRule associated with the orderingID */ 155 protected MatchingRule ordering; 156 157 /** The superior AttributeType OID */ 158 protected String superiorOid; 159 160 /** The superior AttributeType */ 161 protected AttributeType superior; 162 163 /** whether or not this type is single valued */ 164 protected boolean isSingleValued = false; 165 166 /** whether or not this type is a collective attribute */ 167 protected boolean isCollective = false; 168 169 /** whether or not this type can be modified by directory users */ 170 protected boolean canUserModify = true; 171 172 /** the usage for this attributeType */ 173 protected UsageEnum usage = UsageEnum.USER_APPLICATIONS; 174 175 /** the length of this attribute in bytes */ 176 protected long syntaxLength = 0L; 177 178 /** A flag set when the SchemaManager is in relaxed mode */ 179 private boolean isRelaxed = false; 180 181 182 /** 183 * Creates a AttributeType object using a unique OID. 184 * 185 * @param oid the OID for this AttributeType 186 */ 187 public AttributeType( String oid ) 188 { 189 super( SchemaObjectType.ATTRIBUTE_TYPE, oid ); 190 } 191 192 193 /** 194 * Gets whether or not this AttributeType is single-valued. 195 * 196 * @return true if only one value can exist for this AttributeType, false 197 * otherwise 198 */ 199 public boolean isSingleValued() 200 { 201 return isSingleValued; 202 } 203 204 205 /** 206 * Tells if this AttributeType is Single Valued or not 207 * 208 * @param singleValued True if the AttributeType is single-valued 209 */ 210 public void setSingleValued( boolean singleValued ) 211 { 212 if ( locked ) 213 { 214 throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) ); 215 } 216 217 this.isSingleValued = singleValued; 218 } 219 220 221 /** 222 * Gets whether or not this AttributeType can be modified by a user. 223 * 224 * @return true if users can modify it, false if only the directory can. 225 */ 226 public boolean isUserModifiable() 227 { 228 return canUserModify; 229 } 230 231 232 /** 233 * Tells if this AttributeType can be modified by a user or not 234 * 235 * @param userModifiable The flag to set 236 */ 237 public void setUserModifiable( boolean userModifiable ) 238 { 239 if ( locked ) 240 { 241 throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) ); 242 } 243 244 this.canUserModify = userModifiable; 245 } 246 247 248 /** 249 * Gets whether or not this AttributeType is a collective attribute. 250 * 251 * @return true if the attribute is collective, false otherwise 252 */ 253 public boolean isCollective() 254 { 255 return isCollective; 256 } 257 258 259 /** 260 * Sets the collective flag 261 * 262 * @param collective The new value to set 263 */ 264 public void setCollective( boolean collective ) 265 { 266 if ( locked ) 267 { 268 throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) ); 269 } 270 271 this.isCollective = collective; 272 } 273 274 275 /** 276 * @return Tells if the AttributeType is relaxed (the SyntaxChecker will not be activated) 277 */ 278 public boolean isRelaxed() 279 { 280 return isRelaxed; 281 } 282 283 284 /** 285 * Set this AttributeType mode to relaxed 286 * 287 * @param isRelaxed <tt>true</tt> if the syntax checker for this AttributeType should not be activated 288 */ 289 public void setRelaxed( boolean isRelaxed ) 290 { 291 this.isRelaxed = isRelaxed; 292 } 293 294 295 /** 296 * Determines the usage for this AttributeType. 297 * 298 * @return a type safe UsageEnum 299 */ 300 public UsageEnum getUsage() 301 { 302 return usage; 303 } 304 305 306 /** 307 * Sets the AttributeType usage, one of : 308 * <ul> 309 * <li>USER_APPLICATIONS</li> 310 * <li>DIRECTORY_OPERATION</li> 311 * <li>DISTRIBUTED_OPERATION</li> 312 * <li>DSA_OPERATION</li> 313 * </ul> 314 * 315 * @see UsageEnum 316 * @param usage The AttributeType usage 317 */ 318 public void setUsage( UsageEnum usage ) 319 { 320 if ( locked ) 321 { 322 throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) ); 323 } 324 325 this.usage = usage; 326 } 327 328 329 /** 330 * Gets a length limit for this AttributeType. 331 * 332 * @return the length of the attribute 333 */ 334 public long getSyntaxLength() 335 { 336 return syntaxLength; 337 } 338 339 340 /** 341 * Sets the length limit of this AttributeType based on its associated 342 * syntax. 343 * 344 * @param length the new length to set 345 */ 346 public void setSyntaxLength( long length ) 347 { 348 if ( locked ) 349 { 350 throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) ); 351 } 352 353 this.syntaxLength = length; 354 } 355 356 357 /** 358 * Gets the the superior AttributeType of this AttributeType. 359 * 360 * @return the superior AttributeType for this AttributeType 361 */ 362 public AttributeType getSuperior() 363 { 364 return superior; 365 } 366 367 368 /** 369 * Gets the OID of the superior AttributeType for this AttributeType. 370 * 371 * @return The OID of the superior AttributeType for this AttributeType. 372 */ 373 public String getSuperiorOid() 374 { 375 return superiorOid; 376 } 377 378 379 /** 380 * Sets the superior for this AttributeType 381 * 382 * @param superior The superior for this AttributeType 383 */ 384 public void setSuperior( AttributeType superior ) 385 { 386 if ( locked ) 387 { 388 throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) ); 389 } 390 391 this.superior = superior; 392 this.superiorOid = superior.getOid(); 393 } 394 395 396 /** 397 * Sets the superior oid for this AttributeType 398 * 399 * @param newSuperiorOid The superior oid for this AttributeType 400 */ 401 public void setSuperior( String newSuperiorOid ) 402 { 403 if ( locked ) 404 { 405 throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) ); 406 } 407 408 this.superiorOid = newSuperiorOid; 409 } 410 411 412 /** 413 * Sets the superior AttributeType OID of this AttributeType 414 * 415 * @param superiorOid The superior AttributeType OID of this AttributeType 416 */ 417 public void setSuperiorOid( String superiorOid ) 418 { 419 if ( locked ) 420 { 421 throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) ); 422 } 423 424 this.superiorOid = superiorOid; 425 } 426 427 428 /** 429 * Gets the Name of the superior AttributeType for this AttributeType. 430 * 431 * @return The Name of the superior AttributeType for this AttributeType. 432 */ 433 public String getSuperiorName() 434 { 435 if ( superior != null ) 436 { 437 return superior.getName(); 438 } 439 else 440 { 441 return superiorOid; 442 } 443 } 444 445 446 /** 447 * Gets the Syntax for this AttributeType's values. 448 * 449 * @return the value syntax 450 */ 451 public LdapSyntax getSyntax() 452 { 453 return syntax; 454 } 455 456 457 /** 458 * Sets the Syntax for this AttributeType 459 * 460 * @param syntax The Syntax for this AttributeType 461 */ 462 public void setSyntax( LdapSyntax syntax ) 463 { 464 if ( locked ) 465 { 466 throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) ); 467 } 468 469 this.syntax = syntax; 470 this.syntaxOid = syntax.getOid(); 471 } 472 473 474 /** 475 * Gets the Syntax name for this AttributeType's values. 476 * 477 * @return the value syntax name 478 */ 479 public String getSyntaxName() 480 { 481 if ( syntax != null ) 482 { 483 return syntax.getName(); 484 } 485 else 486 { 487 return syntaxOid; 488 } 489 } 490 491 492 /** 493 * Gets the Syntax OID for this AttributeType's values. 494 * 495 * @return the value syntax's OID 496 */ 497 public String getSyntaxOid() 498 { 499 return syntaxOid; 500 } 501 502 503 /** 504 * Sets the Syntax OID for this AttributeType 505 * 506 * @param syntaxOid The syntax OID for this AttributeType 507 */ 508 public void setSyntaxOid( String syntaxOid ) 509 { 510 if ( locked ) 511 { 512 throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) ); 513 } 514 515 this.syntaxOid = syntaxOid; 516 } 517 518 519 /** 520 * Gets the MatchingRule for this AttributeType used for equality matching. 521 * 522 * @return the equality matching rule 523 */ 524 public MatchingRule getEquality() 525 { 526 return equality; 527 } 528 529 530 /** 531 * Sets the Equality MR for this AttributeType 532 * 533 * @param equality The Equality MR for this AttributeType 534 */ 535 public void setEquality( MatchingRule equality ) 536 { 537 if ( locked ) 538 { 539 throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) ); 540 } 541 542 this.equality = equality; 543 this.equalityOid = equality.getOid(); 544 } 545 546 547 /** 548 * Gets the Equality OID for this AttributeType's values. 549 * 550 * @return the value Equality's OID 551 */ 552 public String getEqualityOid() 553 { 554 return equalityOid; 555 } 556 557 558 /** 559 * Sets the Equality OID for this AttributeType 560 * 561 * @param equalityOid The Equality OID for this AttributeType 562 */ 563 public void setEqualityOid( String equalityOid ) 564 { 565 if ( locked ) 566 { 567 throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) ); 568 } 569 570 this.equalityOid = equalityOid; 571 } 572 573 574 /** 575 * Gets the Equality Name for this AttributeType's values. 576 * 577 * @return the value Equality's Name 578 */ 579 public String getEqualityName() 580 { 581 if ( equality != null ) 582 { 583 return equality.getName(); 584 } 585 else 586 { 587 return equalityOid; 588 } 589 } 590 591 592 /** 593 * Gets the MatchingRule for this AttributeType used for Ordering matching. 594 * 595 * @return the Ordering matching rule 596 */ 597 public MatchingRule getOrdering() 598 { 599 return ordering; 600 } 601 602 603 /** 604 * Sets the Ordering MR for this AttributeType 605 * 606 * @param ordering The Ordering MR for this AttributeType 607 */ 608 public void setOrdering( MatchingRule ordering ) 609 { 610 if ( locked ) 611 { 612 throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) ); 613 } 614 615 this.ordering = ordering; 616 this.orderingOid = ordering.getOid(); 617 } 618 619 620 /** 621 * Gets the MatchingRule name for this AttributeType used for Ordering matching. 622 * 623 * @return the Ordering matching rule name 624 */ 625 public String getOrderingName() 626 { 627 if ( ordering != null ) 628 { 629 return ordering.getName(); 630 } 631 else 632 { 633 return orderingOid; 634 } 635 } 636 637 638 /** 639 * Gets the Ordering OID for this AttributeType's values. 640 * 641 * @return the value Equality's OID 642 */ 643 public String getOrderingOid() 644 { 645 return orderingOid; 646 } 647 648 649 /** 650 * Sets the Ordering OID for this AttributeType 651 * 652 * @param orderingOid The Ordering OID for this AttributeType 653 */ 654 public void setOrderingOid( String orderingOid ) 655 { 656 if ( locked ) 657 { 658 throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) ); 659 } 660 661 this.orderingOid = orderingOid; 662 } 663 664 665 /** 666 * Gets the MatchingRule for this AttributeType used for Substr matching. 667 * 668 * @return the Substr matching rule 669 */ 670 public MatchingRule getSubstring() 671 { 672 return substring; 673 } 674 675 676 /** 677 * Sets the Substr MR for this AttributeType 678 * 679 * @param substring The Substr MR for this AttributeType 680 */ 681 public void setSubstring( MatchingRule substring ) 682 { 683 if ( locked ) 684 { 685 throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) ); 686 } 687 688 this.substring = substring; 689 this.substringOid = substring.getOid(); 690 } 691 692 693 /** 694 * Gets the MatchingRule name for this AttributeType used for Substring matching. 695 * 696 * @return the Substring matching rule name 697 */ 698 public String getSubstringName() 699 { 700 if ( substring != null ) 701 { 702 return substring.getName(); 703 } 704 else 705 { 706 return substringOid; 707 } 708 } 709 710 711 /** 712 * Gets the Substr OID for this AttributeType's values. 713 * 714 * @return the value Substr's OID 715 */ 716 public String getSubstringOid() 717 { 718 return substringOid; 719 } 720 721 722 /** 723 * Sets the Substr OID for this AttributeType 724 * 725 * @param substrOid The Substr OID for this AttributeType 726 */ 727 public void setSubstringOid( String substrOid ) 728 { 729 if ( locked ) 730 { 731 throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) ); 732 } 733 734 this.substringOid = substrOid; 735 } 736 737 738 /** 739 * Tells if the attributeType is a USER attribute or not 740 * @return true if this is a USER attributeType 741 */ 742 public boolean isUser() 743 { 744 return usage == UsageEnum.USER_APPLICATIONS; 745 } 746 747 748 /** 749 * Tells if the attributeType is an OPERATIONAL attribute or not 750 * @return true if this is an OPERATIONAL attributeType 751 */ 752 public boolean isOperational() 753 { 754 return usage != UsageEnum.USER_APPLICATIONS; 755 } 756 757 758 /** 759 * Checks to see if this AttributeType is the ancestor of another 760 * attributeType. 761 * 762 * @param descendant the perspective descendant to check 763 * @return true if the descendant is truly a derived from this AttributeType 764 */ 765 public boolean isAncestorOf( AttributeType descendant ) 766 { 767 if ( ( descendant == null ) || this.equals( descendant ) ) 768 { 769 return false; 770 } 771 772 return isAncestorOrEqual( this, descendant ); 773 } 774 775 776 /** 777 * Tells if an AttributeType is HumanReadable or not, depending on its Syntax. 778 * 779 * @return <tt>true</tt> if the AttributeType is Human Readable. 780 */ 781 public boolean isHR() 782 { 783 return ( syntax != null ) && ( syntax.isHumanReadable() ); 784 } 785 786 787 /** 788 * Checks to see if this AttributeType is the descendant of another 789 * attributeType. 790 * 791 * @param ancestor the perspective ancestor to check 792 * @return true if this AttributeType truly descends from the ancestor 793 */ 794 public boolean isDescendantOf( AttributeType ancestor ) 795 { 796 if ( ( ancestor == null ) || equals( ancestor ) ) 797 { 798 return false; 799 } 800 801 return isAncestorOrEqual( ancestor, this ); 802 } 803 804 805 /** 806 * Recursive method which checks to see if a descendant is really an ancestor or if the two 807 * are equal. 808 * 809 * @param ancestor the possible ancestor of the descendant 810 * @param descendant the possible descendant of the ancestor 811 * @return true if the ancestor equals the descendant or if the descendant is really 812 * a subtype of the ancestor. otherwise false 813 */ 814 private boolean isAncestorOrEqual( AttributeType ancestor, AttributeType descendant ) 815 { 816 if ( ( ancestor == null ) || ( descendant == null ) ) 817 { 818 return false; 819 } 820 821 if ( ancestor.equals( descendant ) ) 822 { 823 return true; 824 } 825 826 return isAncestorOrEqual( ancestor, descendant.getSuperior() ); 827 } 828 829 830 /** 831 * {@inheritDoc} 832 */ 833 @Override 834 public String toString() 835 { 836 return SchemaObjectRenderer.OPEN_LDAP_SCHEMA_RENDERER.render( this ); 837 } 838 839 840 /** 841 * {@inheritDoc} 842 */ 843 @Override 844 public AttributeType copy() 845 { 846 AttributeType copy = new AttributeType( oid ); 847 848 // Copy the SchemaObject common data 849 copy.copy( this ); 850 851 // Copy the canUserModify flag 852 copy.canUserModify = canUserModify; 853 854 // Copy the isCollective flag 855 copy.isCollective = isCollective; 856 857 // Copy the isSingleValue flag 858 copy.isSingleValued = isSingleValued; 859 860 // Copy the USAGE type 861 copy.usage = usage; 862 863 // All the references to other Registries object are set to null, 864 // all the OIDs are copied 865 // The EQUALITY MR 866 copy.equality = null; 867 copy.equalityOid = equalityOid; 868 869 // The ORDERING MR 870 copy.ordering = null; 871 copy.orderingOid = orderingOid; 872 873 // The SUBSTR MR 874 copy.substring = null; 875 copy.substringOid = substringOid; 876 877 // The SUP AT 878 copy.superior = null; 879 copy.superiorOid = superiorOid; 880 881 // The SYNTAX 882 copy.syntax = null; 883 copy.syntaxOid = syntaxOid; 884 copy.syntaxLength = syntaxLength; 885 886 // The relaxed flag 887 copy.setRelaxed( isRelaxed ); 888 889 return copy; 890 } 891 892 893 /** 894 * {@inheritDoc} 895 */ 896 @Override 897 public int hashCode() 898 { 899 int ath = super.hashCode(); 900 901 // USER_MODIFY 902 ath += ath * 17 + ( canUserModify ? 1 : 0 ); 903 904 // COLLECTIVE 905 ath += ath * 17 + ( isCollective ? 1 : 0 ); 906 907 // MULTI_VALUED 908 ath += ath * 17 + ( isSingleValued ? 1 : 0 ); 909 910 // The syntax 911 if ( syntax != null ) 912 { 913 ath += ath * 17 + syntax.hashCode(); 914 } 915 916 // The equality matching rule if any 917 if ( equality != null ) 918 { 919 ath += ath * 17 + equality.hashCode(); 920 } 921 922 // The substring matching rule if any 923 if ( substring != null ) 924 { 925 ath += ath * 17 + substring.hashCode(); 926 } 927 928 // The superior if any 929 if ( superior != null ) 930 { 931 ath += ath * 17 + superior.hashCode(); 932 } 933 934 // The ordering if any 935 if ( ordering != null ) 936 { 937 ath += ath * 17 + ordering.hashCode(); 938 } 939 940 // Last, not least, the usage 941 ath += ath * 17 + usage.getValue(); 942 943 return ath; 944 } 945 946 947 /** 948 * {@inheritDoc} 949 */ 950 @Override 951 public boolean equals( Object o ) 952 { 953 if ( this == o ) 954 { 955 return true; 956 } 957 958 if ( !super.equals( o ) ) 959 { 960 return false; 961 } 962 963 if ( !( o instanceof AttributeType ) ) 964 { 965 return false; 966 } 967 968 AttributeType that = ( AttributeType ) o; 969 970 // The COLLECTIVE 971 if ( isCollective != that.isCollective ) 972 { 973 return false; 974 } 975 976 // The SINGLE_VALUE 977 if ( isSingleValued != that.isSingleValued ) 978 { 979 return false; 980 } 981 982 // The NO_USER_MODIFICATION 983 if ( canUserModify != that.canUserModify ) 984 { 985 return false; 986 } 987 988 // The USAGE 989 if ( usage != that.usage ) 990 { 991 return false; 992 } 993 994 // The equality 995 if ( !compareOid( equalityOid, that.equalityOid ) ) 996 { 997 return false; 998 } 999 1000 if ( equality != null ) 1001 { 1002 if ( !equality.equals( that.equality ) ) 1003 { 1004 return false; 1005 } 1006 } 1007 else 1008 { 1009 if ( that.equality != null ) 1010 { 1011 return false; 1012 } 1013 } 1014 1015 // The ordering 1016 if ( !compareOid( orderingOid, that.orderingOid ) ) 1017 { 1018 return false; 1019 } 1020 1021 if ( ordering != null ) 1022 { 1023 if ( !ordering.equals( that.ordering ) ) 1024 { 1025 return false; 1026 } 1027 } 1028 else 1029 { 1030 if ( that.ordering != null ) 1031 { 1032 return false; 1033 } 1034 } 1035 1036 // The substring 1037 if ( !compareOid( substringOid, that.substringOid ) ) 1038 { 1039 return false; 1040 } 1041 1042 if ( substring != null ) 1043 { 1044 if ( !substring.equals( that.substring ) ) 1045 { 1046 return false; 1047 } 1048 } 1049 else 1050 { 1051 if ( that.substring != null ) 1052 { 1053 return false; 1054 } 1055 } 1056 1057 // The superior 1058 if ( !compareOid( superiorOid, that.superiorOid ) ) 1059 { 1060 return false; 1061 } 1062 1063 if ( superior != null ) 1064 { 1065 if ( !superior.equals( that.superior ) ) 1066 { 1067 return false; 1068 } 1069 } 1070 else 1071 { 1072 if ( that.superior != null ) 1073 { 1074 return false; 1075 } 1076 } 1077 1078 // The syntax 1079 if ( !compareOid( syntaxOid, that.syntaxOid ) ) 1080 { 1081 return false; 1082 } 1083 1084 if ( syntaxLength != that.syntaxLength ) 1085 { 1086 return false; 1087 } 1088 1089 if ( syntax == null ) 1090 { 1091 return that.syntax == null; 1092 } 1093 1094 if ( syntax.equals( that.syntax ) ) 1095 { 1096 return syntaxLength == that.syntaxLength; 1097 } 1098 else 1099 { 1100 return false; 1101 } 1102 } 1103 1104 1105 /** 1106 * {@inheritDoc} 1107 */ 1108 @Override 1109 public void clear() 1110 { 1111 // Clear the common elements 1112 super.clear(); 1113 1114 // Clear the references 1115 equality = null; 1116 ordering = null; 1117 substring = null; 1118 superior = null; 1119 syntax = null; 1120 } 1121}