neo4j-wrapper 0.0.1-java

Sign up to get free protection for your applications and to get access to all the features.
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
+