Class: Treequel::Schema::AttributeType

Inherits:
Object
  • Object
show all
Extended by:
Loggability, AttributeDeclarations
Includes:
Constants::Patterns, Normalization
Defined in:
lib/treequel/schema/attributetype.rb

Overview

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

Authors

:include: LICENSE

Please see the file LICENSE in the base directory for licensing details.

Constant Summary collapse

OID_SPLIT_PATTERN =

Regex for splitting a syntax OID from its length specifier

/
  ^
  #{SQUOTE}?
  (#{OID})         # OID = $1
  #{SQUOTE}?
  (?:
    #{LCURLY}
    (#{LEN})        # Length = $2
    #{RCURLY}
  )?$
/x
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)

'userApplications'.freeze
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)

%w[directoryOperation distributedOperation dSAOperation].freeze

Constants included from Constants::Patterns

Constants::Patterns::ALPHA, Constants::Patterns::AMPERSAND, Constants::Patterns::ASSERTIONVALUE, Constants::Patterns::ASTERISK, Constants::Patterns::ATTRIBUTE_TYPE, Constants::Patterns::ATTRIBUTE_TYPE_AND_VALUE, Constants::Patterns::ATTRIBUTE_VALUE, Constants::Patterns::BASE64_CHAR, Constants::Patterns::BASE64_STRING, Constants::Patterns::COLON, Constants::Patterns::COMMA, Constants::Patterns::DESCR, Constants::Patterns::DIGIT, Constants::Patterns::DISTINGUISHED_NAME, Constants::Patterns::DN_ESCAPED, Constants::Patterns::DOLLAR, Constants::Patterns::DOT, Constants::Patterns::DQUOTE, Constants::Patterns::DSTRING, Constants::Patterns::EQUALS, Constants::Patterns::ESC, Constants::Patterns::ESCAPED, Constants::Patterns::EXCLAMATION, Constants::Patterns::EXTENSIONS, Constants::Patterns::FILL, Constants::Patterns::FOLD, Constants::Patterns::HEX, Constants::Patterns::HEXPAIR, Constants::Patterns::HEXSTRING, Constants::Patterns::HYPHEN, Constants::Patterns::KEYCHAR, Constants::Patterns::KEYSTRING, Constants::Patterns::KIND, Constants::Patterns::LANGLE, Constants::Patterns::LCURLY, Constants::Patterns::LDAP_ATTRIBUTE_DESCRIPTION, Constants::Patterns::LDAP_ATTRIBUTE_TYPE_DESCRIPTION, Constants::Patterns::LDAP_MATCHING_RULE_DESCRIPTION, Constants::Patterns::LDAP_MATCHING_RULE_USE_DESCRIPTION, Constants::Patterns::LDAP_MISORDERED_DESC_OBJECTCLASS_DESCRIPTION, Constants::Patterns::LDAP_MISORDERED_KIND_OBJECTCLASS_DESCRIPTION, Constants::Patterns::LDAP_MISORDERED_SYNTAX_ATTRIBUTE_TYPE_DESCRIPTION, Constants::Patterns::LDAP_OBJECTCLASS_DESCRIPTION, Constants::Patterns::LDAP_SUBSTRING_FILTER, Constants::Patterns::LDAP_SUBSTRING_FILTER_VALUE, Constants::Patterns::LDAP_SYNTAX_DESCRIPTION, Constants::Patterns::LDAP_TRAILING_KIND_OBJECTCLASS_DESCRIPTION, Constants::Patterns::LDAP_UNESCAPE_SQUOTE_ATTRIBUTE_TYPE_DESCRIPTION, Constants::Patterns::LDIF_ATTRIBUTE_DESCRIPTION, Constants::Patterns::LDIF_ATTRIBUTE_TYPE, Constants::Patterns::LDIF_ATTRTYPE_OPTION, Constants::Patterns::LDIF_ATTRTYPE_OPTIONS, Constants::Patterns::LDIF_ATTRVAL_SPEC, Constants::Patterns::LDIF_ATTR_TYPE_CHARS, Constants::Patterns::LDIF_OPT_CHAR, Constants::Patterns::LDIF_SAFE_CHAR, Constants::Patterns::LDIF_SAFE_INIT_CHAR, Constants::Patterns::LDIF_SAFE_STRING, Constants::Patterns::LDIF_VALUE_SPEC, Constants::Patterns::LDIGIT, Constants::Patterns::LEADCHAR, Constants::Patterns::LEADKEYCHAR, Constants::Patterns::LEN, Constants::Patterns::LPAREN, Constants::Patterns::LUTF1, Constants::Patterns::MALFORMED_DSTRING, Constants::Patterns::MALFORMED_QDSTRING, Constants::Patterns::NOIDLEN, Constants::Patterns::NORMAL, Constants::Patterns::NUL, Constants::Patterns::NUMBER, Constants::Patterns::NUMERICOID, Constants::Patterns::OCTET, Constants::Patterns::OID, Constants::Patterns::OIDLIST, Constants::Patterns::OIDS, Constants::Patterns::PAIR, Constants::Patterns::PLUS, Constants::Patterns::QDESCR, Constants::Patterns::QDESCRLIST, Constants::Patterns::QDESCRS, Constants::Patterns::QDSTRING, Constants::Patterns::QDSTRINGLIST, Constants::Patterns::QDSTRINGS, Constants::Patterns::QQ, Constants::Patterns::QS, Constants::Patterns::QUOTED_DESCR, Constants::Patterns::QUOTED_NUMERICOID, Constants::Patterns::QUTF1, Constants::Patterns::QUTF8, Constants::Patterns::RANGLE, Constants::Patterns::RCURLY, Constants::Patterns::RELATIVE_DISTINGUISHED_NAME, Constants::Patterns::RPAREN, Constants::Patterns::SEMI, Constants::Patterns::SEP, Constants::Patterns::SHARP, Constants::Patterns::SP, Constants::Patterns::SPACE, Constants::Patterns::SPECIAL, Constants::Patterns::SQUOTE, Constants::Patterns::STRING, Constants::Patterns::STRINGCHAR, Constants::Patterns::SUTF1, Constants::Patterns::TILDE, Constants::Patterns::TRAILCHAR, Constants::Patterns::TUTF1, Constants::Patterns::UNESCAPED, Constants::Patterns::URI_REF, Constants::Patterns::USAGE, Constants::Patterns::USCORE, Constants::Patterns::UTF0, Constants::Patterns::UTF1, Constants::Patterns::UTF1SUBSET, Constants::Patterns::UTF2, Constants::Patterns::UTF3, Constants::Patterns::UTF4, Constants::Patterns::UTF8, Constants::Patterns::UTFMB, Constants::Patterns::VALUEENCODING, Constants::Patterns::VERTBAR, Constants::Patterns::WSP, Constants::Patterns::XSTRING

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from AttributeDeclarations

