jinx 2.1.1

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.
Files changed (149) hide show
  1. data/.gitignore +14 -0
  2. data/.rspec +3 -0
  3. data/.yardopts +1 -0
  4. data/Gemfile +6 -0
  5. data/Gemfile.lock +27 -0
  6. data/History.md +6 -0
  7. data/LEGAL +5 -0
  8. data/LICENSE +22 -0
  9. data/README.md +44 -0
  10. data/Rakefile +41 -0
  11. data/examples/family/README.md +10 -0
  12. data/examples/family/ext/build.xml +35 -0
  13. data/examples/family/ext/src/family/Address.java +68 -0
  14. data/examples/family/ext/src/family/Child.java +24 -0
  15. data/examples/family/ext/src/family/DomainObject.java +26 -0
  16. data/examples/family/ext/src/family/Household.java +36 -0
  17. data/examples/family/ext/src/family/Parent.java +48 -0
  18. data/examples/family/ext/src/family/Person.java +42 -0
  19. data/examples/family/lib/family.rb +15 -0
  20. data/examples/family/lib/family/address.rb +6 -0
  21. data/examples/family/lib/family/domain_object.rb +6 -0
  22. data/examples/family/lib/family/household.rb +6 -0
  23. data/examples/family/lib/family/parent.rb +16 -0
  24. data/examples/family/lib/family/person.rb +6 -0
  25. data/examples/model/README.md +25 -0
  26. data/examples/model/ext/build.xml +35 -0
  27. data/examples/model/ext/src/domain/Child.java +192 -0
  28. data/examples/model/ext/src/domain/Dependent.java +29 -0
  29. data/examples/model/ext/src/domain/DomainObject.java +26 -0
  30. data/examples/model/ext/src/domain/Independent.java +83 -0
  31. data/examples/model/ext/src/domain/Parent.java +129 -0
  32. data/examples/model/ext/src/domain/Person.java +14 -0
  33. data/examples/model/lib/model.rb +13 -0
  34. data/examples/model/lib/model/child.rb +13 -0
  35. data/examples/model/lib/model/domain_object.rb +6 -0
  36. data/examples/model/lib/model/independent.rb +11 -0
  37. data/examples/model/lib/model/parent.rb +17 -0
  38. data/jinx.gemspec +22 -0
  39. data/lib/jinx.rb +3 -0
  40. data/lib/jinx/active_support/README.txt +2 -0
  41. data/lib/jinx/active_support/core_ext/string.rb +7 -0
  42. data/lib/jinx/active_support/core_ext/string/inflections.rb +167 -0
  43. data/lib/jinx/active_support/inflections.rb +55 -0
  44. data/lib/jinx/active_support/inflector.rb +398 -0
  45. data/lib/jinx/cli/application.rb +36 -0
  46. data/lib/jinx/cli/command.rb +214 -0
  47. data/lib/jinx/helpers/array.rb +108 -0
  48. data/lib/jinx/helpers/boolean.rb +42 -0
  49. data/lib/jinx/helpers/case_insensitive_hash.rb +39 -0
  50. data/lib/jinx/helpers/class.rb +149 -0
  51. data/lib/jinx/helpers/collection.rb +33 -0
  52. data/lib/jinx/helpers/collections.rb +11 -0
  53. data/lib/jinx/helpers/collector.rb +20 -0
  54. data/lib/jinx/helpers/conditional_enumerator.rb +21 -0
  55. data/lib/jinx/helpers/enumerable.rb +242 -0
  56. data/lib/jinx/helpers/enumerate.rb +35 -0
  57. data/lib/jinx/helpers/error.rb +15 -0
  58. data/lib/jinx/helpers/file_separator.rb +65 -0
  59. data/lib/jinx/helpers/filter.rb +52 -0
  60. data/lib/jinx/helpers/flattener.rb +38 -0
  61. data/lib/jinx/helpers/hash.rb +12 -0
  62. data/lib/jinx/helpers/hashable.rb +502 -0
  63. data/lib/jinx/helpers/inflector.rb +36 -0
  64. data/lib/jinx/helpers/key_transformer_hash.rb +43 -0
  65. data/lib/jinx/helpers/lazy_hash.rb +44 -0
  66. data/lib/jinx/helpers/log.rb +106 -0
  67. data/lib/jinx/helpers/math.rb +12 -0
  68. data/lib/jinx/helpers/merge.rb +60 -0
  69. data/lib/jinx/helpers/module.rb +18 -0
  70. data/lib/jinx/helpers/multi_enumerator.rb +31 -0
  71. data/lib/jinx/helpers/options.rb +92 -0
  72. data/lib/jinx/helpers/os.rb +19 -0
  73. data/lib/jinx/helpers/partial_order.rb +37 -0
  74. data/lib/jinx/helpers/pretty_print.rb +207 -0
  75. data/lib/jinx/helpers/set.rb +8 -0
  76. data/lib/jinx/helpers/stopwatch.rb +76 -0
  77. data/lib/jinx/helpers/transformer.rb +24 -0
  78. data/lib/jinx/helpers/transitive_closure.rb +55 -0
  79. data/lib/jinx/helpers/uniquifier.rb +50 -0
  80. data/lib/jinx/helpers/validation.rb +33 -0
  81. data/lib/jinx/helpers/visitor.rb +370 -0
  82. data/lib/jinx/import/class_path_modifier.rb +77 -0
  83. data/lib/jinx/import/java.rb +337 -0
  84. data/lib/jinx/importer.rb +240 -0
  85. data/lib/jinx/metadata.rb +155 -0
  86. data/lib/jinx/metadata/attribute_enumerator.rb +73 -0
  87. data/lib/jinx/metadata/dependency.rb +244 -0
  88. data/lib/jinx/metadata/id_alias.rb +23 -0
  89. data/lib/jinx/metadata/introspector.rb +179 -0
  90. data/lib/jinx/metadata/inverse.rb +170 -0
  91. data/lib/jinx/metadata/java_property.rb +169 -0
  92. data/lib/jinx/metadata/propertied.rb +500 -0
  93. data/lib/jinx/metadata/property.rb +401 -0
  94. data/lib/jinx/metadata/property_characteristics.rb +114 -0
  95. data/lib/jinx/resource.rb +862 -0
  96. data/lib/jinx/resource/copy_visitor.rb +36 -0
  97. data/lib/jinx/resource/inversible.rb +90 -0
  98. data/lib/jinx/resource/match_visitor.rb +180 -0
  99. data/lib/jinx/resource/matcher.rb +20 -0
  100. data/lib/jinx/resource/merge_visitor.rb +73 -0
  101. data/lib/jinx/resource/mergeable.rb +185 -0
  102. data/lib/jinx/resource/reference_enumerator.rb +49 -0
  103. data/lib/jinx/resource/reference_path_visitor.rb +38 -0
  104. data/lib/jinx/resource/reference_visitor.rb +55 -0
  105. data/lib/jinx/resource/unique.rb +35 -0
  106. data/lib/jinx/version.rb +3 -0
  107. data/spec/defaults_spec.rb +30 -0
  108. data/spec/definitions/model/alias/child.rb +5 -0
  109. data/spec/definitions/model/base/child.rb +5 -0
  110. data/spec/definitions/model/base/domain_object.rb +5 -0
  111. data/spec/definitions/model/base/independent.rb +5 -0
  112. data/spec/definitions/model/defaults/child.rb +5 -0
  113. data/spec/definitions/model/dependency/child.rb +5 -0
  114. data/spec/definitions/model/dependency/parent.rb +6 -0
  115. data/spec/definitions/model/inverse/child.rb +5 -0
  116. data/spec/definitions/model/inverse/independent.rb +5 -0
  117. data/spec/definitions/model/inverse/parent.rb +5 -0
  118. data/spec/definitions/model/mandatory/child.rb +6 -0
  119. data/spec/dependency_spec.rb +47 -0
  120. data/spec/family_spec.rb +64 -0
  121. data/spec/inverse_spec.rb +53 -0
  122. data/spec/mandatory_spec.rb +43 -0
  123. data/spec/metadata_spec.rb +68 -0
  124. data/spec/resource_spec.rb +30 -0
  125. data/spec/spec_helper.rb +3 -0
  126. data/spec/support/model.rb +19 -0
  127. data/test/fixtures/line_separator/cr_line_sep.txt +1 -0
  128. data/test/fixtures/line_separator/crlf_line_sep.txt +3 -0
  129. data/test/fixtures/line_separator/lf_line_sep.txt +3 -0
  130. data/test/fixtures/mixed/ext/build.xml +35 -0
  131. data/test/fixtures/mixed/ext/src/mixed/Case/Example.java +5 -0
  132. data/test/helper.rb +7 -0
  133. data/test/lib/jinx/command_test.rb +41 -0
  134. data/test/lib/jinx/helpers/boolean_test.rb +27 -0
  135. data/test/lib/jinx/helpers/class_test.rb +60 -0
  136. data/test/lib/jinx/helpers/collections_test.rb +402 -0
  137. data/test/lib/jinx/helpers/file_separator_test.rb +29 -0
  138. data/test/lib/jinx/helpers/inflector_test.rb +11 -0
  139. data/test/lib/jinx/helpers/lazy_hash_test.rb +32 -0
  140. data/test/lib/jinx/helpers/module_test.rb +24 -0
  141. data/test/lib/jinx/helpers/options_test.rb +66 -0
  142. data/test/lib/jinx/helpers/partial_order_test.rb +41 -0
  143. data/test/lib/jinx/helpers/pretty_print_test.rb +83 -0
  144. data/test/lib/jinx/helpers/stopwatch_test.rb +16 -0
  145. data/test/lib/jinx/helpers/transitive_closure_test.rb +80 -0
  146. data/test/lib/jinx/helpers/visitor_test.rb +288 -0
  147. data/test/lib/jinx/import/java_test.rb +78 -0
  148. data/test/lib/jinx/import/mixed_case_test.rb +16 -0
  149. metadata +272 -0
