AttributeType

class
Superclass
Object
Included Modules
Treequel::Normalization
Treequel::Constants::Patterns
Extended With
Loggability
Treequel::AttributeDeclarations

This is a class for representing attributeType declarations in a Treequel::Schema.

== Authors

Copyright © 2008-2016, Michael Granger and Mahlon E. Smith All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Constants

DEFAULT_USAGE_TYPE

The default USAGE type: “Usage of userApplications, the default, indicates that attributes of this type represent user information. That is, they are user attributes.” (RFC4512)

OID_SPLIT_PATTERN

Regex for splitting a syntax OID from its length specifier

OPERATIONAL_ATTRIBUTE_USAGES

A usage of directoryOperation, distributedOperation, or dSAOperation indicates that attributes of this type represent operational and/or administrative information. That is, they are operational attributes. (RFC4512)

Attributes

desc[RW]

The attributeType's description

eqmatch_oid[RW]

The oid of the attributeType's equality matching rule

extensions[RW]

The attributeType's extensions (as a String)

names[R]

The Array of the attributeType's names

oid[R]

The attributeType's oid

ordmatch_oid[RW]

The oid of the attributeType's order matching rule

schema[R]

The schema the attributeType belongs to

submatch_oid[RW]

The oid of the attributeType's substring matching rule

sup_oid[RW]

The attributeType's superior class's OID

syntax_len[RW]

The (optional) syntax length qualifier (nil if not present)

syntax_oid[RW]

The oid of the attributeType's value syntax

usage[RW]

The application of this attributeType

usage=[RW]

The application of this attributeType

usagetype[RW]

The application of this attributeType

Public Class Methods

anchor
handle_malformed_parse( message, attr_desc )

Handle the parse of an attributeType that matches one of the non-standard attributeType definitions found in several RFCs. If Treequel::Schema.strict_parse_mode? is true, this method will raise an exception.

# File lib/treequel/schema/attributetype.rb, line 116
def self::handle_malformed_parse( message, attr_desc )
        raise Treequel::ParseError, "Malformed attributeType: %s: %p" % [ message, attr_desc ] if
                Treequel::Schema.strict_parse_mode?
        Treequel.log.info "Working around malformed attributeType: %s: %p" % [ message, attr_desc ]
end
anchor
new( schema, oid, attributes )

Create a new AttributeType

# File lib/treequel/schema/attributetype.rb, line 130
def initialize( schema, oid, attributes )

        @schema          = schema

        @oid             = oid
        @names           = attributes[:names]
        @desc            = attributes[:desc]
        @obsolete        = attributes[:obsolete] ? true : false
        @sup_oid         = attributes[:sup_oid]
        @eqmatch_oid     = attributes[:eqmatch_oid]
        @ordmatch_oid    = attributes[:ordmatch_oid]
        @submatch_oid    = attributes[:submatch_oid]
        @single          = attributes[:single] ? true : false
        @collective      = attributes[:collective] ? true : false
        @user_modifiable = attributes[:user_modifiable] ? true : false
        @usagetype       = attributes[:usagetype]
        @extensions      = attributes[:extensions]

        @syntax_oid, @syntax_len = split_syntax_oid( attributes[:syntax_oid] ) if
                attributes[:syntax_oid]

        super()
end
anchor
parse( schema, description )

Parse an AttributeType entry from a attributeType description from a schema.

