Module: Jinx::Propertied

Included in:
Introspector
Defined in:
lib/jinx/metadata/propertied.rb

Overview

Meta-data mix-in for attribute accessors.

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#attributes<Symbol> (readonly)

Returns this class’s attributes.

Returns:

  • (<Symbol>)

    this class’s attributes



11
12
13
# File 'lib/jinx/metadata/propertied.rb', line 11

def attributes
  @attributes
end

#defaultsHasher (readonly)

Returns the default attribute => value associations.

Returns:

  • (Hasher)

    the default attribute => value associations



14
15
16
# File 'lib/jinx/metadata/propertied.rb', line 14

def defaults
  @defaults
end

Instance Method Details

#add_alternate_key_attribute(attribute) ⇒ Object (private)

Adds the given attribute to this class’s alternate key.



392
393
394
395
# File 'lib/jinx/metadata/propertied.rb', line 392

def add_alternate_key_attribute(attribute)
  @alt_key ||= []
  @alt_key << standard_attribute(attribute)
end

#add_attribute(attribute, type, *flags) ⇒ Property

Adds the given attribute to this Class.

Parameters:

  • attribute (Symbol)

    the attribute to add

  • type (Class)

    (see Property#initialize)

  • flags (<Symbol>)

    the qualifying #flags

Returns:

  • (Property)

    the attribute meta-data



30
31
32
33
34
# File 'lib/jinx/metadata/propertied.rb', line 30

def add_attribute(attribute, type, *flags)
  prop = create_nonjava_property(attribute, type, *flags)
  add_property(prop)
  prop
end

#add_attribute_aliases(hash) ⇒ Object (private)

Deprecated.

Use #alias_attribute instead

Creates the given aliases to attributes.

Parameters:

See Also:

  • #attribute_alias


363
364
365
# File 'lib/jinx/metadata/propertied.rb', line 363

def add_attribute_aliases(hash)
  hash.each { |aliaz, pa| alias_attribute(aliaz, pa) }
end

#add_attribute_default(attribute, value) ⇒ Object (private)

Parameters:

  • attribute (Symbol)

    the attribute

  • value

    the default value



434
435
436
# File 'lib/jinx/metadata/propertied.rb', line 434

def add_attribute_default(attribute, value)
  @local_defaults[standard_attribute(attribute)] = value
end

#add_attribute_defaults(hash) ⇒ Object (private)

Parameters:

  • hash (Hash)

    the attribute => value defaults



428
429
430
# File 'lib/jinx/metadata/propertied.rb', line 428

def add_attribute_defaults(hash)
  hash.each { |da, value| add_attribute_default(da, value) }
end

#add_mandatory_attribute(attribute) ⇒ Object (private)

Parameters:

  • attribute (Symbol)

    the mandatory attribute



444
445
446
# File 'lib/jinx/metadata/propertied.rb', line 444

def add_mandatory_attribute(attribute)
  @local_mndty_attrs << standard_attribute(attribute)
end

#add_mandatory_attributes(*attributes) ⇒ Object (private)

Parameters:

  • attributes (<Symbol>)

    the mandatory attributes



439
440
441
# File 'lib/jinx/metadata/propertied.rb', line 439

def add_mandatory_attributes(*attributes)
  attributes.each { |ma| add_mandatory_attribute(ma) }
end

#add_primary_key_attribute(attribute) ⇒ Object (private)

Adds the given attribute to this class’s primary key.



368
369
370
371
# File 'lib/jinx/metadata/propertied.rb', line 368

def add_primary_key_attribute(attribute)
  @prm_key ||= []
  @prm_key << standard_attribute(attribute)
end

#add_property(property) ⇒ Object (private)

Parameters:



494
495
496
497
498
499
500
501
502
503
# File 'lib/jinx/metadata/propertied.rb', line 494

def add_property(property)
  pa = property.attribute
  # Guard against redundant property
  if @local_prop_hash.has_key?(pa) then
    raise ArgumentError.new("#{self} property already exists: #{pa}")
  end
  @local_prop_hash[pa] = property
  # map the attribute symbol to itself in the alias map
  @local_std_prop_hash[pa] = pa
end

#add_restriction(attribute) ⇒ Object

Adds the given attribute restriction to this Class. This method is intended for the exclusive use of Jinx::Property#restrict. Clients restrict an attribute by calling that method.

Parameters:

  • attribute (Property)

    the restricted attribute



41
42
43
44
# File 'lib/jinx/metadata/propertied.rb', line 41

def add_restriction(attribute)
  add_property(attribute)
  logger.debug { "Added restriction #{attribute} to #{qp}." }
end

#add_secondary_key_attribute(attribute) ⇒ Object (private)

Adds the given attribute to this class’s secondary key.



380
381
382
383
# File 'lib/jinx/metadata/propertied.rb', line 380

def add_secondary_key_attribute(attribute)
  @scnd_key ||= []
  @scnd_key << standard_attribute(attribute)
end

#alias_attribute(aliaz, attribute) ⇒ Object (private)

Creates the given attribute alias. If the attribute metadata is registered with this class, then this method overrides Class.alias_attribute to create a new alias reader (writer) method which delegates to the attribute reader (writer, resp.). This aliasing mechanism differs from Class#alias_attribute, which directly aliases the existing reader or writer method. Delegation allows the alias to pick up run-time redefinitions of the aliased reader and writer. If the attribute metadata is not registered with this class, then this method delegates to Class#alias_attribute.

Parameters:

  • aliaz (Symbol)

    the attribute alias

  • attribute (Symbol)

    the attribute to alias



349
350
351
352
353
354
355
356
# File 'lib/jinx/metadata/propertied.rb', line 349

def alias_attribute(aliaz, attribute)
  if property_defined?(attribute) then
    delegate_to_property(aliaz, property(attribute))
    register_property_alias(aliaz, attribute)
  else
    super
  end
end

#alias_standard_attribute_hash{Symbol => Symbol} (protected)

Returns the attribute alias => standard hash.

Returns:

  • ({Symbol => Symbol})

    the attribute alias => standard hash



252
253
254
# File 'lib/jinx/metadata/propertied.rb', line 252

def alias_standard_attribute_hash
  @alias_std_prop_map
end

#all_key_attributes<Symbol>

Returns the primary, secondary and alternate key attributes.

Returns:

  • (<Symbol>)

    the primary, secondary and alternate key attributes



70
71
72
# File 'lib/jinx/metadata/propertied.rb', line 70

def all_key_attributes
  primary_key_attributes + secondary_key_attributes + alternate_key_attributes
end

#alternate_key_attributes<Symbol>

Returns this class’s alternate key attribute array. If this class’s secondary key is not set, then the alternate key is the Metadata superclass alternate key, if any.

Returns:

  • (<Symbol>)

    the alternate key attributes



65
66
67
# File 'lib/jinx/metadata/propertied.rb', line 65

def alternate_key_attributes
  @alt_key or superclass < Resource ? superclass.alternate_key_attributes : Array::EMPTY_ARRAY
end

#append_ancestor_enum(enum) ⇒ Enumerable (private)

Appends to the given enumerable the result of evaluating the block given to this method on the superclass, if the superclass is also a Resource class.

Parameters:

Returns:

  • (Enumerable)

    the Enumerable#union of the base collection with the superclass collection, if applicable



520
521
522
523
524
525
526
527
# File 'lib/jinx/metadata/propertied.rb', line 520

def append_ancestor_enum(enum)
  return enum unless Class === self and superclass < Resource and superclass.introspected?
  anc_enum = yield superclass
  if anc_enum.nil? then
    raise MetadataError.new("#{qp} superclass #{superclass.qp} does not have required metadata")
  end
  enum.union(anc_enum)
end

#attribute_filter(attributes = nil) {|prop| ... } ⇒ AttributeEnumerator

Returns an AttributeEnumerator on this Resource class’s attributes which iterates on each of the given attributes. If a filter block is given, then only those properties which satisfy the filter block are enumerated.

Parameters:

  • attributes (<Symbol>, nil) (defaults to: nil)

    the optional attributes to filter on (default all attributes)

Yields:

  • (prop)

    the optional attribute selector

Yield Parameters:

  • prop (Property)

    the candidate attribute

Returns:

Raises:



232
233
234
235
236
237
# File 'lib/jinx/metadata/propertied.rb', line 232

def attribute_filter(attributes=nil, &filter)
  # make the attribute filter
  raise MetadataError.new("#{self} has not been introspected") unless introspected?
  ph = attributes ? attributes.to_compact_hash { |pa| @prop_hash[pa] } : @prop_hash
  AttributeEnumerator.new(ph, &filter)
end

#collect_mandatory_attributesObject (private)

Merges the secondary key, owner and additional mandatory attributes defined in the attributes.



541
542
543
544
# File 'lib/jinx/metadata/propertied.rb', line 541

def collect_mandatory_attributes
  @local_mndty_attrs.merge!(default_mandatory_local_attributes)
  append_ancestor_enum(@local_mndty_attrs) { |par| par.mandatory_attributes }
end

#collection_attribute?(attribute) ⇒ Boolean

Returns whether attribute is an instance of a Java domain class.

Parameters:

  • attribute (Symbol)

    the attribute to check

Returns:

  • (Boolean)

    whether attribute is an instance of a Java domain class



220
221
222
# File 'lib/jinx/metadata/propertied.rb', line 220

def collection_attribute?(attribute)
  property(attribute).collection?
end

#compose_property(property, other) {|target| ... } ⇒ Property (private)

Creates a new convenience property in this source class which composes the given property and the other property. The new property symbol is the same as the other property symbol. The new property reader and writer methods delegate to the respective composed property reader and writer methods.

Parameters:

  • property (Property)

    the reference from the source to the intermediary

  • other (Property)

    the reference from the intermediary to the target

Yields:

  • (target)

    obtain the intermediary object from the target

Yield Parameters:

  • target (Resource)

    the target object

Returns:

Raises:

  • (ArgumentError)

    if the other property does not have an inverse



282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
# File 'lib/jinx/metadata/propertied.rb', line 282

def compose_property(property, other)
  if other.inverse.nil? then
    raise ArgumentError.new("Can't compose #{qp}.#{property} with inverseless #{other.declarer.qp}.#{other}")
  end
  # the source -> intermediary access methods
  sir, siw = property.accessors
  # the intermediary -> target access methods
  itr, itw = other.accessors
  # the target -> intermediary reader method
  tir = other.inverse
  # The reader composes the source -> intermediary -> target readers.
  define_method(itr) do
    ref = send(sir)
    ref.send(itr) if ref
  end
  # The writer sets the source intermediary to the target intermediary.
  define_method(itw) do |tgt|
    if tgt then
      ref = block_given? ? yield(tgt) : tgt.send(tir)
      raise ArgumentError.new("#{tgt} does not reference a #{other.inverse}") if ref.nil?
    end
    send(siw, ref)
  end
  prop = add_attribute(itr, other.type)
  logger.debug { "Created #{qp}.#{prop} which composes #{qp}.#{property} and #{other.declarer.qp}.#{other}." }
  prop.qualify(:collection) if other.collection?
  prop
end

#create_nonjava_property(attribute, type, *flags) ⇒ Property (private)

Returns the attribute meta-data.

Parameters:

  • attribute (Symbol)

    the attribute to add

  • type (Class)

    (see Property#initialize)

  • flags (<Symbol>)

    the qualifying #flags

Returns:

  • (Property)

    the attribute meta-data



313
314
315
# File 'lib/jinx/metadata/propertied.rb', line 313

def create_nonjava_property(attribute, type, *flags)
  Property.new(attribute, self, type, *flags)
end

#default_mandatory_local_attributesObject (private)



546
547
548
549
550
551
552
553
554
555
# File 'lib/jinx/metadata/propertied.rb', line 546

def default_mandatory_local_attributes
  mandatory = Set.new
  # add the secondary key
  mandatory.merge(secondary_key_attributes)
  # add the owner attribute, if any
  oa = mandatory_owner_attribute
  mandatory << oa if oa
  # remove optional attributes
  mandatory.delete_if { |ma| property(ma).flags.include?(:optional) }
end

#dependent_attributes(inc_super = true) ⇒ <Symbol>

Returns the dependent attributes.

Parameters:

  • inc_super (Boolean, nil) (defaults to: true)

    flag indicating whether to include dependents defined in the superclass

Returns:

  • (<Symbol>)

    the dependent attributes



169
170
171
172
173
174
175
# File 'lib/jinx/metadata/propertied.rb', line 169

def dependent_attributes(inc_super=true)
  if inc_super then
    @dep_flt ||= attribute_filter { |prop| prop.dependent? }
  else
    @local_dep_flt ||= dependent_attributes.compose { |prop| prop.declarer == self }
  end
end

#dependent_properties(inc_super = true) ⇒ <Property>

Returns the dependent properties.

Parameters:

  • inc_super (Boolean, nil) (defaults to: true)

    flag indicating whether to include dependents defined in the superclass

Returns:

  • (<Property>)

    the dependent properties



179
180
181
# File 'lib/jinx/metadata/propertied.rb', line 179

def dependent_properties(inc_super=true)
  dependent_attributes(inc_super).properties
end

#domain_attribute?(attribute) ⇒ Boolean

Returns whether attribute return type is a domain object or collection thereof.

Parameters:

  • attribute (Symbol)

    the attribute to check

Returns:

  • (Boolean)

    whether attribute return type is a domain object or collection thereof



208
209
210
# File 'lib/jinx/metadata/propertied.rb', line 208

def domain_attribute?(attribute)
  property(attribute).domain?
end

#domain_attributes<Symbol>

Returns the domain attributes.

Returns:

  • (<Symbol>)

    the domain attributes



138
139
140
# File 'lib/jinx/metadata/propertied.rb', line 138

def domain_attributes
  @dom_flt ||= attribute_filter { |prop| prop.domain? }
end

#domain_properties<Property>

Returns the domain properties.

Returns:

  • (<Property>)

    the domain properties



143
144
145
# File 'lib/jinx/metadata/propertied.rb', line 143

def domain_properties
  domain_attributes.properties
end

#each_property {|prop| ... } ⇒ Object

Yields:

  • (prop)

    operate on the given property

Yield Parameters:

  • prop (Property)

    the property in this class



76
77
78
# File 'lib/jinx/metadata/propertied.rb', line 76

def each_property(&block)
  @prop_hash.each_value(&block)
end

#independent_attributes<Symbol>

Returns:



163
164
165
# File 'lib/jinx/metadata/propertied.rb', line 163

def independent_attributes
  @ind_flt ||= attribute_filter { |prop| prop.independent? }
end

#init_property_classifiersObject (private)

Initializes the property meta-data structures.



259
260
261
262
263
264
265
266
267
268
# File 'lib/jinx/metadata/propertied.rb', line 259

def init_property_classifiers
  @local_std_prop_hash = {}
  @alias_std_prop_map = append_ancestor_enum(@local_std_prop_hash) { |par| par.alias_standard_attribute_hash }
  @local_prop_hash = {}
  @prop_hash = append_ancestor_enum(@local_prop_hash) { |par| par.property_hash }
  @attributes = Enumerable::Enumerator.new(@prop_hash, :each_key)
  @local_mndty_attrs = Set.new
  @local_defaults = {}
  @defaults = append_ancestor_enum(@local_defaults) { |par| par.defaults }
end

#introspected?Boolean

Returns whether this class’s metadata has been introspected.

Returns:

  • (Boolean)

    whether this class’s metadata has been introspected



240
241
242
# File 'lib/jinx/metadata/propertied.rb', line 240

def introspected?
  !!@prop_hash
end

#java_attributes<Symbol> Also known as: printable_attributes

Returns the domain attributes which wrap a java attribute.

Returns:

  • (<Symbol>)

    the domain attributes which wrap a java attribute

See Also:



131
132
133
# File 'lib/jinx/metadata/propertied.rb', line 131

def java_attributes
  @java_flt ||= attribute_filter { |prop| prop.java_property? }
end

#mandatory_attributesObject

Returns the subject class’s required attributes, determined as follows:

  • An attribute marked with the :mandatory flag is mandatory.

  • An attribute marked with the :optional or :autogenerated flag is not mandatory.

  • Otherwise, A secondary key or owner attribute is mandatory.



193
194
195
# File 'lib/jinx/metadata/propertied.rb', line 193

def mandatory_attributes
  @mnd_flt ||= collect_mandatory_attributes
end

#mandatory_owner_attributeSymbol? (private)

Returns the unique non-self-referential owner attribute, if one exists.

Returns:

  • (Symbol, nil)

    the unique non-self-referential owner attribute, if one exists



558
559
560
561
562
# File 'lib/jinx/metadata/propertied.rb', line 558

def mandatory_owner_attribute
  oa = owner_attribute || return
  prop = property(oa)
  oa if prop.java_property? and prop.type != self
end

#most_specific_domain_attribute(klass, attributes = nil) ⇒ Symbol? (private)

Returns the most specific attribute which references the given target type, or nil if none. If the given class can be returned by more than on of the attributes, then the attribute is chosen whose return type most closely matches the given class.

Parameters:

  • klass (Class)

    the target type

  • attributes (AttributeEnumerator, nil) (defaults to: nil)

    the attributes to check (default all domain attributes)

Returns:

  • (Symbol, nil)

    the most specific reference attribute, or nil if none



324
325
326
327
328
329
330
331
332
333
334
335
336
337
# File 'lib/jinx/metadata/propertied.rb', line 324

def most_specific_domain_attribute(klass, attributes=nil)
  attributes ||= domain_attributes
  candidates = attributes.properties
  best = candidates.inject(nil) do |better, prop|
    # If the attribute can return the klass then the return type is a candidate.
    # In that case, the klass replaces the best candidate if it is more specific than
    # the best candidate so far.
    klass <= prop.type ? (better && better.type <= prop.type ? better : prop) : better
  end
  if best then
    logger.debug { "Most specific #{qp} -> #{klass.qp} reference from among #{candidates.qp} is #{best.declarer.qp}.#{best}." }
    best.to_sym
  end
end

#nondomain_attribute?(attribute) ⇒ Boolean

Returns whether attribute is not a domain attribute.

Parameters:

  • attribute (Symbol)

    the attribute to check

Returns:

  • (Boolean)

    whether attribute is not a domain attribute



214
215
216
# File 'lib/jinx/metadata/propertied.rb', line 214

def nondomain_attribute?(attribute)
  not domain_attribute?(attribute)
end

#nondomain_attributes<Symbol>

Returns the non-domain Java attributes.

Returns:

  • (<Symbol>)

    the non-domain Java attributes



148
149
150
# File 'lib/jinx/metadata/propertied.rb', line 148

def nondomain_attributes
  @ndom_flt ||= attribute_filter { |prop| prop.java_property? and prop.nondomain? }
end

#nondomain_java_attributes<Symbol> Also known as: mergeable_attributes

Returns the non-domain Java attribute wrapper attributes.

Returns:

  • (<Symbol>)

    the non-domain Java attribute wrapper attributes



153
154
155
# File 'lib/jinx/metadata/propertied.rb', line 153

def nondomain_java_attributes
  @ndom_java_flt ||= nondomain_attributes.compose { |prop| prop.java_property? }
end

#nonowner_attributesObject



197
198
199
# File 'lib/jinx/metadata/propertied.rb', line 197

def nonowner_attributes
  @nownr_atts ||= attribute_filter { |prop| not prop.owner? }
end

#offset_attribute(hash, offset = nil) ⇒ Object (private)

Makes a new synthetic Class#offset_attr_accessor attribute for each method => original hash entry.

Parameters:

  • hash ({Symbol => Symbol})

    the offset => original method hash

  • offset (Integer, nil) (defaults to: nil)

    the offset amount (default is -1)



533
534
535
536
# File 'lib/jinx/metadata/propertied.rb', line 533

def offset_attribute(hash, offset=nil)
  offset_attr_accessor(hash, offset)
  hash.each { |ja, original| add_attribute(ja, property(original).type) }
end

#primary_key_attributes<Symbol>

Returns the primary key attributes.

Returns:

  • (<Symbol>)

    the primary key attributes



47
48
49
# File 'lib/jinx/metadata/propertied.rb', line 47

def primary_key_attributes
  @prm_key or Class === self && superclass < Resource ? superclass.primary_key_attributes : Array::EMPTY_ARRAY
end

#properties<Property>

Returns this domain class’s properties.

Returns:

  • (<Property>)

    this domain class’s properties



81
82
83
# File 'lib/jinx/metadata/propertied.rb', line 81

def properties
  @props ||= enum_for(:each_property)
end

#property(attribute) ⇒ Property

Returns the corresponding property.

Parameters:

  • attribute (Symbol)

    the property attribute symbol or alias

Returns:

  • (Property)

    the corresponding property

Raises:

  • (NameError)

    if the attribute is not recognized



88
89
90
91
92
93
94
95
96
97
# File 'lib/jinx/metadata/propertied.rb', line 88

def property(attribute)
  # Simple and predominant case is that the attribute is a standard attribute.
  # Otherwise, resolve attribute to the standard symbol.
  prop = @prop_hash[attribute] || @prop_hash[standard_attribute(attribute)]
  # If not found, then raise a NameError.
  if prop.nil? then
    raise NameError.new("#{name.demodulize} attribute not found: #{attribute}")
  end
  prop
end

#property_defined?(name) ⇒ Boolean

Returns whether this class has an attribute with the given symbol.

Parameters:

Returns:

  • (Boolean)

    whether there is a corresponding attribute



20
21
22
# File 'lib/jinx/metadata/propertied.rb', line 20

def property_defined?(name)
  !!@alias_std_prop_map[name.to_sym]
end

#property_hash{Symbol => Property} (protected)

Returns the attribute => metadata hash.

Returns:



247
248
249
# File 'lib/jinx/metadata/propertied.rb', line 247

def property_hash
  @prop_hash
end

#property_path(*attributes) ⇒ <Property>

Returns the corresponding property path.

Parameters:

  • attributes (<Symbol>)

    an attribute reference path leading from this class

Returns:

  • (<Property>)

    the corresponding property path

Raises:

  • (ArgumentError)

    if there are no attributes or one of the attributes besides the last is not a domain attribute

  • (NameError)

    if the attribute is not recognized



104
105
106
107
108
109
110
111
112
113
114
# File 'lib/jinx/metadata/propertied.rb', line 104

def property_path(*attributes)
  raise ArgumentError.new("#{self} property path attributes is missing") if attributes.empty?
  # the property of the first attribute
  prop = property(attributes.shift)
  return [prop] if attributes.empty?
  unless prop.type < Resource then
    raise ArgumentError.new("#{self} property path attribute #{prop} is not a domain type")
  end
  # Prepend the first property to the remaining properties.
  prop.type.property_path(*attributes).unshift(prop)
end

#qualify_attribute(attribute, *flags) ⇒ Object (private)

Convenience method which delegates to #qualify_property.

Parameters:

  • attribute (Symbol)

    the attribute to qualify

  • (see ({Symbol => Object})

    #qualify_property)



465
466
467
# File 'lib/jinx/metadata/propertied.rb', line 465

def qualify_attribute(attribute, *flags)
  qualify_property(property(attribute), *flags)
end

#qualify_property(property, *flags) ⇒ Object (private)

Marks the given attribute with flags supported by Jinx::Property#qualify.

Parameters:

  • property (Property)

    the property to qualify

  • the ({Symbol => Object})

    flags to apply to the restricted attribute



452
453
454
455
456
457
458
459
# File 'lib/jinx/metadata/propertied.rb', line 452

def qualify_property(property, *flags)
  if property.declarer == self then
    property.qualify(*flags)
  else
    logger.debug { "Restricting #{property.declarer.qp}.#{property} to #{qp} with additional flags #{flags.to_series}" }
    property.restrict_flags(self, *flags)
  end
end

#register_property_alias(aliaz, attribute) ⇒ Object (private)

Registers an alias to an attribute.

Parameters:

  • aliaz (Symbol)

    the attribute alias

  • attribute (Symbol)

    the attribute to alias

Raises:

  • (ArgumentError)


508
509
510
511
512
# File 'lib/jinx/metadata/propertied.rb', line 508

def register_property_alias(aliaz, attribute)
  std = standard_attribute(attribute)
  raise ArgumentError.new("#{self} attribute not found: #{attribute}") if std.nil?
  @local_std_prop_hash[aliaz.to_sym] = std
end

#remove_attribute(attribute) ⇒ Object (private)

Removes the given attribute from this Resource. An attribute declared in a superclass Resource is hidden from this Resource but retained in the declaring Resource.



472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
# File 'lib/jinx/metadata/propertied.rb', line 472

def remove_attribute(attribute)
  sa = standard_attribute(attribute)
  # if the attribute is local, then delete it, otherwise filter out the superclass attribute
  sp = @local_prop_hash.delete(sa)
  if sp then
    # clear the inverse, if any
    clear_inverse(sp)
    # remove from the mandatory attributes, if necessary
    @local_mndty_attrs.delete(sa)
    # remove from the attribute => metadata hash
    @local_std_prop_hash.delete_if { |aliaz, pa| pa == sa }
  else
    # Filter the superclass hashes.
    anc_prop_hash = @prop_hash.components[1]
    @prop_hash.components[1] = anc_prop_hash.filter_on_key { |pa| pa != attribute }
    anc_alias_hash = @alias_std_prop_map.components[1]
    @alias_std_prop_map.components[1] = anc_alias_hash.filter_on_key { |pa| pa != attribute }
  end
  logger.debug { "Removed the #{qp} #{attribute} property." }
end

#secondary_key_attributes<Symbol>

Returns this class’s secondary key attribute array. If this class’s secondary key is not set, then the secondary key is the Metadata superclass secondary key, if any.

Returns:

  • (<Symbol>)

    the secondary key attributes



56
57
58
# File 'lib/jinx/metadata/propertied.rb', line 56

def secondary_key_attributes
  @scnd_key or Class === self && superclass < Resource ? superclass.secondary_key_attributes : Array::EMPTY_ARRAY
end

#secondary_key_non_owner_domain_attributes<Symbol>

Returns # the non-owner secondary key domain attributes.

Returns:

  • (<Symbol>)

    # the non-owner secondary key domain attributes



202
203
204
# File 'lib/jinx/metadata/propertied.rb', line 202

def secondary_key_non_owner_domain_attributes
  @scd_key_nown_flt ||= attribute_filter(secondary_key_attributes) { |prop| prop.domain? and not prop.owner? }
end

#set_alternate_key_attributes(*attributes) ⇒ Object (private)

Sets this class’s alternate key attributes to the given attributes. If attributes is set to nil, then the alternate key is cleared.



399
400
401
# File 'lib/jinx/metadata/propertied.rb', line 399

def set_alternate_key_attributes(*attributes)
  attributes.each { |a| add_alternate_key_attribute(a) }
end

#set_attribute_type(attribute, klass) ⇒ Object (private)

Sets the given attribute type to klass. If attribute is defined in a superclass, then klass must be a subclass of the superclass attribute type.

Parameters:

  • attribute (Symbol)

    the attribute to modify

  • klass (Class)

    the attribute type

Raises:

  • (ArgumentError)

    if the new type is incompatible with the current attribute type



409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
# File 'lib/jinx/metadata/propertied.rb', line 409

def set_attribute_type(attribute, klass)
  prop = property(attribute)
  # degenerate no-op case
  return if klass == prop.type
  # If this class is the declarer, then simply set the attribute type.
  # Otherwise, if the attribute type is unspecified or is a superclass of the given class,
  # then make a new attribute metadata for this class.
  if prop.declarer == self then
    prop.type = klass
    logger.debug { "Set #{qp}.#{attribute} type to #{klass.qp}." }
  elsif prop.type.nil? or klass < prop.type then
    prop.restrict(self, :type => klass)
    logger.debug { "Restricted #{prop.declarer.qp}.#{attribute}(#{prop.type.qp}) to #{qp} with return type #{klass.qp}." }
  else
    raise ArgumentError.new("Cannot reset #{qp}.#{attribute} type #{prop.type.qp} to incompatible #{klass.qp}")
  end
end

#set_primary_key_attributes(*attributes) ⇒ Object (private)

Sets this class’s primary key attributes to the given attributes. If attributes is set to nil, then the primary key is cleared.



375
376
377
# File 'lib/jinx/metadata/propertied.rb', line 375

def set_primary_key_attributes(*attributes)
  attributes.each { |a| add_primary_key_attribute(a) }
end

#set_secondary_key_attributes(*attributes) ⇒ Object (private)

Sets this class’s secondary key attributes to the given attributes. If attributes is set to nil, then the secondary key is cleared.



387
388
389
# File 'lib/jinx/metadata/propertied.rb', line 387

def set_secondary_key_attributes(*attributes)
  attributes.each { |a| add_secondary_key_attribute(a) }
end

#standard_attribute(name_or_alias) ⇒ Symbol

Returns the standard attribute symbol for the given name or alias.

Parameters:

  • name_or_alias (Symbol, String)

    the attribute name or alias

Returns:

  • (Symbol)

    the standard attribute symbol for the given name or alias

Raises:

  • (ArgumentError)

    if the attribute name or alias argument is missing

  • (NameError)

    if the attribute is not found



120
121
122
123
124
125
# File 'lib/jinx/metadata/propertied.rb', line 120

def standard_attribute(name_or_alias)
  if name_or_alias.nil? then
    raise ArgumentError.new("#{qp} standard attribute call is missing the attribute name/alias parameter")
  end
  @alias_std_prop_map[name_or_alias.to_sym] or raise NameError.new("#{self} attribute not found: #{name_or_alias}")
end

#unidirectional_dependent_attributes<Symbol>

Returns the unidirectional dependent attributes.

Returns:

  • (<Symbol>)

    the unidirectional dependent attributes

See Also:



185
186
187
# File 'lib/jinx/metadata/propertied.rb', line 185

def unidirectional_dependent_attributes
  @uni_dep_flt ||= dependent_attributes.compose { |prop| prop.unidirectional? }
end