class Treequel::Schema::AttributeType

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

Authors

Copyright (c) 2008-2011, 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

handle_malformed_parse( message, attr_desc ) click to toggle source

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 112
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
new( schema, oid, attributes ) click to toggle source

Create a new AttributeType

# File lib/treequel/schema/attributetype.rb, line 126
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
parse( schema, description ) click to toggle source

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

# File lib/treequel/schema/attributetype.rb, line 61
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

directory_operational?() click to toggle source
distributed_operational?() click to toggle source
dsa_operational?() click to toggle source
Alias for: is_dsa_operational?
dsa_specific?() click to toggle source
Alias for: is_dsa_operational?
equality_matching_rule() click to toggle source

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

# File lib/treequel/schema/attributetype.rb, line 279
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
inspect() click to toggle source

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

# File lib/treequel/schema/attributetype.rb, line 263
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
is_directory_operational?() click to toggle source

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

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

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

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

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

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

Test whether or not the attribute is an operational attribute.

# File lib/treequel/schema/attributetype.rb, line 340
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?
is_user?() click to toggle source

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

# File lib/treequel/schema/attributetype.rb, line 333
def is_user?
        return !self.is_operational?
end
Also aliased as: user?
name() click to toggle source

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

# File lib/treequel/schema/attributetype.rb, line 207
def name
        return self.names.first
end
normalized_names() click to toggle source

Return the attributeType's names after normalizing them.

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

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

# File lib/treequel/schema/attributetype.rb, line 292
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
substr_matching_rule() click to toggle source

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

# File lib/treequel/schema/attributetype.rb, line 305
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
sup() click to toggle source

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 229
def sup
        return nil unless oid = self.sup_oid
        return self.schema.attribute_types[ oid ]
end
syntax() click to toggle source

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

# File lib/treequel/schema/attributetype.rb, line 317
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
to_s() click to toggle source

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

# File lib/treequel/schema/attributetype.rb, line 237
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
user?() click to toggle source
Alias for: is_user?
valid_name?( name ) click to toggle source

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

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