neo4j-wrapper 0.0.1-java

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 (88) hide show
  1. data/Gemfile +10 -0
  2. data/README.rdoc +64 -0
  3. data/lib/db/active_tx_log +1 -0
  4. data/lib/db/index/lucene/node/Person_exact/_0.fdt +0 -0
  5. data/lib/db/index/lucene/node/Person_exact/_0.fdx +0 -0
  6. data/lib/db/index/lucene/node/Person_exact/_0.fnm +1 -0
  7. data/lib/db/index/lucene/node/Person_exact/_0.frq +0 -0
  8. data/lib/db/index/lucene/node/Person_exact/_0.nrm +1 -0
  9. data/lib/db/index/lucene/node/Person_exact/_0.prx +0 -0
  10. data/lib/db/index/lucene/node/Person_exact/_0.tii +0 -0
  11. data/lib/db/index/lucene/node/Person_exact/_0.tis +0 -0
  12. data/lib/db/index/lucene/node/Person_exact/_1.fdt +0 -0
  13. data/lib/db/index/lucene/node/Person_exact/_1.fdx +0 -0
  14. data/lib/db/index/lucene/node/Person_exact/_1.fnm +1 -0
  15. data/lib/db/index/lucene/node/Person_exact/_1.frq +0 -0
  16. data/lib/db/index/lucene/node/Person_exact/_1.nrm +1 -0
  17. data/lib/db/index/lucene/node/Person_exact/_1.prx +0 -0
  18. data/lib/db/index/lucene/node/Person_exact/_1.tii +0 -0
  19. data/lib/db/index/lucene/node/Person_exact/_1.tis +0 -0
  20. data/lib/db/index/lucene/node/Person_exact/_2.fdt +0 -0
  21. data/lib/db/index/lucene/node/Person_exact/_2.fdx +0 -0
  22. data/lib/db/index/lucene/node/Person_exact/_2.fnm +1 -0
  23. data/lib/db/index/lucene/node/Person_exact/_2.frq +0 -0
  24. data/lib/db/index/lucene/node/Person_exact/_2.nrm +1 -0
  25. data/lib/db/index/lucene/node/Person_exact/_2.prx +0 -0
  26. data/lib/db/index/lucene/node/Person_exact/_2.tii +0 -0
  27. data/lib/db/index/lucene/node/Person_exact/_2.tis +0 -0
  28. data/lib/db/index/lucene/node/Person_exact/segments.gen +0 -0
  29. data/lib/db/index/lucene/node/Person_exact/segments_3 +0 -0
  30. data/lib/db/index/lucene-store.db +0 -0
  31. data/lib/db/index/lucene.log.active +0 -0
  32. data/lib/db/index.db +0 -0
  33. data/lib/db/messages.log +826 -0
  34. data/lib/db/neostore +0 -0
  35. data/lib/db/neostore.id +0 -0
  36. data/lib/db/neostore.nodestore.db +0 -0
  37. data/lib/db/neostore.nodestore.db.id +0 -0
  38. data/lib/db/neostore.propertystore.db +0 -0
  39. data/lib/db/neostore.propertystore.db.arrays +0 -0
  40. data/lib/db/neostore.propertystore.db.arrays.id +0 -0
  41. data/lib/db/neostore.propertystore.db.id +0 -0
  42. data/lib/db/neostore.propertystore.db.index +0 -0
  43. data/lib/db/neostore.propertystore.db.index.id +0 -0
  44. data/lib/db/neostore.propertystore.db.index.keys +0 -0
  45. data/lib/db/neostore.propertystore.db.index.keys.id +0 -0
  46. data/lib/db/neostore.propertystore.db.strings +0 -0
  47. data/lib/db/neostore.propertystore.db.strings.id +0 -0
  48. data/lib/db/neostore.relationshipstore.db +0 -0
  49. data/lib/db/neostore.relationshipstore.db.id +0 -0
  50. data/lib/db/neostore.relationshiptypestore.db +0 -0
  51. data/lib/db/neostore.relationshiptypestore.db.id +0 -0
  52. data/lib/db/neostore.relationshiptypestore.db.names +0 -0
  53. data/lib/db/neostore.relationshiptypestore.db.names.id +0 -0
  54. data/lib/db/nioneo_logical.log.active +0 -0
  55. data/lib/db/tm_tx_log.1 +0 -0
  56. data/lib/example.rb +34 -0
  57. data/lib/neo4j/identity_map.rb +109 -0
  58. data/lib/neo4j/node_mixin.rb +74 -0
  59. data/lib/neo4j/relationship_mixin.rb +62 -0
  60. data/lib/neo4j/type_converters/type_converters.rb +333 -0
  61. data/lib/neo4j-wrapper/class_methods.rb +27 -0
  62. data/lib/neo4j-wrapper/find.rb +65 -0
  63. data/lib/neo4j-wrapper/has_n/class_methods.rb +131 -0
  64. data/lib/neo4j-wrapper/has_n/decl_rel.rb +261 -0
  65. data/lib/neo4j-wrapper/has_n/instance_methods.rb +12 -0
  66. data/lib/neo4j-wrapper/has_n/nodes.rb +83 -0
  67. data/lib/neo4j-wrapper/node_mixin/class_methods.rb +53 -0
  68. data/lib/neo4j-wrapper/node_mixin/delegates.rb +140 -0
  69. data/lib/neo4j-wrapper/node_mixin/initialize.rb +43 -0
  70. data/lib/neo4j-wrapper/properties/class_methods.rb +150 -0
  71. data/lib/neo4j-wrapper/relationship_mixin/class_methods.rb +30 -0
  72. data/lib/neo4j-wrapper/relationship_mixin/delegates.rb +110 -0
  73. data/lib/neo4j-wrapper/relationship_mixin/initialize.rb +35 -0
  74. data/lib/neo4j-wrapper/rule/class_methods.rb +204 -0
  75. data/lib/neo4j-wrapper/rule/event_listener.rb +66 -0
  76. data/lib/neo4j-wrapper/rule/functions/count.rb +45 -0
  77. data/lib/neo4j-wrapper/rule/functions/function.rb +76 -0
  78. data/lib/neo4j-wrapper/rule/functions/sum.rb +31 -0
  79. data/lib/neo4j-wrapper/rule/instance_methods.rb +16 -0
  80. data/lib/neo4j-wrapper/rule/neo4j_core_ext/traverser.rb +29 -0
  81. data/lib/neo4j-wrapper/rule/rule.rb +134 -0
  82. data/lib/neo4j-wrapper/rule/rule_node.rb +205 -0
  83. data/lib/neo4j-wrapper/version.rb +5 -0
  84. data/lib/neo4j-wrapper/wrapper.rb +38 -0
  85. data/lib/neo4j-wrapper.rb +35 -0
  86. data/lib/test.rb +61 -0
  87. data/neo4j-wrapper.gemspec +31 -0
  88. metadata +162 -0
