jinx 2.1.1 → 2.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.md +4 -0
 - data/lib/jinx.rb +0 -1
 - data/lib/jinx/cli/application.rb +3 -3
 - data/lib/jinx/cli/command.rb +1 -1
 - data/lib/jinx/helpers/array.rb +3 -3
 - data/lib/jinx/helpers/associative.rb +41 -0
 - data/lib/jinx/helpers/collections.rb +0 -1
 - data/lib/jinx/helpers/enumerable.rb +5 -2
 - data/lib/jinx/helpers/hash.rb +1 -1
 - data/lib/jinx/helpers/hashable.rb +1 -7
 - data/lib/jinx/helpers/inflector.rb +1 -1
 - data/lib/jinx/helpers/log.rb +63 -11
 - data/lib/jinx/helpers/math.rb +20 -11
 - data/lib/jinx/helpers/options.rb +4 -4
 - data/lib/jinx/helpers/pretty_print.rb +0 -1
 - data/lib/jinx/helpers/transitive_closure.rb +1 -1
 - data/lib/jinx/helpers/uniquifier.rb +50 -17
 - data/lib/jinx/helpers/visitor.rb +3 -3
 - data/lib/jinx/import/java.rb +1 -1
 - data/lib/jinx/importer.rb +3 -2
 - data/lib/jinx/metadata/attribute_enumerator.rb +1 -1
 - data/lib/jinx/metadata/dependency.rb +3 -3
 - data/lib/jinx/metadata/introspector.rb +46 -42
 - data/lib/jinx/metadata/inverse.rb +17 -1
 - data/lib/jinx/metadata/java_property.rb +10 -10
 - data/lib/jinx/metadata/propertied.rb +19 -16
 - data/lib/jinx/metadata/property.rb +11 -11
 - data/lib/jinx/resource.rb +86 -14
 - data/lib/jinx/resource/match_visitor.rb +7 -5
 - data/lib/jinx/resource/merge_visitor.rb +3 -10
 - data/lib/jinx/resource/mergeable.rb +16 -16
 - data/lib/jinx/resource/reference_enumerator.rb +0 -1
 - data/lib/jinx/resource/reference_path_visitor.rb +1 -1
 - data/lib/jinx/resource/reference_visitor.rb +5 -6
 - data/lib/jinx/resource/unique.rb +1 -1
 - data/lib/jinx/version.rb +1 -1
 - data/test/lib/jinx/helpers/associative_test.rb +26 -0
 - data/test/lib/jinx/helpers/collections_test.rb +14 -2
 - data/test/lib/jinx/helpers/uniquifier_test.rb +11 -0
 - metadata +9 -8
 - data/Gemfile.lock +0 -27
 - data/lib/jinx/helpers/error.rb +0 -15
 - data/lib/jinx/helpers/key_transformer_hash.rb +0 -43
 
    
        data/lib/jinx/helpers/visitor.rb
    CHANGED
    
    | 
         @@ -196,7 +196,7 @@ module Jinx 
     | 
|
| 
       196 
196 
     | 
    
         
             
                # @yieldparam children the nodes slated by this Visitor to visit next
         
     | 
| 
       197 
197 
     | 
    
         
             
                # @raise [ArgumentError] if a block is not given to this method
         
     | 
| 
       198 
198 
     | 
    
         
             
                def filter
         
     | 
| 
       199 
     | 
    
         
            -
                   
     | 
| 
      
 199 
     | 
    
         
            +
                  raise ArgumentError.new("A filter block is not given to the visitor filter method") unless block_given?
         
     | 
| 
       200 
200 
     | 
    
         
             
                  Visitor.new(@options) { |node| yield(node, node_children(node)) }
         
     | 
| 
       201 
201 
     | 
    
         
             
                end
         
     | 
| 
       202 
202 
     | 
    
         | 
| 
         @@ -319,7 +319,7 @@ module Jinx 
     | 
|
| 
       319 
319 
     | 
    
         
             
                  def visit(*nodes)
         
     | 
| 
       320 
320 
     | 
    
         
             
                    if nodes.size == 1 then
         
     | 
| 
       321 
321 
     | 
    
         
             
                      nodes = nodes.first
         
     | 
| 
       322 
     | 
    
         
            -
                       
     | 
| 
      
 322 
     | 
    
         
            +
                      raise ArgumentError.new("Sync visitor requires a pair of entry nodes") unless nodes.size == 2
         
     | 
| 
       323 
323 
     | 
    
         
             
                    end
         
     | 
| 
       324 
324 
     | 
    
         
             
                    super(nodes)
         
     | 
| 
       325 
325 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -331,7 +331,7 @@ module Jinx 
     | 
|
| 
       331 
331 
     | 
    
         
             
                  def to_enum(*nodes)
         
     | 
| 
       332 
332 
     | 
    
         
             
                    if nodes.size == 1 then
         
     | 
| 
       333 
333 
     | 
    
         
             
                      nodes = nodes.first
         
     | 
| 
       334 
     | 
    
         
            -
                       
     | 
| 
      
 334 
     | 
    
         
            +
                      raise ArgumentError.new("Sync visitor requires a pair of entry nodes") unless nodes.size == 2
         
     | 
| 
       335 
335 
     | 
    
         
             
                    end
         
     | 
| 
       336 
336 
     | 
    
         
             
                    super(nodes)
         
     | 
| 
       337 
337 
     | 
    
         
             
                  end
         
     | 
    
        data/lib/jinx/import/java.rb
    CHANGED
    
    | 
         @@ -91,7 +91,7 @@ module Java 
     | 
|
| 
       91 
91 
     | 
    
         
             
                  # merge return a new collection.
         
     | 
| 
       92 
92 
     | 
    
         
             
                  def merge(other)
         
     | 
| 
       93 
93 
     | 
    
         
             
                    return self if other.nil?
         
     | 
| 
       94 
     | 
    
         
            -
                     
     | 
| 
      
 94 
     | 
    
         
            +
                    raise ArgumentError.new("Merge argument must be enumerable: #{other}") unless Enumerable === other
         
     | 
| 
       95 
95 
     | 
    
         
             
                    other.each { |item| self << item }
         
     | 
| 
       96 
96 
     | 
    
         
             
                    self
         
     | 
| 
       97 
97 
     | 
    
         
             
                  end
         
     | 
    
        data/lib/jinx/importer.rb
    CHANGED
    
    | 
         @@ -69,6 +69,7 @@ module Jinx 
     | 
|
| 
       69 
69 
     | 
    
         | 
| 
       70 
70 
     | 
    
         
             
                # @param [String] the module name to resolve in the context of this module
         
     | 
| 
       71 
71 
     | 
    
         
             
                # @return [Module] the corresponding module
         
     | 