predicate_attr

Methods included from Normalization

normalize_hash, normalize_key

Constructor Details

#initialize(schema, oid, attributes) ⇒ AttributeType

Create a new AttributeType



131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/treequel/schema/attributetype.rb', line 131

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

Instance Attribute Details

#descObject

The attributeType’s description



170
171
172
# File 'lib/treequel/schema/attributetype.rb', line 170

def desc
  @desc
end

#eqmatch_oidObject

The oid of the attributeType’s equality matching rule



179
180
181
# File 'lib/treequel/schema/attributetype.rb', line 179

def eqmatch_oid
  @eqmatch_oid
end

#extensionsObject

The attributeType’s extensions (as a String)



208
209
210
# File 'lib/treequel/schema/attributetype.rb', line 208

def extensions
  @extensions
end

#namesObject (readonly)

The Array of the attributeType’s names



167
168
169
# File 'lib/treequel/schema/attributetype.rb', line 167

def names
  @names
end

#oidObject (readonly)

The attributeType’s oid



164
165
166
# File 'lib/treequel/schema/attributetype.rb', line 164

def oid
  @oid
end

#ordmatch_oidObject

The oid of the attributeType’s order matching rule



182
183
184
# File 'lib/treequel/schema/attributetype.rb', line 182

def ordmatch_oid
  @ordmatch_oid
end

#schemaObject (readonly)

The schema the attributeType belongs to



161
162
163
# File 'lib/treequel/schema/attributetype.rb', line 161

def schema
  @schema
end

#submatch_oidObject

The oid of the attributeType’s substring matching rule



185
186
187
# File 'lib/treequel/schema/attributetype.rb', line 185

def submatch_oid
  @submatch_oid
end

#sup_oidObject