# File lib/treequel/schema/attributetype.rb, line 65
def self::parse( schema, description )
        oid, names, desc, obsolete, sup_oid, eqmatch_oid, ordmatch_oid, submatch_oid, syntax_oid,
                single, collective, nousermod, usagetype, extensions = nil

        case description.gsub( /[\n\t]+/, ' ' ).squeeze( ' ' )
        when LDAP_ATTRIBUTE_TYPE_DESCRIPTION
                oid, names, desc, obsolete, sup_oid, eqmatch_oid, ordmatch_oid, submatch_oid, syntax_oid,
                        single, collective, nousermod, usagetype, extensions = $~.captures
        when LDAP_UNESCAPE_SQUOTE_ATTRIBUTE_TYPE_DESCRIPTION
                oid, names, desc, obsolete, sup_oid, eqmatch_oid, ordmatch_oid, submatch_oid, syntax_oid,
                        single, collective, nousermod, usagetype, extensions = $~.captures
                self.handle_malformed_parse( "unescaped single quote in DESC #{desc}", description )
        when LDAP_MISORDERED_SYNTAX_ATTRIBUTE_TYPE_DESCRIPTION
                oid, names, desc, obsolete, sup_oid, syntax_oid, eqmatch_oid, ordmatch_oid, submatch_oid,
                        single, collective, nousermod, usagetype, extensions = $~.captures
                self.handle_malformed_parse( "misordered SYNTAX #{syntax_oid}", description )
        else
                raise Treequel::ParseError, "failed to parse attributeType from %p" % [ description ]
        end

        # Normalize the attributes
        names = Treequel::Schema.parse_names( names )
        desc  = Treequel::Schema.unquote_desc( desc )
        # syntax_oid  = Treequel::Schema.unquote_desc( syntax_oid ) # For AD

        sup_oid = Treequel::Schema.parse_oid( sup_oid ) if sup_oid
        eqmatch_oid = Treequel::Schema.parse_oid( eqmatch_oid ) if eqmatch_oid
        ordmatch_oid = Treequel::Schema.parse_oid( ordmatch_oid ) if ordmatch_oid
        submatch_oid = Treequel::Schema.parse_oid( submatch_oid ) if submatch_oid

        return self.new( schema, oid,
                :names           => names,
                :desc            => desc,
                :obsolete        => obsolete,
                :sup_oid         => sup_oid,
                :eqmatch_oid     => eqmatch_oid,
                :ordmatch_oid    => ordmatch_oid,
                :submatch_oid    => submatch_oid,
                :syntax_oid      => syntax_oid,
                :single          => single,
                :collective      => collective,
                :user_modifiable => nousermod ? false : true,
                :usagetype       => usagetype || DEFAULT_USAGE_TYPE,
                :extensions      => extensions
          )
end

Public Instance Methods

anchor
directory_operational?()
anchor
distributed_operational?()
anchor
dsa_operational?()
Alias for: is_dsa_operational?
anchor
dsa_specific?()
Alias for: is_dsa_operational?
anchor
equality_matching_rule()

Return the Treequel::Schema::MatchingRule that corresponds to the EQUALITY matchingRule of the receiving attributeType.

# File lib/treequel/schema/attributetype.rb, line 283
def equality_matching_rule
        if oid = self.eqmatch_oid
                return self.schema.matching_rules[ oid ]
        elsif self.sup
                return self.sup.equality_matching_rule
        else
                return nil
        end
end
anchor
inspect()

Return a human-readable representation of the object suitable for debugging

# File lib/treequel/schema/attributetype.rb, line 267
def inspect
        return "#<%s:0x%0x %s(%s) %p %sSYNTAX: %s (length: %s)>" % [
                self.class.name,
                self.object_id / 2,
                self.name,
                self.oid,
                self.desc,
                self.is_single? ? '(SINGLE) ' : '',
                self.syntax || self.syntax_oid,
                self.syntax_len ? self.syntax_len : 'unlimited',
        ]
end
anchor
is_directory_operational?()

Test whether or not the attribute is a directory operational attribute.

# File lib/treequel/schema/attributetype.rb, line 352
def is_directory_operational?
        usage_type = self.usage || DEFAULT_USAGE_TYPE
        return usage_type == 'directoryOperation'
end
Also aliased as: directory_operational?
anchor
is_distributed_operational?()

Test whether or not the attribute is a distributed operational attribute.

# File lib/treequel/schema/attributetype.rb, line 360
def is_distributed_operational?
        usage_type = self.usage || DEFAULT_USAGE_TYPE
        return usage_type == 'distributedOperation'
end
Also aliased as: distributed_operational?
anchor
is_dsa_operational?()

Test whether or not the attribute is a DSA-specific operational attribute.

# File lib/treequel/schema/attributetype.rb, line 368
def is_dsa_operational?
        usage_type = self.usage || DEFAULT_USAGE_TYPE
        return usage_type == 'dSAOperation'
end
Also aliased as: dsa_operational? , dsa_specific?
anchor
is_operational?()

Test whether or not the attribute is an operational attribute.