| 
      
 72 
     | 
    
         
            +
                # @raise [NameError] if the name cannot be resolved
         
     | 
| 
       72 
73 
     | 
    
         
             
                def module_for_name(name)
         
     | 
| 
       73 
74 
     | 
    
         
             
                  begin
         
     | 
| 
       74 
75 
     | 
    
         
             
                    # Incrementally resolve the module.
         
     | 
| 
         @@ -97,7 +98,7 @@ module Jinx 
     | 
|
| 
       97 
98 
     | 
    
         
             
                    begin
         
     | 
| 
       98 
99 
     | 
    
         
             
                      eval "java_package Java::#{pkg}"
         
     | 
| 
       99 
100 
     | 
    
         
             
                    rescue Exception => e
         
     | 
| 
       100 
     | 
    
         
            -
                       
     | 
| 
      
 101 
     | 
    
         
            +
                      raise ArgumentError.new("#{self} Java package #{pkg} not found - #{$!}")
         
     | 
| 
       101 
102 
     | 
    
         
             
                    end
         
     | 
| 
       102 
103 
     | 
    
         
             
                  end
         
     | 
| 
       103 
104 
     | 
    
         
             
                  # The introspected classes.
         
     | 
| 
         @@ -221,7 +222,7 @@ module Jinx 
     | 
|
| 
       221 
222 
     | 
    
         
             
                  mod = klass.parent_module
         
     | 
| 
       222 
223 
     | 
    
         
             
                  klass.each_property do |prop|
         
     | 
| 
       223 
224 
     | 
    
         
             
                    ref = prop.type
         
     | 
| 
       224 
     | 
    
         
            -
                    if ref.nil? then  
     | 
| 
      
 225 
     | 
    
         
            +
                    if ref.nil? then raise MetadataError.new("#{self} #{prop} domain type is unknown.") end
         
     | 
| 
       225 
226 
     | 
    
         
             
                    unless @introspected.include?(ref) or ref.parent_module != mod then
         
     | 
| 
       226 
227 
     | 
    
         
             
                      logger.debug { "Introspecting #{qp} #{prop} reference #{ref.qp}..." }
         
     | 
| 
       227 
228 
     | 
    
         
             
                      add_metadata(ref)
         
     | 
| 
         @@ -10,7 +10,7 @@ module Jinx 
     | 
|
| 
       10 
10 
     | 
    
         
             
                # @yieldparam [Property] the metadata for the standard attribute
         
     | 
| 
       11 
11 
     | 
    
         
             
                # @raise [ArgumentError] if a parameter is missing 
         
     | 
| 
       12 
12 
     | 
    
         
             
                def initialize(hash, &filter)
         
     | 
| 
       13 
     | 
    
         
            -
                   
     | 
| 
      
 13 
     | 
    
         
            +
                  raise ArgumentError.new("Attribute filter missing hash argument") if hash.nil?
         
     | 
| 
       14 
14 
     | 
    
         
             
                  @hash = hash
         
     | 
| 
       15 
15 
     | 
    
         
             
                  @filter = block_given? ? filter : Proc.new { true }
         
     | 
| 
       16 
16 
     | 
    
         
             
                end
         
     | 
| 
         @@ -115,11 +115,11 @@ module Jinx 
     | 
|
| 
       115 
115 
     | 
    
         
             
                # @raise [ValidationError] if the inverse is nil
         
     | 
| 
       116 
116 
     | 
    
         
             
                def add_owner(klass, inverse, attribute=nil)
         
     | 
| 
       117 
117 
     | 
    
         
             
                  if inverse.nil? then
         
     | 
| 
       118 
     | 
    
         
            -
                     
     | 
| 
      
 118 
     | 
    
         
            +
                    raise ValidationError.new("Owner #{klass.qp} missing dependent attribute for dependent #{qp}")
         
     | 
| 
       119 
119 
     | 
    
         
             
                  end
         
     | 
| 
       120 
120 
     | 
    
         
             
                  logger.debug { "Adding #{qp} owner #{klass.qp}#{' attribute ' + attribute.to_s if attribute} with inverse #{inverse}..." }
         
     | 
| 
       121 
121 
     | 
    
         
             
                  if @owner_prop_hash then
         
     | 
| 
       122 
     | 
    
         
            -
                     
     | 
| 
      
 122 
     | 
    
         
            +
                    raise MetadataError.new("Can't add #{qp} owner #{klass.qp} after dependencies have been accessed")
         
     | 
| 
       123 
123 
     | 
    
         
             
                  end
         
     | 
| 
       124 
124 
     | 
    
         | 
| 
       125 
125 
     | 
    
         
             
                  # detect the owner attribute, if necessary
         
     | 
| 
         @@ -175,7 +175,7 @@ module Jinx 
     | 
|
| 
       175 
175 
     | 
    
         
             
                  if hash.include?(otype) then
         
     | 
| 
       176 
176 
     | 
    
         
             
                    oa = hash[otype]
         
     | 
| 
       177 
177 
     | 
    
         
             
                    unless oa.nil? then
         
     | 
| 
       178 
     | 
    
         
            -
                       
     | 
| 
      
 178 
     | 
    
         
            +
                      raise MetadataError.new("Cannot set #{qp} owner attribute to #{attribute} since it is already set to #{oa}")
         
     | 
| 
       179 
179 
     | 
    
         
             
                    end
         
     | 
| 
       180 
180 
     | 
    
         
             
                    hash[otype] = prop
         
     | 
| 
       181 
181 
     | 
    
         
             
                  else
         
     | 
| 
         @@ -2,6 +2,7 @@ require 'jinx/helpers/module' 
     | 
|
| 
       2 
2 
     | 
    
         
             
            require 'jinx/import/java'
         
     | 
| 
       3 
3 
     | 
    
         
             
            require 'jinx/metadata/propertied'
         
     | 
| 
       4 
4 
     | 
    
         
             
            require 'jinx/metadata/java_property'
         
     | 
| 
      
 5 
     | 
    
         
            +
            require 'jinx/helpers/math'
         
     | 
| 
       5 
6 
     | 
    
         | 
| 
       6 
7 
     | 
    
         
             
            module Jinx
         
     | 
| 
       7 
8 
     | 
    
         
             
              # Meta-data mix-in to infer attribute meta-data from Java properties.
         
     | 
| 
         @@ -77,68 +78,71 @@ module Jinx 
     | 
|
| 
       77 
78 
     | 
    
         
             
                    return
         
     | 
| 
       78 
79 
     | 
    
         
             
                  end
         
     | 
| 
       79 
80 
     | 
    
         
             
                  # the standard underscore lower-case attributes
         
     | 
| 
       80 
     | 
    
         
            -
                   
     | 