@@ -0,0 +1,49 @@
1
+ require 'enumerator'
2
+ require 'generator'
3
+ require 'jinx/helpers/options'
4
+ require 'jinx/helpers/collections'
5
+
6
+ require 'jinx/helpers/validation'
7
+ require 'jinx/helpers/visitor'
8
+ require 'jinx/helpers/math'
9
+
10
+ module Jinx
11
+ # A ReferenceEnumerator iterates over domain property references.
12
+ class ReferenceEnumerator
13
+ include Enumerable
14
+
15
+ # @return [Resource] the domain object containing the references
16
+ attr_reader :subject
17
+
18
+ alias :on :subject
19
+
20
+ alias :from :subject
21
+
22
+ # @return [<Property>] the current property
23
+ attr_reader :property
24
+
25
+ # @param [Resource, nil] on the object containing the references
26
+ # @param [<Property>, Property, nil] properties the property or properties to dereference
27
+ def initialize(on=nil, properties=nil)
28
+ @subject = on
29
+ @properties = properties
30
+ end
31
+
32
+ # @param [Resource] obj the visiting domain object
33
+ # @return [(Resource, Resource, Property)] the (visited, visiting, property) tuples
34
+ # @yield [obj, from, property] operates on the visited domain object
35
+ # @yieldparam [Resource] obj the visited domain object
36
+ # @yieldparam [Resource] from the visiting domain object
37
+ # @yieldparam [Property] property the visiting property
38
+ def each
39
+ return if @subject.nil?
40
+ @properties.enumerate do |prop|
41
+ @property = prop
42
+ # the reference(s) to visit
43
+ refs = @subject.send(prop.attribute)
44
+ # associate each reference to visit with the current visited attribute
45
+ refs.enumerate { |ref| yield(ref) }
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,38 @@
1
+ require 'jinx/helpers/collections'
2
+
3
+ require 'jinx/helpers/validation'
4
+ require 'jinx/helpers/visitor'
5
+ require 'jinx/helpers/math'
6
+
7
+ module Jinx
8
+ # A ReferencePathVisitor traverses an attribute path.
9
+ #
10
+ # For example, given the attributes:
11
+ # favorites : Person -> Book
12
+ # authors : Book -> Author
13
+ # publications : Author -> Book
14
+ # then a path visitor given by:
15
+ # ReferencePathVisitor.new(Person, [:favorites, :authors, :publications])
16
+ # visits the transitive closure of books published by the authors of a person's favorite books.
17
+ class ReferencePathVisitor < ReferenceVisitor
18
+ # @return [ReferenceVisitor] a visitor which traverses the given path attributes starting at
19
+ # an instance of the given type
20
+ #
21
+ # @param [Class] the type of object to begin the traversal
22
+ # @param [<Symbol>] the attributes to traverse
23
+ # @param opts (see ReferenceVisitor#initialize)
24
+ def initialize(klass, attributes, opts=nil)
25
+ # augment the attributes path as a [class, attribute] path
26
+ path = klass.property_path(*attributes)
27
+ # make the visitor
28
+ super(opts) do |ref|
29
+ # Collect the path attributes whose type is the ref type up to the
30
+ # next position in the path.
31
+ max = lineage.size.min(path.size)
32
+ pas = (0...max).map { |i| path[i].attribute if path[i].declarer === ref }
33
+ pas.compact!
34
+ ref.class.attribute_filter(pas)
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,55 @@
1
+ require 'enumerator'
2
+ require 'generator'
3
+ require 'jinx/helpers/options'
4
+ require 'jinx/helpers/collections'
5
+
6
+ require 'jinx/helpers/validation'
7
+ require 'jinx/helpers/visitor'
8
+ require 'jinx/helpers/math'
9
+
10
+ module Jinx
11
+ # A ReferenceVisitor traverses reference attributes.
12
+ class ReferenceVisitor < Visitor
13
+ # Creates a new ReferenceVisitor on domain reference attributes.
14
+ #
15
+ # The required selector block given to this initializer determines which attributes to
16
+ # visit. The references to visit next thus consist of the current domain object's selector
17
+ # attributes' values. If the :filter option is set, then the given filter block is applied
18
+ # to the selected attribute references to restrict which domain objects will be visited.
19
+ #
20
+ # @param opts (see Visitor#initialize)
21
+ # @option opts [Proc] :filter an optional filter on the references to visit
22
+ # @yield [obj] returns the {AttributeEnumerator} of attributes to visit next from the
23
+ # current domain object
24
+ # @yieldparam [Resource] obj the current domain object
25
+ def initialize(opts=nil, &selector)
26
+ Jinx.fail(ArgumentError, "Reference visitor missing domain reference selector") unless block_given?
27
+ # the property selector
28
+ @flt_sel = selector
29
+ # the reference filter
30
+ flt = Options.get(:filter, opts)
31
+ # Initialize the Visitor with a reference enumerator which selects the reference
32
+ # attributes and applies the optional filter if necessary.
33
+ @ref_enums = {}
34
+ super do |ref|
35
+ # the reference property filter
36
+ attrs = attributes_to_visit(ref)
37
+ if attrs then
38
+ logger.debug { "#{qp} visiting #{ref} attributes #{attrs.pp_s(:single_line)}..." } if @verbose
39
+ # an enumerator on the reference properties
40
+ enum = ReferenceEnumerator.new(ref, attrs.properties)
41
+ # If there is a reference filter, then apply it to the enum references.
42
+ flt ? enum.filter(&flt) : enum
43
+ end
44
+ end
45
+ end
46
+
47
+ private
48
+
49
+ # @param [Resource] obj the visiting object
50
+ # @return [Propertied::Filter] the attributes to visit
51
+ def attributes_to_visit(obj)
52
+ @flt_sel.call(obj)
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,35 @@
1
+ require 'jinx/helpers/uniquifier'
2
+
3
+ module Jinx
4
+ # The Unique mix-in makes values unique within the scope of a Resource class.
5
+ module Unique
6
+ # Makes the given String value unique in the context of this object's class.
7
+ # @return nil if value is nil
8
+ # Raises TypeError if value is neither nil nor a String.
9
+ def uniquify_value(value)
10
+ unless String === value or value.nil? then
11
+ Jinx.fail(TypeError, "Cannot uniquify #{qp} non-String value #{value}")
12
+ end
13
+ Uniquifier.instance.uniquify(self, value)
14
+ end
15
+
16
+ # Makes the secondary key unique by replacing each String key attribute value
17
+ # with a unique value.
18
+ def uniquify
19
+ uniquify_attributes(self.class.secondary_key_attributes)
20
+ uniquify_attributes(self.class.alternate_key_attributes)
21
+ end
22
+
23
+ # Makes the given attribute values unique by replacing each String value
24
+ # with a unique value.
25
+ def uniquify_attributes(attributes)
26
+ attributes.each do |ka|
27
+ oldval = send(ka)
28
+ next unless String === oldval
29
+ newval = uniquify_value(oldval)
30
+ set_property_value(ka, newval)
31
+ logger.debug { "Reset #{qp} #{ka} from #{oldval} to unique value #{newval}." }
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,3 @@
1
+ module Jinx
2
+ VERSION = "2.1.1"
3
+ end
@@ -0,0 +1,30 @@
1
+ require File.expand_path('spec_helper', File.dirname(__FILE__))
2
+
3
+ module Model
4
+ describe 'Defaults' do
5
+ before(:all) do
6
+ Model.definitions BASE, DEFAULTS
7
+ end
8
+
9
+ it "should recognize the property default" do
10
+ Child.defaults[:cardinal].should be 1
11
+ end
12
+
13
+ it "should set the default property value" do
14
+ c = Child.new
15
+ c.add_defaults
16
+ c.cardinal.should be 1
17
+ end
18
+
19
+ it "should not reset a property value to the default" do
20
+ c = Child.new(:cardinal => 2)
21
+ c.add_defaults
22
+ c.cardinal.should be 2
23
+ end
24
+
25
+ private
26
+
27
+ # The defaults fixture model definitions.
28
+ DEFAULTS = File.dirname(__FILE__) + '/definitions/model/defaults'
29
+ end
30
+ end
@@ -0,0 +1,5 @@
1
+ module Model
2
+ class Child
3
+ property :friends, :alias => :pals
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module Model
2
+ class Child
3
+ property :name, :secondary_key
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module Model
2
+ class DomainObject
3
+ property :identifier, :primary_key
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module Model
2
+ class Independent
3
+ property :others, :type => self
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module Model
2
+ class Child
3
+ property :cardinal, :default => 1
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module Model
2
+ class Child
3
+ property :dependent, :dependent
4
+ end
5
+ end
@@ -0,0 +1,6 @@
1
+ module Model
2
+ class Parent
3
+ property :children, :dependent
4
+ property :dependent, :dependent
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ module Model
2
+ class Child
3
+ property :parent, :inverse => :children
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module Model
2
+ class Independent
3
+ property :others, :inverse => :others
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module Model
2
+ class Parent
3
+ property :spouse, :inverse => :spouse
4
+ end
5
+ end
@@ -0,0 +1,6 @@
1
+ module Model
2
+ class Child
3
+ property :flag, :mandatory
4
+ property :dependent, :autogenerated
5
+ end
6
+ end
@@ -0,0 +1,47 @@
1
+ require File.expand_path('spec_helper', File.dirname(__FILE__))
2
+
3
+ module Model
4
+ describe 'Dependency' do
5
+ before(:all) do
6
+ Model.definitions BASE, DEPENDENCY
7
+ end
8
+
9
+ context '1:1' do
10
+ it "should capture the dependents" do
11
+ d = Dependent.new
12
+ c = Child.new(:dependent => d)
13
+ c.dependents.should include d
14
+ end
15
+ end
16
+
17
+ context '1:N' do
18
+ it "should set the inverses" do
19
+ Child.property(:parent).inverse.should be :children
20
+ Parent.property(:children).inverse.should be :parent
21
+ end
22
+
23
+ it "should capture the dependents" do
24
+ p = Parent.new
25
+ c = Child.new(:parent => p)
26
+ p.dependents.should include c
27
+ end
28
+
29
+ it "should fail to validate a missing owner" do
30
+ c = Child.new
31
+ expect { c.validate }.to raise_error(Jinx::ValidationError)
32
+ end
33
+
34
+ it "should validate an existing owner" do
35
+ p = Parent.new
36
+ c = Child.new(:parent => p, :name => 'Sam')
37
+ expect { c.validate }.to_not raise_error
38
+ end
39
+ end
40
+
41
+ private
42
+
43
+ # The dependency fixture model definitions.
44
+ # @private
45
+ DEPENDENCY = File.dirname(__FILE__) + '/definitions/model/dependency'
46
+ end
47
+ end
@@ -0,0 +1,64 @@
1
+ require File.expand_path('spec_helper', File.dirname(__FILE__))
2
+ require File.dirname(__FILE__) + '/../examples/family/lib/family'
3
+
4
+ module Family
5
+ describe DomainObject do
6
+ it "should set the primary key attribute" do
7
+ DomainObject.primary_key_attributes.should == [:identifier]
8
+ end
9
+ end
10
+
11
+ describe Address do
12
+ it "should have an attribute => value constructor" do
13
+ Address.new(:state => 'OR').state.should == 'OR'
14
+ end
15
+
16
+ it "should recognize an alias" do
17
+ a = Address.new(:postal_code => '95111')
18
+ a.zip.should == a.postal_code
19
+ end
20
+ end
21
+
22
+ describe Parent do
23
+ it "should inherit the primary key" do
24
+ Parent.primary_key_attributes.should be DomainObject.primary_key_attributes
25
+ end
26
+
27
+ it "should have a secondary key" do
28
+ Parent.secondary_key_attributes.should == [:ssn]
29
+ end
30
+
31
+ it "should have a name property" do
32
+ Parent.property_defined?(:name).should be true
33
+ end
34
+
35
+ it "should have a children dependent" do
36
+ Parent.property(:children).dependent?.should be true
37
+ end
38
+ end
39
+
40
+ describe Child do
41
+ it "should have a parents owner" do
42
+ Child.property(:parents).owner?.should be true
43
+ end
44
+
45
+ it "should add itself to the household inverse" do
46
+ h = Household.new
47
+ c = Child.new(:household => h)
48
+ h.members.should include c
49
+ end
50
+
51
+ it "should not add itself to the parents inverse" do
52
+ p = Parent.new
53
+ c = Child.new(:parents => [p])
54
+ p.children.should_not include c
55
+ end
56
+ end
57
+
58
+ describe Household do
59
+ it "should have a dependent address" do
60
+ a = Address.new
61
+ Household.new(:address => a).dependents.should include a
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,53 @@
1
+ require File.expand_path('spec_helper', File.dirname(__FILE__))
2
+
3
+ module Model
4
+ describe 'Inverse' do
5
+ before(:all) do
6
+ Model.definitions BASE, INVERSE
7
+ end
8
+
9
+ context '1:1' do
10
+ it "should set the inverse" do
11
+ Parent.property(:spouse).inverse.should == :spouse
12
+ end
13
+
14
+ it "should set the target inverse type back to self" do
15
+ Parent.property(:spouse).inverse.should == :spouse
16
+ end
17
+
18
+ it "should enforce inverse integrity" do
19
+ m = Parent.new
20
+ f = Parent.new(:spouse => m)
21
+ m.spouse.should be f
22
+ end
23
+ end
24
+
25
+ context '1:N' do
26
+ it "should set the inverse" do
27
+ Child.property(:parent).inverse.should == :children
28
+ end
29
+
30
+ it "should set the target inverse type back to self" do
31
+ Parent.property(:children).inverse.should == :parent
32
+ end
33
+
34
+ it "should enforce inverse integrity" do
35
+ p = Parent.new
36
+ c = Child.new(:parent => p)
37
+ p.children.should include c
38
+ end
39
+ end
40
+
41
+ context 'M:N' do
42
+ it "should set the inverse" do
43
+ Independent.property(:others).inverse.should == :others
44
+ end
45
+ end
46
+
47
+ private
48
+
49
+ # The inverse fixture model definitions.
50
+ # @private
51
+ INVERSE = File.dirname(__FILE__) + '/definitions/model/inverse'
52
+ end
53
+ end