# File lib/treequel/schema/attributetype.rb, line 344
def is_operational?
        usage_type = self.usage || DEFAULT_USAGE_TYPE
        return OPERATIONAL_ATTRIBUTE_USAGES.map( &:downcase ).include?( usage_type.downcase )
end
Also aliased as: operational?
anchor
is_user?()

Test whether or not the attrinbute is a user applications attribute.

# File lib/treequel/schema/attributetype.rb, line 337
def is_user?
        return !self.is_operational?
end
Also aliased as: user?
anchor
name()

Return the first of the attributeType's names, if it has any, or nil.

# File lib/treequel/schema/attributetype.rb, line 211
def name
        return self.names.first
end
anchor
normalized_names()

Return the attributeType's names after normalizing them.

# File lib/treequel/schema/attributetype.rb, line 217
def normalized_names
        return self.names.collect {|name| normalize_key(name) }
end
anchor
operational?()
Alias for: is_operational?
anchor
ordering_matching_rule()

Return the Treequel::Schema::MatchingRule that corresponds to the ORDERING matchingRule of the receiving attributeType.

# File lib/treequel/schema/attributetype.rb, line 296
def ordering_matching_rule
        if oid = self.ordmatch_oid
                return self.schema.matching_rules[ oid ]
        elsif self.sup
                return self.sup.ordering_matching_rule
        else
                return nil
        end
end
anchor
substr_matching_rule()

Return the Treequel::Schema::MatchingRule that corresponds to the SUBSTR matchingRule of the receiving attributeType.

# File lib/treequel/schema/attributetype.rb, line 309
def substr_matching_rule
        if oid = self.submatch_oid
                return self.schema.matching_rules[ oid ]
        elsif self.sup
                return self.sup.substr_matching_rule
        else
                return nil
        end
end
anchor
sup()

Return the Treequel::Schema::AttributeType instance that corresponds to the receiver's superior type. If the attributeType doesn't have a SUP attribute, this method returns nil.

# File lib/treequel/schema/attributetype.rb, line 233
def sup
        return nil unless oid = self.sup_oid
        return self.schema.attribute_types[ oid ]
end
anchor
syntax()

Return the Treequel::Schema::LDAPSyntax that corresponds to the receiver's SYNTAX attribute.

# File lib/treequel/schema/attributetype.rb, line 321
def syntax
        if oid = self.syntax_oid
                return self.schema.ldap_syntaxes[ oid ]
        elsif self.sup
                return self.sup.syntax
        else
                return nil
        end
end
anchor
to_s()

Returns the attributeType as a String, which is the RFC4512-style schema description.

# File lib/treequel/schema/attributetype.rb, line 241
def to_s
        parts = [ self.oid ]

        parts << "NAME %s" % Treequel::Schema.qdescrs( self.names ) unless self.names.empty?

        parts << "DESC '%s'" % [ self.desc ]           if self.desc
        parts << "OBSOLETE"                            if self.obsolete?
        parts << "SUP %s" % [ self.sup_oid ]           if self.sup_oid
        parts << "EQUALITY %s" % [ self.eqmatch_oid ]  if self.eqmatch_oid
        parts << "ORDERING %s" % [ self.ordmatch_oid ] if self.ordmatch_oid
        parts << "SUBSTR %s" % [ self.submatch_oid ]   if self.submatch_oid
        if self.syntax_oid
                parts << "SYNTAX %s" % [ self.syntax_oid ]
                parts.last << "{%d}" % [ self.syntax_len ] if self.syntax_len
        end
        parts << "SINGLE-VALUE"                        if self.is_single?
        parts << "COLLECTIVE"                          if self.is_collective?
        parts << "NO-USER-MODIFICATION"            unless self.is_user_modifiable?
        parts << "USAGE %s" % [ self.usagetype ]       if self.usagetype
        parts << self.extensions.strip             unless self.extensions.empty?

        return "( %s )" % [ parts.join(' ') ]
end
anchor
user?()
Alias for: is_user?
anchor
valid_name?( name )

Returns true if the specified name is one of the attribute's names after normalization of both.

# File lib/treequel/schema/attributetype.rb, line 224
def valid_name?( name )
        normname = normalize_key( name )
        return self.normalized_names.include?( normname )
end