| 
      
 81 
     | 
    
         
            +
                  prop = add_java_property(pd)
         
     | 
| 
       81 
82 
     | 
    
         
             
                  # delegate the standard attribute accessors to the attribute accessors
         
     | 
| 
       82 
     | 
    
         
            -
                  alias_property_accessors( 
     | 
| 
      
 83 
     | 
    
         
            +
                  alias_property_accessors(prop)
         
     | 
| 
       83 
84 
     | 
    
         
             
                  # add special wrappers
         
     | 
| 
       84 
     | 
    
         
            -
                  wrap_java_property( 
     | 
| 
      
 85 
     | 
    
         
            +
                  wrap_java_property(prop)
         
     | 
| 
       85 
86 
     | 
    
         
             
                  # create Ruby alias for boolean, e.g. alias :empty? for :empty
         
     | 
| 
       86 
87 
     | 
    
         
             
                  if pd.property_type.name[/\w+$/].downcase == 'boolean' then
         
     | 
| 
       87 
     | 
    
         
            -
                    #  
     | 
| 
       88 
     | 
    
         
            -
                    aliaz =  
     | 
| 
       89 
     | 
    
         
            -
                     
     | 
| 
      
 88 
     | 
    
         
            +
                    # Strip the leading is_, if any, before appending a question mark.
         
     | 
| 
      
 89 
     | 
    
         
            +
                    aliaz = prop.to_s[/^(is_)?(\w+)/, 2] << '?'
         
     | 
| 
      
 90 
     | 
    
         
            +
                    delegate_to_property(aliaz, prop)
         
     | 
| 
       90 
91 
     | 
    
         
             
                  end
         
     | 
| 
       91 
92 
     | 
    
         
             
                end
         
     | 
| 
       92 
93 
     | 
    
         | 
| 
       93 
     | 
    
         
            -
                # Adds a filter to the  
     | 
| 
       94 
     | 
    
         
            -
                def wrap_java_property( 
     | 
| 
      
 94 
     | 
    
         
            +
                # Adds a filter to the given property access methods if it is a String or Date.
         
     | 
| 
      
 95 
     | 
    
         
            +
                def wrap_java_property(property)
         
     | 
| 
      
 96 
     | 
    
         
            +
                  pd = property.property_descriptor
         
     | 
| 
       95 
97 
     | 
    
         
             
                  if pd.property_type == Java::JavaLang::String.java_class then
         
     | 
| 
       96 
     | 
    
         
            -
                     
     | 
| 
      
 98 
     | 
    
         
            +
                    wrap_java_string_property(property)
         
     | 
| 
       97 
99 
     | 
    
         
             
                  elsif pd.property_type == Java::JavaUtil::Date.java_class then
         
     | 
| 
       98 
     | 
    
         
            -
                     
     | 
| 
      
 100 
     | 
    
         
            +
                    wrap_java_date_property(property)
         
     | 
| 
       99 
101 
     | 
    
         
             
                  end
         
     | 
| 
       100 
102 
     | 
    
         
             
                end
         
     | 
| 
       101 
103 
     | 
    
         | 
| 
       102 
     | 
    
         
            -
                # Adds a  
     | 
| 
       103 
     | 
    
         
            -
                def  
     | 
| 
      
 104 
     | 
    
         
            +
                # Adds a number -> string filter to the given String property Ruby access methods.
         
     | 
| 
      
 105 
     | 
    
         
            +
                def wrap_java_string_property(property)
         
     | 
| 
      
 106 
     | 
    
         
            +
                  ra, wa = property.accessors
         
     | 
| 
      
 107 
     | 
    
         
            +
                  jra, jwa = property.java_accessors
         
     | 
| 
       104 
108 
     | 
    
         
             
                  # filter the attribute writer
         
     | 
| 
       105 
     | 
    
         
            -
                   
     | 
| 
       106 
     | 
    
         
            -
             
     | 
| 
       107 
     | 
    
         
            -
             
     | 
| 
       108 
     | 
    
         
            -
                    stdval = value.to_s unless value.nil_or_empty?
         
     | 
| 
       109 
     | 
    
         
            -
                    send(pwtr, stdval)
         
     | 
| 
      
 109 
     | 
    
         
            +
                  define_method(wa) do |value|
         
     | 
| 
      
 110 
     | 
    
         
            +
                    stdval = Math.numeric?(value) ? value.to_s : value
         
     | 
| 
      
 111 
     | 
    
         
            +
                    send(jwa, stdval)
         
     | 
| 
       110 
112 
     | 
    
         
             
                  end
         
     | 
| 
       111 
     | 
    
         
            -
                  logger.debug { "Filtered #{qp} #{ 
     | 
| 
      
 113 
     | 
    
         
            +
                  logger.debug { "Filtered #{qp} #{wa} method with non-String -> String converter." }
         
     | 
| 
       112 
114 
     | 
    
         
             
                end
         
     | 
| 
       113 
115 
     | 
    
         | 
| 
       114 
     | 
    
         
            -
                # Adds a  
     | 
| 
       115 
     | 
    
         
            -
                 
     | 
| 
      
 116 
     | 
    
         
            +
                # Adds a Java-Ruby Date filter to the given Date property Ruby access methods.
         
     | 
| 
      
 117 
     | 
    
         
            +
                # The reader returns a Ruby date. The writer sets a Java date.
         
     | 
| 
      
 118 
     | 
    
         
            +
                def wrap_java_date_property(property)
         
     | 
| 
      
 119 
     | 
    
         
            +
                  ra, wa = property.accessors
         
     | 
| 
      
 120 
     | 
    
         
            +
                  jra, jwa = property.java_accessors
         
     | 
| 
      
 121 
     | 
    
         
            +
                  
         
     | 
| 
       116 
122 
     | 
    
         
             
                  # filter the attribute reader
         
     | 
| 
       117 
     | 
    
         
            -
                   
     | 
| 
       118 
     | 
    
         
            -
             
     | 
| 
       119 
     | 
    
         
            -
                    value = send(prdr)
         
     | 
| 
      
 123 
     | 
    
         
            +
                  define_method(ra) do
         
     | 
| 
      
 124 
     | 
    
         
            +
                    value = send(jra)
         
     | 
| 
       120 
125 
     | 
    
         
             
                    Java::JavaUtil::Date === value ? value.to_ruby_date : value
         
     | 
| 
       121 
126 
     | 
    
         
             
                  end
         
     | 
| 
       122 
127 
     | 
    
         | 
| 
       123 
128 
     | 
    
         
             
                  # filter the attribute writer
         
     | 
| 
       124 
     | 
    
         
            -
                   
     | 
| 
       125 
     | 
    
         
            -
                  pwtr = pd.write_method.name.to_sym
         
     | 
| 
       126 
     | 
    
         
            -
                  define_method(awtr) do |value|
         
     | 
| 
      
 129 
     | 
    
         
            +
                  define_method(wa) do |value|
         
     | 
| 
       127 
130 
     | 
    
         
             
                    value = Java::JavaUtil::Date.from_ruby_date(value) if ::Date === value
         
     | 
| 
       128 
     | 
    
         
            -
                    send( 
     | 
| 
      
 131 
     | 
    
         
            +
                    send(jwa, value)
         
     | 
| 
       129 
132 
     | 
    
         
             
                  end
         
     | 
| 
       130 
133 
     | 
    
         | 
| 
       131 
     | 
    
         
            -
                  logger.debug { "Filtered #{qp} #{ 
     | 
| 
      
 134 
     | 
    
         
            +
                  logger.debug { "Filtered #{qp} #{ra} and #{wa} methods with Java Date <-> Ruby Date converter." }
         
     | 
| 
       132 
135 
     | 
    
         
             
                end
         
     | 
| 
       133 
136 
     | 
    
         | 
| 
       134 
     | 
    
         
            -
                # Aliases the  
     | 
| 
       135 
     | 
    
         
            -
                # 
     | 
| 
       136 
     | 
    
         
            -
                 
     | 
| 
      
 137 
     | 
    
         
            +
                # Aliases the given Ruby property reader and writer to its underlying Java property reader and writer, resp.
         
     | 
| 
      
 138 
     | 
    
         
            +
                #
         
     | 
| 
      
 139 
     | 
    
         
            +
                # @param [Property] property the property to alias
         
     | 
| 
      
 140 
     | 
    
         
            +
                def alias_property_accessors(property)
         
     | 
| 
      
 141 
     | 
    
         
            +
                  # the Java reader and writer accessor method symbols
         
     | 
| 
      
 142 
     | 
    
         
            +
                  jra, jwa = property.java_accessors
         
     | 
| 
       137 
143 
     | 
    
         
             
                  # strip the Java reader and writer is/get/set prefix and make a symbol
         
     | 
| 
       138 
     | 
    
         
            -
                   
     | 
| 
       139 
     | 
    
         
            -
                  alias_method( 
     | 
| 
       140 
     | 
    
         
            -
                  writer = "#{aliaz}=".to_sym
         
     | 
| 
       141 
     | 
    
         
            -
                  alias_method(writer, pwtr)
         
     | 
| 
      
 144 
     | 
    
         
            +
                  alias_method(property.reader, jra)
         
     | 
| 
      
 145 
     | 
    
         
            +
                  alias_method(property.writer, jwa)
         
     | 
| 
       142 
146 
     | 
    
         
             
                end
         
     | 
| 
       143 
147 
     | 
    
         | 
| 
       144 
148 
     | 
    
         
             
                # Makes a standard attribute for the given property descriptor.
         
     | 
| 
         @@ -154,7 +158,7 @@ module Jinx 
     | 
|
| 
       154 
158 
     | 
    
         
             
                  pa = prop.attribute
         
     | 
| 
       155 
159 
     | 
    
         
             
                  # the Java property name as an attribute symbol
         
     | 
| 
       156 
160 
     | 
    
         
             
                  ja = pd.name.to_sym
         
     | 
| 
       157 
     | 
    
         
            -
                   
     | 
| 
      
 161 
     | 
    
         
            +
                  delegate_to_property(ja, prop) unless prop.reader == ja
         
     | 
| 
       158 
162 
     | 
    
         
             
                  prop
         
     | 
| 
       159 
163 
     | 
    
         
             
                end
         
     | 
| 
       160 
164 
     | 
    
         | 
| 
         @@ -168,12 +172,12 @@ module Jinx 
     | 
|
| 
       168 
172 
     | 
    
         
             
                # _attribute=_ accessor methods, resp.
         
     | 
| 
       169 
173 
     | 
    
         
             
                # Calling rather than aliasing the attribute accessor allows the aliaz accessor to
         
     | 
| 
       170 
174 
     | 
    
         
             
                # reflect a change to the attribute accessor.
         
     | 
| 
       171 
     | 
    
         
            -
                def  
     | 
| 
       172 
     | 
    
         
            -
                   
     | 
| 
       173 
     | 
    
         
            -
                   
     | 
| 
       174 
     | 
    
         
            -
                  define_method(aliaz) { send( 
     | 
| 
       175 
     | 
    
         
            -
                  define_method("#{aliaz}=".to_sym) { |value| send( 
     | 
| 
       176 
     | 
    
         
            -
                  register_property_alias(aliaz, attribute)
         
     | 
| 
      
 175 
     | 
    
         
            +
                def delegate_to_property(aliaz, property)
         
     | 
| 
      
 176 
     | 
    
         
            +
                  ra, wa = property.accessors
         
     | 
| 
      
 177 
     | 
    
         
            +
                  if aliaz == ra then raise MetadataError.new("Cannot delegate #{self} #{aliaz} to itself.") end
         
     | 
| 
      
 178 
     | 
    
         
            +
                  define_method(aliaz) { send(ra) }
         
     | 
| 
      
 179 
     | 
    
         
            +
                  define_method("#{aliaz}=".to_sym) { |value| send(wa, value) }
         
     | 
| 
      
 180 
     | 
    
         
            +
                  register_property_alias(aliaz, property.attribute)
         
     | 
| 
       177 
181 
     | 
    
         
             
                end
         
     | 
| 
       178 
182 
     | 
    
         
             
              end
         
     | 
| 
       179 
183 
     | 
    
         
             
            end
         
     | 
| 
         @@ -56,7 +56,7 @@ module Jinx 
     | 
|
| 
       56 
56 
     | 
    
         
             
                  end
         
     | 
| 
       57 
57 
     | 
    
         
             
                  # This class must be the same as or a subclass of the inverse attribute type.
         
     | 
| 
       58 
58 
     | 
    
         
             
                  unless self <= inv_prop.type then
         
     | 
| 
       59 
     | 
    
         
            -
                     
     | 
| 
      
 59 
     | 
    
         
            +
                    raise TypeError.new("Cannot set #{qp}.#{pa} inverse to #{prop.type.qp}.#{pa} with incompatible type #{inv_prop.type.qp}")
         
     | 
| 
       60 
60 
     | 
    
         
             
                  end
         
     | 
| 
       61 
61 
     | 
    
         
             
                  # Set the inverse in the attribute metadata.
         
     | 
| 
       62 
62 
     | 
    
         
             
                  prop.inverse = inverse
         
     | 
| 
         @@ -70,6 +70,22 @@ module Jinx 
     | 
|
| 
       70 
70 
     | 
    
         
             
                  end
         
     | 
| 
       71 
71 
     | 
    
         
             
                  logger.debug { "Set #{qp}.#{pa} inverse to #{inverse}." }
         
     | 
| 
       72 
72 
     | 
    
         
             
                end
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
                # Clears the property inverse, if there is one.
         
     | 
| 
      
 75 
     | 
    
         
            +
                def clear_inverse(property)
         
     | 
| 
      
 76 
     | 
    
         
            +
                  # the inverse property
         
     | 
| 
      
 77 
     | 
    
         
            +
                  ip = property.inverse_property || return
         
     | 
| 
      
 78 
     | 
    
         
            +
                  # If the property is a collection and the inverse is not, then delegate to
         
     | 
| 
      
 79 
     | 
    
         
            +
                  # the inverse.
         
     | 
| 
      
 80 
     | 
    
         
            +
                  if property.collection? then
         
     | 
| 
      
 81 
     | 
    
         
            +
                    return ip.declarer.clear_inverse(ip) unless ip.collection?
         
     | 
| 
      
 82 
     | 
    
         
            +
                  else
         
     | 
| 
      
 83 
     | 
    
         
            +
                    # Restore the property reader and writer to the Java reader and writer, resp.
         
     | 
| 
      
 84 
     | 
    
         
            +
                    alias_property_accessors(property)
         
     | 
| 
      
 85 
     | 
    
         
            +
                  end
         
     | 
| 
      
 86 
     | 
    
         
            +
                  # Unset the inverse.
         
     | 
| 
      
 87 
     | 
    
         
            +
                  property.inverse = nil
         
     | 
| 
      
 88 
     | 
    
         
            +
                end
         
     | 
| 
       73 
89 
     | 
    
         | 
| 
       74 
90 
     | 
    
         
             
                # Detects an unambiguous attribute which refers to the given referencing class.
         
     | 
| 
       75 
91 
     | 
    
         
             
                # If there is exactly one attribute with the given return type, then that attribute is chosen.
         
     | 
| 
         @@ -9,7 +9,7 @@ module Jinx 
     | 
|
| 
       9 
9 
     | 
    
         
             
                attr_reader :property_descriptor
         
     | 
| 
       10 
10 
     | 
    
         | 
| 
       11 
11 
     | 
    
         
             
                # This property's Java property [reader, writer] accessors, e.g. +[:getActivityStatus, :setActivityStatus]+.
         
     | 
| 
       12 
     | 
    
         
            -
                attr_reader : 
     | 
| 
      
 12 
     | 
    
         
            +
                attr_reader :java_accessors
         
     | 
| 
       13 
13 
     | 
    
         | 
| 
       14 
14 
     | 
    
         
             
                # Creates a Ruby Property symbol corresponding to the given Ruby Java class wrapper klazz
         
     | 
| 
       15 
15 
     | 
    
         
             
                # and Java property_descriptor.
         
     | 
| 
         @@ -34,34 +34,34 @@ module Jinx 
     | 
|
| 
       34 
34 
     | 
    
         
             
                  @property_descriptor = pd
         
     | 
| 
       35 
35 
     | 
    
         
             
                  # deficient Java introspector does not recognize 'is' prefix for a Boolean property
         
     | 
| 
       36 
36 
     | 
    
         
             
                  rm = declarer.property_read_method(pd)
         
     | 
| 
       37 
     | 
    
         
            -
                   
     | 
| 
      
 37 
     | 
    
         
            +
                  raise ArgumentError.new("Property does not have a read method: #{declarer.qp}.#{pd.name}") unless rm
         
     | 
| 
       38 
38 
     | 
    
         
             
                  reader = rm.name.to_sym
         
     | 
| 
       39 
39 
     | 
    
         
             
                  unless declarer.method_defined?(reader) then
         
     | 
| 
       40 
40 
     | 
    
         
             
                    reader = "is#{reader.to_s.capitalize_first}".to_sym
         
     | 
| 
       41 
41 
     | 
    
         
             
                    unless declarer.method_defined?(reader) then
         
     | 
| 
       42 
     | 
    
         
            -
                       
     | 
| 
      
 42 
     | 
    
         
            +
                      raise ArgumentError.new("Reader method not found for #{declarer} property #{pd.name}")
         
     | 
| 
       43 
43 
     | 
    
         
             
                    end
         
     | 
| 
       44 
44 
     | 
    
         
             
                  end
         
     | 
| 
       45 
45 
     | 
    
         
             
                  unless pd.write_method then
         
     | 
| 
       46 
     | 
    
         
            -
                     
     | 
| 
      
 46 
     | 
    
         
            +
                    raise ArgumentError.new("Property does not have a write method: #{declarer.qp}.#{pd.name}")
         
     | 
| 
       47 
47 
     | 
    
         
             
                  end
         
     | 
| 
       48 
48 
     | 
    
         
             
                  writer = pd.write_method.name.to_sym
         
     | 
| 
       49 
49 
     | 
    
         
             
                  unless declarer.method_defined?(writer) then
         
     | 
| 
       50 
     | 
    
         
            -
                     
     | 
| 
      
 50 
     | 
    
         
            +
                    raise ArgumentError.new("Writer method not found for #{declarer} property #{pd.name}")
         
     | 
| 
       51 
51 
     | 
    
         
             
                  end
         
     | 
| 
       52 
     | 
    
         
            -
                  @ 
     | 
| 
      
 52 
     | 
    
         
            +
                  @java_accessors = [reader, writer]
         
     | 
| 
       53 
53 
     | 
    
         
             
                  qualify(:collection) if collection_java_class?
         
     | 
| 
       54 
54 
     | 
    
         
             
                  @type = infer_type
         
     | 
| 
       55 
55 
     | 
    
         
             
                end
         
     | 
| 
       56 
56 
     | 
    
         | 
| 
       57 
57 
     | 
    
         
             
                # @return [Symbol] the JRuby wrapper method for the Java property reader
         
     | 
| 
       58 
     | 
    
         
            -
                def  
     | 
| 
       59 
     | 
    
         
            -
                   
     | 
| 
      
 58 
     | 
    
         
            +
                def java_reader
         
     | 
| 
      
 59 
     | 
    
         
            +
                  java_accessors.first
         
     | 
| 
       60 
60 
     | 
    
         
             
                end
         
     | 
| 
       61 
61 
     | 
    
         | 
| 
       62 
62 
     | 
    
         
             
                # @return [Symbol] the JRuby wrapper method for the Java property writer
         
     | 
| 
       63 
     | 
    
         
            -
                def  
     | 
| 
       64 
     | 
    
         
            -
                   
     | 
| 
      
 63 
     | 
    
         
            +
                def java_writer
         
     | 
| 
      
 64 
     | 
    
         
            +
                  java_accessors.last
         
     | 
| 
       65 
65 
     | 
    
         
             
                end
         
     | 
| 
       66 
66 
     | 
    
         | 
| 
       67 
67 
     | 
    
         
             
                # Returns a lower-case, underscore symbol for the given property_name.
         
     | 
| 
         @@ -15,13 +15,10 @@ module Jinx 
     | 
|
| 
       15 
15 
     | 
    
         | 
| 
       16 
16 
     | 
    
         
             
                # Returns whether this class has an attribute with the given symbol.
         
     | 
| 
       17 
17 
     | 
    
         
             
                #
         
     | 
| 
       18 
     | 
    
         
            -
                # @param [Symbol]  
     | 
| 
      
 18 
     | 
    
         
            +
                # @param [String, Symbol] name the potential attribute
         
     | 
| 
       19 
19 
     | 
    
         
             
                # @return [Boolean] whether there is a corresponding attribute
         
     | 
| 
       20 
     | 
    
         
            -
                def property_defined?( 
     | 
| 
       21 
     | 
    
         
            -
                   
     | 
| 
       22 
     | 
    
         
            -
                    Jinx.fail(ArgumentError, "Property argument #{symbol.qp} of type #{symbol.class.qp} is not a symbol")
         
     | 
| 
       23 
     | 
    
         
            -
                  end
         
     | 
| 
       24 
     | 
    
         
            -
                  !!@alias_std_prop_map[symbol.to_sym]
         
     | 
| 
      
 20 
     | 
    
         
            +
                def property_defined?(name)
         
     | 
| 
      
 21 
     | 
    
         
            +
                  !!@alias_std_prop_map[name.to_sym]
         
     | 
| 
       25 
22 
     | 
    
         
             
                end
         
     | 
| 
       26 
23 
     | 
    
         | 
| 
       27 
24 
     | 
    
         
             
                # Adds the given attribute to this Class.
         
     | 
| 
         @@ -80,7 +77,8 @@ module Jinx 
     | 
|
| 
       80 
77 
     | 
    
         
             
                  @prop_hash.each_value(&block)
         
     | 
| 
       81 
78 
     | 
    
         
             
                end
         
     | 
| 
       82 
79 
     | 
    
         | 
| 
       83 
     | 
    
         
            -
                # @ 
     | 
| 
      
 80 
     | 
    
         
            +
                # @param [Symbol] attribute the property attribute symbol or alias
         
     | 
| 
      
 81 
     | 
    
         
            +
                # @return [Property] the corresponding property
         
     | 
| 
       84 
82 
     | 
    
         
             
                # @raise [NameError] if the attribute is not recognized
         
     | 
| 
       85 
83 
     | 
    
         
             
                def property(attribute)
         
     | 
| 
       86 
84 
     | 
    
         
             
                  # Simple and predominant case is that the attribute is a standard attribute.
         
     | 
| 
         @@ -88,7 +86,7 @@ module Jinx 
     | 
|
| 
       88 
86 
     | 
    
         
             
                  prop = @prop_hash[attribute] || @prop_hash[standard_attribute(attribute)]
         
     | 
| 
       89 
87 
     | 
    
         
             
                  # If not found, then raise a NameError.
         
     | 
| 
       90 
88 
     | 
    
         
             
                  if prop.nil? then
         
     | 
| 
       91 
     | 
    
         
            -
                     
     | 
| 
      
 89 
     | 
    
         
            +
                    raise NameError.new("#{name.demodulize} attribute not found: #{attribute}")
         
     | 
| 
       92 
90 
     | 
    
         
             
                  end
         
     | 
| 
       93 
91 
     | 
    
         
             
                  prop
         
     | 
| 
       94 
92 
     | 
    
         
             
                end
         
     | 
| 
         @@ -116,9 +114,9 @@ module Jinx 
     | 
|
| 
       116 
114 
     | 
    
         
             
                # @raise [NameError] if the attribute is not found
         
     | 
| 
       117 
115 
     | 
    
         
             
                def standard_attribute(name_or_alias)
         
     | 
| 
       118 
116 
     | 
    
         
             
                  if name_or_alias.nil? then
         
     | 
| 
       119 
     | 
    
         
            -
                     
     | 
| 
      
 117 
     | 
    
         
            +
                    raise ArgumentError.new("#{qp} standard attribute call is missing the attribute name/alias parameter")
         
     | 
| 
       120 
118 
     | 
    
         
             
                  end
         
     | 
| 
       121 
     | 
    
         
            -
                  @alias_std_prop_map[name_or_alias.to_sym] or  
     | 
| 
      
 119 
     | 
    
         
            +
                  @alias_std_prop_map[name_or_alias.to_sym] or raise NameError.new("#{self} attribute not found: #{name_or_alias}")
         
     | 
| 
       122 
120 
     | 
    
         
             
                end
         
     | 
| 
       123 
121 
     | 
    
         | 
| 
       124 
122 
     | 
    
         
             
                ## Metadata ATTRIBUTE FILTERS ##
         
     | 
| 
         @@ -217,10 +215,15 @@ module Jinx 
     | 
|
| 
       217 
215 
     | 
    
         
             
                # @return [AttributeEnumerator] a new attribute enumerator
         
     | 
| 
       218 
216 
     | 
    
         
             
                def attribute_filter(attributes=nil, &filter)
         
     | 
| 
       219 
217 
     | 
    
         
             
                  # make the attribute filter
         
     | 
| 
       220 
     | 
    
         
            -
                  raise MetadataError.new("#{self} has not been introspected")  
     | 
| 
      
 218 
     | 
    
         
            +
                  raise MetadataError.new("#{self} has not been introspected") unless introspected?
         
     | 
| 
       221 
219 
     | 
    
         
             
                  ph = attributes ? attributes.to_compact_hash { |pa| @prop_hash[pa] } : @prop_hash
         
     | 
| 
       222 
220 
     | 
    
         
             
                  AttributeEnumerator.new(ph, &filter)
         
     | 
| 
       223 
221 
     | 
    
         
             
                end
         
     | 
| 
      
 222 
     | 
    
         
            +
                   
         
     | 
| 
      
 223 
     | 
    
         
            +
                # @return [Boolean] whether this class's metadata has been introspected
         
     | 
| 
      
 224 
     | 
    
         
            +
                def introspected?
         
     | 
| 
      
 225 
     | 
    
         
            +
                  !!@prop_hash
         
     | 
| 
      
 226 
     | 
    
         
            +
                end
         
     | 
| 
       224 
227 
     | 
    
         | 
| 
       225 
228 
     | 
    
         
             
                protected
         
     | 
| 
       226 
229 
     | 
    
         | 
| 
         @@ -296,7 +299,7 @@ module Jinx 
     | 
|
| 
       296 
299 
     | 
    
         
             
                # @param [Symbol] attribute the attribute to alias
         
     | 
| 
       297 
300 
     | 
    
         
             
                def alias_attribute(aliaz, attribute)
         
     | 
| 
       298 
301 
     | 
    
         
             
                  if property_defined?(attribute) then
         
     | 
| 
       299 
     | 
    
         
            -
                     
     | 
| 
      
 302 
     | 
    
         
            +
                    delegate_to_property(aliaz, property(attribute))
         
     | 
| 
       300 
303 
     | 
    
         
             
                    register_property_alias(aliaz, attribute)
         
     | 
| 
       301 
304 
     | 
    
         
             
                  else
         
     | 
| 
       302 
305 
     | 
    
         
             
                    super
         
     | 
| 
         @@ -368,7 +371,7 @@ module Jinx 
     | 
|
| 
       368 
371 
     | 
    
         
             
                    prop.restrict(self, :type => klass)
         
     | 
| 
       369 
372 
     | 
    
         
             
                    logger.debug { "Restricted #{prop.declarer.qp}.#{attribute}(#{prop.type.qp}) to #{qp} with return type #{klass.qp}." }
         
     | 
| 
       370 
373 
     | 
    
         
             
                  else
         
     | 
| 
       371 
     | 
    
         
            -
                     
     | 
| 
      
 374 
     | 
    
         
            +
                    raise ArgumentError.new("Cannot reset #{qp}.#{attribute} type #{prop.type.qp} to incompatible #{klass.qp}")
         
     | 
| 
       372 
375 
     | 
    
         
             
                  end
         
     | 
| 
       373 
376 
     | 
    
         
             
                end
         
     | 
| 
       374 
377 
     | 
    
         | 
| 
         @@ -416,7 +419,7 @@ module Jinx 
     | 
|
| 
       416 
419 
     | 
    
         
             
                  prop = @local_prop_hash.delete(std_prop)
         
     | 
| 
       417 
420 
     | 
    
         
             
                  if prop then
         
     | 
| 
       418 
421 
     | 
    
         
             
                    # clear the inverse, if any
         
     | 
| 
       419 
     | 
    
         
            -
                    prop 
     | 
| 
      
 422 
     | 
    
         
            +
                    clear_inverse(prop)
         
     | 
| 
       420 
423 
     | 
    
         
             
                    # remove from the mandatory attributes, if necessary
         
     | 
| 
       421 
424 
     | 
    
         
             
                    @local_mndty_flt.delete(std_prop)
         
     | 
| 
       422 
425 
     | 
    
         
             
                    # remove from the attribute => metadata hash
         
     | 
| 
         @@ -443,7 +446,7 @@ module Jinx 
     | 
|
| 
       443 
446 
     | 
    
         
             
                # @param (see #alias_attribute)
         
     | 
| 
       444 
447 
     | 
    
         
             
                def register_property_alias(aliaz, attribute)
         
     | 
| 
       445 
448 
     | 
    
         
             
                  std = standard_attribute(attribute)
         
     | 
| 
       446 
     | 
    
         
            -
                   
     | 
| 
      
 449 
     | 
    
         
            +
                  raise ArgumentError.new("#{self} attribute not found: #{attribute}") if std.nil?
         
     | 
| 
       447 
450 
     | 
    
         
             
                  @local_std_prop_hash[aliaz.to_sym] = std
         
     | 
| 
       448 
451 
     | 
    
         
             
                end
         
     | 
| 
       449 
452 
     | 
    
         | 
| 
         @@ -457,7 +460,7 @@ module Jinx 
     | 
|
| 
       457 
460 
     | 
    
         
             
                  return enum unless Class === self and superclass.parent_module == parent_module
         
     | 
| 
       458 
461 
     | 
    
         
             
                  anc_enum = yield superclass
         
     | 
| 
       459 
462 
     | 
    
         
             
                  if anc_enum.nil? then
         
     | 
| 
       460 
     | 
    
         
            -
                     
     | 
| 
      
 463 
     | 
    
         
            +
                    raise MetadataError.new("#{qp} superclass #{superclass.qp} does not have required metadata")
         
     | 
| 
       461 
464 
     | 
    
         
             
                  end
         
     | 
| 
       462 
465 
     | 
    
         
             
                  enum.union(anc_enum)
         
     | 
| 
       463 
466 
     | 
    
         
             
                end
         
     | 
| 
         @@ -121,13 +121,13 @@ module Jinx 
     | 
|
| 
       121 
121 
     | 
    
         
             
                  begin
         
     | 
| 
       122 
122 
     | 
    
         
             
                    @inv_prop = type.property(attribute)
         
     | 
| 
       123 
123 
     | 
    
         
             
                  rescue NameError => e
         
     | 
| 
       124 
     | 
    
         
            -
                     
     | 
| 
      
 124 
     | 
    
         
            +
                    raise MetadataError.new("#{@declarer.qp}.#{self} inverse attribute #{type.qp}.#{attribute} not found")
         
     | 
| 
       125 
125 
     | 
    
         
             
                  end
         
     | 
| 
       126 
126 
     | 
    
         
             
                  # the inverse of the inverse
         
     | 
| 
       127 
127 
     | 
    
         
             
                  inv_inv_prop = @inv_prop.inverse_property
         
     | 
| 
       128 
128 
     | 
    
         
             
                  # If the inverse of the inverse is already set to a different attribute, then raise an exception.
         
     | 
| 
       129 
129 
     | 
    
         
             
                  if inv_inv_prop and not (inv_inv_prop == self or inv_inv_prop.restriction?(self))
         
     | 
| 
       130 
     | 
    
         
            -
                     
     | 
| 
      
 130 
     | 
    
         
            +
                    raise MetadataError.new("Cannot set #{type.qp}.#{attribute} inverse attribute to #{@declarer.qp}.#{self}@#{object_id} since it conflicts with existing inverse #{inv_inv_prop.declarer.qp}.#{inv_inv_prop}@#{inv_inv_prop.object_id}")
         
     | 
| 
       131 
131 
     | 
    
         
             
                  end
         
     | 
| 
       132 
132 
     | 
    
         
             
                  # Set the inverse of the inverse to this attribute.
         
     | 
| 
       133 
133 
     | 
    
         
             
                  @inv_prop.inverse = @attribute
         
     | 
| 
         @@ -270,10 +270,10 @@ module Jinx 
     | 
|
| 
       270 
270 
     | 
    
         
             
                  rtype = opts[:type] || @type
         
     | 
| 
       271 
271 
     | 
    
         
             
                  rinv = opts[:inverse] || inverse
         
     | 
| 
       272 
272 
     | 
    
         
             
                  unless declarer < @declarer then
         
     | 
| 
       273 
     | 
    
         
            -
                     
     | 
| 
      
 273 
     | 
    
         
            +
                    raise ArgumentError.new("Cannot restrict #{@declarer.qp}.#{self} to an incompatible declarer type #{declarer.qp}")
         
     | 
| 
       274 
274 
     | 
    
         
             
                  end
         
     | 
| 
       275 
275 
     | 
    
         
             
                  unless rtype <= @type then
         
     | 
| 
       276 
     | 
    
         
            -
                     
     | 
| 
      
 276 
     | 
    
         
            +
                    raise ArgumentError.new("Cannot restrict #{@declarer.qp}.#{self}({@type.qp}) to an incompatible return type #{rtype.qp}")
         
     | 
| 
       277 
277 
     | 
    
         
             
                  end
         
     | 
| 
       278 
278 
     | 
    
         
             
                  # Copy this attribute and its instance variables minus the restrictions and make a deep copy of the flags.
         
     | 
| 
       279 
279 
     | 
    
         
             
                  rst = deep_copy
         
     | 
| 
         @@ -318,7 +318,7 @@ module Jinx 
     | 
|
| 
       318 
318 
     | 
    
         
             
                # @param [Class] klass the declaring class of this restriction attribute
         
     | 
| 
       319 
319 
     | 
    
         
             
                def set_restricted_declarer(klass)
         
     | 
| 
       320 
320 
     | 
    
         
             
                  if @declarer and not klass < @declarer then
         
     | 
| 
       321 
     | 
    
         
            -
                     
     | 
| 
      
 321 
     | 
    
         
            +
                    raise MetadataError.new("Cannot reset #{declarer.qp}.#{self} declarer to #{type.qp}")
         
     | 
| 
       322 
322 
     | 
    
         
             
                  end
         
     | 
| 
       323 
323 
     | 
    
         
             
                  @declarer = klass
         
     | 
| 
       324 
324 
     | 
    
         
             
                  @declarer.add_restriction(self)
         
     | 
| 
         @@ -350,11 +350,11 @@ module Jinx 
     | 
|
| 
       350 
350 
     | 
    
         
             
                  return unless @inv_prop
         
     | 
| 
       351 
351 
     | 
    
         
             
                  logger.debug { "Clearing #{@declarer.qp}.#{self} inverse #{type.qp}.#{inverse}..." }
         
     | 
| 
       352 
352 
     | 
    
         
             
                  # Capture the inverse before unsetting it.
         
     | 
| 
       353 
     | 
    
         
            -
                   
     | 
| 
      
 353 
     | 
    
         
            +
                  ip = @inv_prop
         
     | 
| 
       354 
354 
     | 
    
         
             
                  # Unset the inverse.
         
     | 
| 
       355 
355 
     | 
    
         
             
                  @inv_prop = nil
         
     | 
| 
       356 
356 
     | 
    
         
             
                  # Clear the inverse of the inverse.
         
     | 
| 
       357 
     | 
    
         
            -
                   
     | 
| 
      
 357 
     | 
    
         
            +
                  ip.inverse = nil
         
     | 
| 
       358 
358 
     | 
    
         
             
                  logger.debug { "Cleared #{@declarer.qp}.#{self} inverse." }
         
     | 
| 
       359 
359 
     | 
    
         
             
                end
         
     | 
| 
       360 
360 
     | 
    
         | 
| 
         @@ -363,7 +363,7 @@ module Jinx 
     | 
|
| 
       363 
363 
     | 
    
         
             
                def set_flag(flag)
         
     | 
| 
       364 
364 
     | 
    
         
             
                  return if @flags.include?(flag)
         
     | 
| 
       365 
365 
     | 
    
         
             
                  unless flag_supported?(flag) then
         
     | 
| 
       366 
     | 
    
         
            -
                     
     | 
| 
      
 366 
     | 
    
         
            +
                    raise ArgumentError.new("Property #{declarer.name}.#{self} flag not supported: #{flag.qp}")
         
     | 
| 
       367 
367 
     | 
    
         
             
                  end
         
     | 
| 
       368 
368 
     | 
    
         
             
                  @flags << flag
         
     | 
| 
       369 
369 
     | 
    
         
             
                  case flag
         
     | 
| 
         @@ -379,11 +379,11 @@ module Jinx 
     | 
|
| 
       379 
379 
     | 
    
         
             
                # @raise [MetadataError] if this attribute is dependent or an inverse could not be inferred
         
     | 
| 
       380 
380 
     | 
    
         
             
                def owner_flag_set
         
     | 
| 
       381 
381 
     | 
    
         
             
                  if dependent? then
         
     | 
| 
       382 
     | 
    
         
            -
                     
     | 
| 
      
 382 
     | 
    
         
            +
                    raise MetadataError.new("#{declarer.qp}.#{self} cannot be set as a #{type.qp} owner since it is already defined as a #{type.qp} dependent")
         
     | 
| 
       383 
383 
     | 
    
         
             
                  end
         
     | 
| 
       384 
384 
     | 
    
         
             
                  inv_attr = type.dependent_attribute(@declarer)
         
     | 
| 
       385 
385 
     | 
    
         
             
                  if inv_attr.nil? then
         
     | 
| 
       386 
     | 
    
         
            -
                     
     | 
| 
      
 386 
     | 
    
         
            +
                    raise MetadataError.new("#{@declarer.qp} owner attribute #{self} does not have a #{type.qp} dependent inverse")
         
     | 
| 
       387 
387 
     | 
    
         
             
                  end
         
     | 
| 
       388 
388 
     | 
    
         
             
                  logger.debug { "#{declarer.qp}.#{self} inverse is the #{type.qp} dependent attribute #{inv_attr}." }
         
     | 
| 
       389 
389 
     | 
    
         
             
                  self.inverse = inv_attr
         
     | 
| 
         @@ -394,7 +394,7 @@ module Jinx 
     | 
|
| 
       394 
394 
     | 
    
         
             
                # @raise [MetadataError] if this is an owner attribute
         
     | 
| 
       395 
395 
     | 
    
         
             
                def dependent_flag_set
         
     | 
| 
       396 
396 
     | 
    
         
             
                  if owner? then
         
     | 
| 
       397 
     | 
    
         
            -
                     
     | 
| 
      
 397 
     | 
    
         
            +
                    raise MetadataError.new("#{declarer.qp}.#{self} cannot be set as a  #{type.qp} dependent since it is already defined as a #{type.qp} owner")
         
     | 
| 
       398 
398 
     | 
    
         
             
                  end
         
     | 
| 
       399 
399 
     | 
    
         
             
                end
         
     | 
| 
       400 
400 
     | 
    
         
             
              end
         
     |