data/lib/db/neostore ADDED
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
data/lib/example.rb ADDED
@@ -0,0 +1,34 @@
1
+ require 'rubygems'
2
+ require 'neo4j-wrapper'
3
+
4
+ class Company
5
+ include Neo4j::NodeMixin
6
+ has_n(:employees)
7
+ end
8
+
9
+ class Person
10
+ include Neo4j::NodeMixin
11
+ property :name
12
+ property :age, :size, :type => Fixnum, :index => :exact
13
+ property :description, :index => :fulltext
14
+
15
+ has_one(:best_friend)
16
+ has_n(:employed_by).from(:employees)
17
+ end
18
+
19
+ Neo4j::Transaction.run do
20
+ Person.new(:name => 'jimmy', :age => 35)
21
+ end
22
+
23
+ person = Person.find(:age => (10..42)).first
24
+
25
+ Neo4j::Transaction.run do
26
+ person.best_friend = Person.new
27
+ person.employed_by << Company.new(:name => "Foo ab")
28
+ end
29
+
30
+ company = person.employed_by.find { |p| p[:name] == 'Foo ab' }
31
+ puts "Person #{person.name} employed by #{company[:name]}"
32
+
33
+ company.employees.each {|x| puts x.name}
34
+
@@ -0,0 +1,109 @@
1
+ module Neo4j
2
+
3
+ # = Neo4j Identity Map
4
+ #
5
+ # Ensures that each object gets loaded only once by keeping every loaded
6
+ # object in a map. Looks up objects using the map when referring to them.
7
+ #
8
+ # More information on Identity Map pattern:
9
+ # http://www.martinfowler.com/eaaCatalog/identityMap.html
10
+ #
11
+ # == Configuration
12
+ #
13
+ # In order to enable IdentityMap, set <tt>config.neo4j.identity_map = true</tt>
14
+ # in your <tt>config/application.rb</tt> file. If used outside rails, set Neo4j::Config[:identity_map] = true.
15
+ #
16
+ # IdentityMap is disabled by default and still in development (i.e. use it with care).
17
+ #
18
+ module IdentityMap
19
+
20
+ class << self
21
+ def enabled=(flag)
22
+ Thread.current[:neo4j_identity_map] = flag
23
+ end
24
+
25
+ def enabled
26
+ Thread.current[:neo4j_identity_map] == true
27
+ end
28
+
29
+ alias enabled? enabled
30
+
31
+ def node_repository
32
+ Thread.current[:node_identity_map] ||= java.util.HashMap.new
33
+ end
34
+
35
+ def rel_repository
36
+ Thread.current[:rel_identity_map] ||= java.util.HashMap.new
37
+ end
38
+
39
+ def repository_for(neo_entity)
40
+ return nil unless enabled?
41
+ if neo_entity.class == Neo4j::Node
42
+ node_repository
43
+ elsif neo_entity.class == Neo4j::Relationship
44
+ rel_repository
45
+ else
46
+ nil
47
+ end
48
+ end
49
+
50
+ def use
51
+ old, self.enabled = enabled, true
52
+ yield if block_given?
53
+ ensure
54
+ self.enabled = old
55
+ clear
56
+ end
57
+
58
+ def without
59
+ old, self.enabled = enabled, false
60
+ yield if block_given?
61
+ ensure
62
+ self.enabled = old
63
+ end
64
+
65
+ def get(neo_entity)
66
+ r = repository_for(neo_entity)
67
+ r && r.get(neo_entity.neo_id)
68
+ end
69
+
70
+ def add(neo_entity, wrapped_entity)
71
+ r = repository_for(neo_entity)
72
+ r && r.put(neo_entity.neo_id, wrapped_entity)
73
+ end
74
+
75
+ def remove(neo_entity)
76
+ r = repository_for(neo_entity)
77
+ r && r.remove(neo_entity.neo_id)
78
+ end
79
+
80
+ def remove_node_by_id(node_id)
81
+ node_repository.remove(node_id)
82
+ end
83
+
84
+ def remove_rel_by_id(rel_id)
85
+ rel_repository.remove(rel_id)
86
+ end
87
+
88
+ def clear
89
+ node_repository.clear
90
+ rel_repository.clear
91
+ end
92
+
93
+ def on_after_commit(*)
94
+ clear
95
+ end
96
+
97
+ def on_neo4j_started(db)
98
+ if !Neo4j::Config[:identity_map] && !enabled
99
+ db.event_handler.remove(self)
100
+ end
101
+ end
102
+
103
+ end
104
+
105
+ end
106
+ end
107
+
108
+ Neo4j.unstarted_db.event_handler.add(Neo4j::IdentityMap)
109
+
@@ -0,0 +1,74 @@
1
+ module Neo4j
2
+
3
+ # This mixin is used to wrap Neo4j Java Nodes in Ruby objects.
4
+ #
5
+ # @example Declare and Use a Lucene Index
6
+ #
7
+ # class Contact
8
+ # include Neo4j::NodeMixin
9
+ # property :phone, :index => :exact
10
+ # end
11
+ #
12
+ # # Find an contact with a phone number
13
+ # Contact.find('phone: 12345').first #=> a phone object !
14
+ #
15
+ #
16
+ # = Class Method Modules
17
+ # * {Neo4j::Wrapper::ClassMethods}
18
+ # * {Neo4j::Wrapper::NodeMixin::ClassMethods}
19
+ # * {Neo4j::Wrapper::Property::ClassMethods}
20
+ # * {Neo4j::Wrapper::HasN::ClassMethods}
21
+ # * {Neo4j::Wrapper::Find}
22
+ # * {Neo4j::Wrapper::Rule::ClassMethods}
23
+ # * {http://rdoc.info/github/andreasronge/neo4j-core/master/Neo4j/Core/Index/ClassMethods Neo4j::Core::Index::ClassMethods}
24
+ #
25
+ # = Instance Method Modules
26
+ # * {http://rdoc.info/github/andreasronge/neo4j-core/master/Neo4j/Core/Index Neo4j::Core::Index}
27
+ module NodeMixin
28
+ include Neo4j::Wrapper::NodeMixin::Delegates
29
+ include Neo4j::Wrapper::NodeMixin::Initialize
30
+ include Neo4j::Wrapper::HasN::InstanceMethods
31
+ include Neo4j::Wrapper::Rule::InstanceMethods
32
+ include Neo4j::Core::Index
33
+
34
+ # @private
35
+ def self.included(klass)
36
+ klass.extend Neo4j::Wrapper::ClassMethods
37
+ klass.extend Neo4j::Wrapper::NodeMixin::ClassMethods
38
+ klass.extend Neo4j::Wrapper::Property::ClassMethods
39
+ klass.extend Neo4j::Wrapper::HasN::ClassMethods
40
+ klass.extend Neo4j::Core::Index::ClassMethods
41
+ klass.extend Neo4j::Wrapper::Find
42
+ klass.extend Neo4j::Wrapper::Rule::ClassMethods
43
+
44
+ klass.send(:include, Neo4j::Wrapper::Rule::Functions)
45
+
46
+
47
+ klass.node_indexer do
48
+ index_names :exact => "#{klass._index_name}_exact", :fulltext => "#{klass._index_name}_fulltext"
49
+ trigger_on :_classname => klass.to_s
50
+ prefix_index_name &klass.method(:index_prefix)
51
+ end
52
+
53
+ def klass.inherited(sub_klass)
54
+ return super if sub_klass.to_s == self.to_s
55
+ base_class = self
56
+
57
+ # make the base class trigger on the sub class nodes
58
+ base_class._indexer.config.trigger_on :_classname => sub_klass.to_s
59
+
60
+ sub_klass.inherit_rules_from self
61
+
62
+ sub_klass.node_indexer do
63
+ inherit_from base_class
64
+ index_names :exact => "#{sub_klass._index_name}_exact", :fulltext => "#{sub_klass._index_name}_fulltext"
65
+ trigger_on :_classname => sub_klass.to_s
66
+ prefix_index_name &sub_klass.method(:index_prefix)
67
+ end
68
+ super
69
+ end
70
+ super
71
+ end
72
+
73
+ end
74
+ end
@@ -0,0 +1,62 @@
1
+ module Neo4j
2
+ # Use this mixin to wrap Neo4j Relationship Java object.
3
+ # This mixin is similar to Neo4j::NodeMixin which wraps Neo4j::Node Java objects.
4
+ #
5
+ # @example
6
+ # class Friend
7
+ # include Neo4j::RelationshipMixin
8
+ # property :since, :type => Fixnum, :index => :exact
9
+ # property :strength, :type => Float
10
+ # property :location
11
+ # end
12
+ #
13
+ # Friend.new(:knows, node_a, node_b, :strength => 3.14)
14
+ # Friend.find(:strength => (2..5)).first
15
+ #
16
+ # = Class Method Modules
17
+ # * {Neo4j::Wrapper::RelationshipMixin::ClassMethods}
18
+ # * {Neo4j::Wrapper::Property::ClassMethods}
19
+ # * {Neo4j::Core::Index::ClassMethods}
20
+ # * {Neo4j::Wrapper::Find}
21
+ module RelationshipMixin
22
+
23
+ include Neo4j::Wrapper::RelationshipMixin::Initialize
24
+ include Neo4j::Wrapper::RelationshipMixin::Delegates
25
+
26
+ # @private
27
+ def self.included(klass)
28
+ klass.extend Neo4j::Wrapper::ClassMethods
29
+ klass.extend Neo4j::Wrapper::RelationshipMixin::ClassMethods
30
+ klass.extend Neo4j::Wrapper::Property::ClassMethods
31
+ klass.extend Neo4j::Core::Index::ClassMethods
32
+ klass.extend Neo4j::Wrapper::Find
33
+
34
+ index_name = klass.to_s.gsub("::", '_')
35
+
36
+ klass.rel_indexer do
37
+ index_names :exact => "#{index_name}_exact", :fulltext => "#{index_name}_fulltext"
38
+ trigger_on :_classname => klass.to_s
39
+ end
40
+
41
+ def klass.inherited(sub_klass)
42
+ return super if sub_klass.to_s == self.to_s
43
+ index_name = sub_klass.to_s.gsub("::", '_')
44
+ base_class = self
45
+
46
+ # make the base class trigger on the sub class nodes
47
+ base_class._indexer.config.trigger_on :_classname => sub_klass.to_s
48
+
49
+ sub_klass.rel_indexer do
50
+ inherit_from base_class
51
+ index_names :exact => "#{index_name}_exact", :fulltext => "#{index_name}_fulltext"
52
+ trigger_on :_classname => sub_klass.to_s
53
+ end
54
+ super
55
+ end
56
+
57
+ super
58
+
59
+ end
60
+
61
+ end
62
+ end
@@ -0,0 +1,333 @@
1
+ module Neo4j
2
+
3
+ # Responsible for converting values from and to Java Neo4j and Lucene.
4
+ # You can implement your own converter by implementing the method <tt>convert?</tt>, <tt>index_as</tt>
5
+ # <tt>to_java</tt> and <tt>to_ruby</tt> in this module.
6
+ #
7
+ # There are currently three default converters that are triggered when a Time, Date or a DateTime is read or written
8
+ # if there is a type declared for the property.
9
+ #
10
+ # @example writing your own marshalling converter:
11
+ #
12
+ # class Foo
13
+ # include Neo4j::NodeMixin
14
+ # property :thing, :type => MyType
15
+ # end
16
+ #
17
+ # module Neo4j::TypeConverters
18
+ # class MyTypeConverter
19
+ # class << self
20
+ # def convert?(type)
21
+ # type == MyType
22
+ # end
23
+ #
24
+ # def to_java(val)
25
+ # "silly:#{val}"
26
+ # end
27
+ #
28
+ # def to_ruby(val)
29
+ # val.sub(/silly:/, '')
30
+ # end
31
+ #
32
+ # def index_as
33
+ # String
34
+ # end
35
+ # end
36
+ # end
37
+ # end
38
+ #
39
+ module TypeConverters
40
+
41
+ # The default converter to use if there isn't a specific converter for the type
42
+ class DefaultConverter
43
+ class << self
44
+
45
+ def to_java(value)
46
+ value
47
+ end
48
+
49
+ def to_ruby(value)
50
+ value
51
+ end
52
+
53
+ def index_as
54
+ String
55
+ end
56
+ end
57
+ end
58
+
59
+
60
+ class BooleanConverter
61
+ class << self
62
+
63
+ def convert?(class_or_symbol)
64
+ :boolean == class_or_symbol
65
+ end
66
+
67
+ def to_java(value)
68
+ return nil if value.nil?
69
+ !!value && value != '0'
70
+ end
71
+
72
+ def to_ruby(value)
73
+ return nil if value.nil?
74
+ !!value && value != '0'
75
+ end
76
+
77
+ def index_as
78
+ String
79
+ end
80
+ end
81
+
82
+ end
83
+
84
+ class SymbolConverter
85
+ class << self
86
+
87
+ def convert?(class_or_symbol)
88
+ :symbol == class_or_symbol || Symbol == class_or_symbol
89
+ end
90
+
91
+ def to_java(value)
92
+ return nil if value.nil?
93
+ value.to_s
94
+ end
95
+
96
+ def to_ruby(value)
97
+ return nil if value.nil?
98
+ value.to_sym
99
+ end
100
+
101
+ def index_as
102
+ String
103
+ end
104
+
105
+ end
106
+ end
107
+
108
+
109
+ class StringConverter
110
+ class << self
111
+
112
+ def convert?(class_or_symbol)
113
+ [String, :string, :text].include? class_or_symbol
114
+ end
115
+
116
+ def to_java(value)
117
+ return nil if value.nil?
118
+ value.to_s
119
+ end
120
+
121
+ def to_ruby(value)
122
+ return nil if value.nil?
123
+ value.to_s
124
+ end
125
+
126
+ def index_as
127
+ String
128
+ end
129
+
130
+ end
131
+ end
132
+
133
+
134
+
135
+ class FixnumConverter
136
+ class << self
137
+
138
+ def convert?(class_or_symbol)
139
+ Fixnum == class_or_symbol || :fixnum == class_or_symbol || :numeric == class_or_symbol
140
+ end
141
+
142
+ def to_java(value)
143
+ return nil if value.nil?
144
+ value.to_i
145
+ end
146
+
147
+ def to_ruby(value)
148
+ return nil if value.nil?
149
+ value.to_i
150
+ end
151
+
152
+ def index_as
153
+ Fixnum
154
+ end
155
+
156
+ end
157
+ end
158
+
159
+ class FloatConverter
160
+ class << self
161
+
162
+ def convert?(clazz_or_symbol)
163
+ Float == clazz_or_symbol || :float == clazz_or_symbol
164
+ end
165
+
166
+ def to_java(value)
167
+ return nil if value.nil?
168
+ value.to_f
169
+ end
170
+
171
+ def to_ruby(value)
172
+ return nil if value.nil?
173
+ value.to_f
174
+ end
175
+
176
+ def index_as
177
+ Float
178
+ end
179
+
180
+ end
181
+ end
182
+
183
+ # Converts Date objects to Java long types. Must be timezone UTC.
184
+ class DateConverter
185
+ class << self
186
+
187
+ def convert?(clazz_or_symbol)
188
+ Date == clazz_or_symbol || :date == clazz_or_symbol
189
+ end
190
+
191
+ def to_java(value)
192
+ return nil if value.nil?
193
+ Time.utc(value.year, value.month, value.day).to_i
194
+ end
195
+
196
+ def to_ruby(value)
197
+ return nil if value.nil?
198
+ Time.at(value).utc.to_date
199
+ end
200
+
201
+ def index_as
202
+ Fixnum
203
+ end
204
+
205
+ end
206
+ end
207
+
208
+ # Converts DateTime objects to and from Java long types. Must be timezone UTC.
209
+ class DateTimeConverter
210
+ class << self
211
+
212
+ def convert?(clazz_or_symbol)
213
+ DateTime == clazz_or_symbol || :datetime == clazz_or_symbol
214
+ end
215
+
216
+ # Converts the given DateTime (UTC) value to an Fixnum.
217
+ # Only utc times are supported !
218
+ def to_java(value)
219
+ return nil if value.nil?
220
+ if value.class == Date
221
+ Time.utc(value.year, value.month, value.day, 0, 0, 0).to_i
222
+ else
223
+ Time.utc(value.year, value.month, value.day, value.hour, value.min, value.sec).to_i
224
+ end
225
+ end
226
+
227
+ def to_ruby(value)
228
+ return nil if value.nil?
229
+ t = Time.at(value).utc
230
+ DateTime.civil(t.year, t.month, t.day, t.hour, t.min, t.sec)
231
+ end
232
+
233
+ def index_as
234
+ Fixnum
235
+ end
236
+
237
+ end
238
+ end
239
+
240
+ class TimeConverter
241
+ class << self
242
+
243
+ def convert?(clazz_or_symbol)
244
+ Time == clazz_or_symbol || :time == clazz_or_symbol
245
+ end
246
+
247
+ # Converts the given DateTime (UTC) value to an Fixnum.
248
+ # Only utc times are supported !
249
+ def to_java(value)
250
+ return nil if value.nil?
251
+ if value.class == Date
252
+ Time.utc(value.year, value.month, value.day, 0, 0, 0).to_i
253
+ else
254
+ value.utc.to_i
255
+ end
256
+ end
257
+
258
+ def to_ruby(value)
259
+ return nil if value.nil?
260
+ Time.at(value).utc
261
+ end
262
+
263
+ def index_as
264
+ Fixnum
265
+ end
266
+
267
+ end
268
+ end
269
+
270
+ class << self
271
+
272
+ # Mostly for testing purpose, You can use this method in order to
273
+ # add a converter while the neo4j has already started.
274
+ def converters=(converters)
275
+ @converters = converters
276
+ end
277
+
278
+ # Always returns a converter that handles to_ruby or to_java
279
+ # if +enforce_type+ is set to false then it will raise in case of unknown type
280
+ # otherwise it will return the DefaultConverter.
281
+ def converter(type = nil, enforce_type = true)
282
+ return DefaultConverter unless type
283
+ @converters ||= begin
284
+ Neo4j::TypeConverters.constants.find_all do |c|
285
+ Neo4j::TypeConverters.const_get(c).respond_to?(:convert?)
286
+ end.map do |c|
287
+ Neo4j::TypeConverters.const_get(c)
288
+ end
289
+ end
290
+ found = @converters.find {|c| c.convert?(type) }
291
+ raise "The type #{type.inspect} is unknown. Use one of #{@converters.map{|c| c.name }.join(", ")} or create a custom type converter." if !found && enforce_type
292
+ found or DefaultConverter
293
+ end
294
+
295
+ # Converts the given value to a Java type by using the registered converters.
296
+ # It just looks at the class of the given value unless an attribute name is given.
297
+ def convert(value, attribute = nil, klass = nil, enforce_type = true)
298
+ converter(attribute_type(value, attribute, klass), enforce_type).to_java(value)
299
+ end
300
+
301
+ # Converts the given property (key, value) to Java if there is a type converter for given type.
302
+ # The type must also be declared using Neo4j::NodeMixin#property property_name, :type => clazz
303
+ # If no Converter is defined for this value then it simply returns the given value.
304
+ def to_java(clazz, key, value)
305
+ type = clazz._decl_props[key.to_sym] && clazz._decl_props[key.to_sym][:type]
306
+ converter(type).to_java(value)
307
+ end
308
+
309
+ # Converts the given property (key, value) to Ruby if there is a type converter for given type.
310
+ # If no Converter is defined for this value then it simply returns the given value.
311
+ def to_ruby(clazz, key, value)
312
+ type = clazz._decl_props[key.to_sym] && clazz._decl_props[key.to_sym][:type]
313
+ converter(type).to_ruby(value)
314
+ end
315
+
316
+ private
317
+ def attribute_type(value, attribute = nil, klass = nil)
318
+ type = (attribute && klass) ? attribute_type_from_attribute_and_klass(value, attribute, klass) : nil
319
+ type || attribute_type_from_value(value)
320
+ end
321
+
322
+ def attribute_type_from_attribute_and_klass(value, attribute, klass)
323
+ if klass.respond_to?(:_decl_props)
324
+ (klass._decl_props.has_key?(attribute) && klass._decl_props[attribute][:type]) ? klass._decl_props[attribute][:type] : nil
325
+ end
326
+ end
327
+
328
+ def attribute_type_from_value(value)
329
+ value.class
330
+ end
331
+ end
332
+ end
333
+ end
@@ -0,0 +1,27 @@
1
+ module Neo4j
2
+ # Responsible for loading the correct Ruby wrapper class for the Neo4j Entity
3
+ module Wrapper
4
+ module ClassMethods
5
+ # Loads the wrapper by using the original new method and initialize it
6
+ # @private
7
+ def _load_wrapper(node)
8
+ wrapped_node = self.orig_new
9
+ wrapped_node.init_on_load(node)
10
+ wrapped_node
11
+ end
12
+
13
+ # Creates an alias to the original new method: <tt>orig_new</t>
14
+ # @private
15
+ def self.extended(klass)
16
+ klass.instance_eval do
17
+ class << self
18
+ alias_method :orig_new, :new
19
+ end
20
+ end unless klass.respond_to?(:orig_new)
21
+ super
22
+ end
23
+ end
24
+ end
25
+ end
26
+
27
+