The attributeType’s superior class’s OID



176
177
178
# File 'lib/treequel/schema/attributetype.rb', line 176

def sup_oid
  @sup_oid
end

#syntax_lenObject

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



191
192
193
# File 'lib/treequel/schema/attributetype.rb', line 191

def syntax_len
  @syntax_len
end

#syntax_oidObject

The oid of the attributeType’s value syntax



188
189
190
# File 'lib/treequel/schema/attributetype.rb', line 188

def syntax_oid
  @syntax_oid
end

#usagetypeObject Also known as: usage

The application of this attributeType



203
204
205
# File 'lib/treequel/schema/attributetype.rb', line 203

def usagetype
  @usagetype
end

Class Method Details

.handle_malformed_parse(message, attr_desc) ⇒ Object

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.



117
118
119
120
121
# File 'lib/treequel/schema/attributetype.rb', line 117

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

.parse(schema, description) ⇒ Object

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



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/treequel/schema/attributetype.rb', line 66

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

Instance Method Details

#equality_matching_ruleObject

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



284
285
286
287
288
289
290
291
292
# File 'lib/treequel/schema/attributetype.rb', line 284

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

#inspectObject

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



268
269
270
271
272
273
274
275
276
277
278
279
# File 'lib/treequel/schema/attributetype.rb', line 268

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?Boolean Also known as: directory_operational?

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

Returns:

  • (Boolean)


353
354
355
356
# File 'lib/treequel/schema/attributetype.rb', line 353

def is_directory_operational?
  usage_type = self.usage || DEFAULT_USAGE_TYPE
  return usage_type == 'directoryOperation'
end

#is_distributed_operational?Boolean Also known as: distributed_operational?

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

Returns:

  • (Boolean)


361
362
363
364
# File 'lib/treequel/schema/attributetype.rb', line 361

def is_distributed_operational?
  usage_type = self.usage || DEFAULT_USAGE_TYPE
  return usage_type == 'distributedOperation'
end

#is_dsa_operational?Boolean Also known as: dsa_operational?, dsa_specific?

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

Returns:

  • (Boolean)


369
370
371
372
# File 'lib/treequel/schema/attributetype.rb', line 369

def is_dsa_operational?
  usage_type = self.usage || DEFAULT_USAGE_TYPE
  return usage_type == 'dSAOperation'
end

#is_operational?Boolean Also known as: operational?

Test whether or not the attribute is an operational attribute.

Returns:

  • (Boolean)


345
346
347
348
# File 'lib/treequel/schema/attributetype.rb', line 345

def is_operational?
  usage_type = self.usage || DEFAULT_USAGE_TYPE
  return OPERATIONAL_ATTRIBUTE_USAGES.map( &:downcase ).include?( usage_type.downcase )
end

#is_user?Boolean Also known as: user?

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

Returns:

  • (Boolean)


338
339
340
# File 'lib/treequel/schema/attributetype.rb', line 338

def is_user?
  return !self.is_operational?
end

#nameObject

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



212
213
214
# File 'lib/treequel/schema/attributetype.rb', line 212

def name
  return self.names.first
end

#normalized_namesObject

Return the attributeType’s names after normalizing them.



218
219
220
# File 'lib/treequel/schema/attributetype.rb', line 218

def normalized_names
  return self.names.collect {|name| normalize_key(name) }
end

#ordering_matching_ruleObject

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



297
298
299
300
301
302
303
304
305
# File 'lib/treequel/schema/attributetype.rb', line 297

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_ruleObject

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



310
311
312
313
314
315
316
317
318
# File 'lib/treequel/schema/attributetype.rb', line 310

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

#supObject

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.



234
235
236
237
# File 'lib/treequel/schema/attributetype.rb', line 234

def sup
  return nil unless oid = self.sup_oid
  return self.schema.attribute_types[ oid ]
end

#syntaxObject

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



322
323
324
325
326
327
328
329
330
# File 'lib/treequel/schema/attributetype.rb', line 322

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_sObject

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



242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
# File 'lib/treequel/schema/attributetype.rb', line 242

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

#valid_name?(name) ⇒ Boolean

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

Returns:

  • (Boolean)


225
226
227
228
# File 'lib/treequel/schema/attributetype.rb', line 225

def valid_name?( name )
  normname = normalize_key( name )
  return self.normalized_names.include?( normname )
end