neo4j-core 0.0.3-java → 0.0.4-java

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -1,11 +1,11 @@
1
1
  == Neo4j-core {<img src="https://secure.travis-ci.org/andreasronge/neo4j-core.png" />}[http://travis-ci.org/andreasronge/neo4j-core]
2
2
 
3
3
  This gem only contains the JRuby mapping of the Neo4j graph database.
4
- The neo4j.rb gem will be split up into two gems, neo4j-core and neo4j.
4
+ The neo4j.rb gem will be split up into three gems, neo4j-core, {neo4j-wrapper}[http://github.com/andreasronge/neo4j-wrapper] and {neo4j}[http://github.com/andreasronge/neo4j].
5
5
  This gem will be included by neo4j 2.0.0 gem.
6
6
 
7
7
  This gem contains two modules: Neo4j and Neo4j::Core
8
- The Neo4j module is public and the Neo4j::Core(::*) are private modules.
8
+ The Neo4j module is public and the Neo4j::Core(::*) are internal modules.
9
9
 
10
10
  == Documentation
11
11
 
@@ -23,7 +23,7 @@ The Neo4j module is public and the Neo4j::Core(::*) are private modules.
23
23
 
24
24
  == Custom Index
25
25
 
26
- You can create your own indexer
26
+ You can create your own indexer.
27
27
 
28
28
  class MyIndex
29
29
  extend Neo4j::Core::Index::ClassMethods
data/lib/neo4j-core.rb CHANGED
@@ -50,8 +50,6 @@ require 'neo4j-core/node/class_methods'
50
50
 
51
51
  require 'neo4j/transaction'
52
52
 
53
- require 'neo4j/type_converters/type_converters'
54
-
55
53
  require 'neo4j-core/traversal/evaluator'
56
54
  require 'neo4j-core/traversal/filter_predicate'
57
55
  require 'neo4j-core/traversal/prune_evaluator'
@@ -41,7 +41,7 @@ module Neo4j
41
41
  # @return [Neo4j::Core::Index::Indexer] The indexer that should be used to index the given class
42
42
  # @see Neo4j::Core::Index::IndexConfig for possible configuration values in the +config_dsl+ block
43
43
  # @yield evaluated in the a Neo4j::Core::Index::IndexConfig object to configure it.
44
- def node_indexer(config = IndexConfig.new(:node), &config_dsl)
44
+ def node_indexer(config = _config || IndexConfig.new(:node), &config_dsl)
45
45
  config.instance_eval(&config_dsl)
46
46
  indexer(config)
47
47
  end
@@ -51,11 +51,14 @@ module Neo4j
51
51
  #
52
52
  # @param (see #node_indexer)
53
53
  # @return (see #node_indexer)
54
- def rel_indexer(config = IndexConfig.new(:rel), &config_dsl)
54
+ def rel_indexer(config = _config || IndexConfig.new(:rel), &config_dsl)
55
55
  config.instance_eval(&config_dsl)
56
56
  indexer(config)
57
57
  end
58
58
 
59
+ def _config
60
+ @_indexer && @_indexer.config
61
+ end
59
62
 
60
63
  def indexer(index_config)
61
64
  @_indexer ||= IndexerRegistry.instance.register(Indexer.new(index_config))
@@ -16,8 +16,7 @@ module Neo4j
16
16
  # @see Neo4j::Core::Index::ClassMethods#add_index
17
17
  #
18
18
  def add_index(field, value=self[field])
19
- converted_value = Neo4j::TypeConverters.convert(value, field, self.class)
20
- self.class.add_index(wrapped_entity, field.to_s, converted_value)
19
+ self.class.add_index(wrapped_entity, field.to_s, value)
21
20
  end
22
21
 
23
22
  # Removes an index on the given property.
@@ -5,23 +5,25 @@ module Neo4j
5
5
  # Responsible for holding the configuration for one index
6
6
  # Is used in a DSL to configure the index.
7
7
  class IndexConfig
8
- attr_reader :_trigger_on, :_index_names, :entity_type, :_index_type, :_numeric_types, :_decl_type
8
+ attr_reader :_trigger_on, :_index_names, :entity_type, :_index_type, :_field_types
9
9
 
10
10
  # @param [:rel, :node] entity_type the type of index
11
11
  def initialize(entity_type)
12
12
  @entity_type = entity_type
13
13
  @_index_type = {}
14
- @_numeric_types = []
14
+ @_field_types = {}
15
15
  @_trigger_on = {}
16
- @_decl_type = {}
16
+ end
17
+
18
+ def to_s
19
+ "IndexConfig [#@entity_type, _index_type: #{@_index_type.inspect}, _field_types: #{@_field_types.inspect}, _trigger_on: #{@_trigger_on.inspect}]"
17
20
  end
18
21
 
19
22
  def inherit_from(clazz)
20
23
  c = clazz._indexer.config
21
24
  raise "Can't inherit from different index type #{@entity_type} != #{c.entity_type}" if @entity_type != c.entity_type
22
25
  @_index_type.merge!(c._index_type)
23
- @_numeric_types += c._numeric_types
24
- @_decl_type.merge!(c._decl_type)
26
+ @_field_types.merge!(c._field_types)
25
27
  end
26
28
 
27
29
  # Specifies which property and values the index should be triggered on.
@@ -31,11 +33,8 @@ module Neo4j
31
33
  merge_and_to_string(@_trigger_on, hash)
32
34
  end
33
35
 
34
- # Specifies the types of the properties being indexed so that the proper sort order can be applied.
35
- # Used in the Index DSL.
36
- # @see Neo4j::Core::Index::ClassMethods#node_indexer
37
- def decl_type(prop_and_type_hash)
38
- merge_and_to_string(@_decl_type, prop_and_type_hash)
36
+ def field_type(key)
37
+ @_field_types[key.to_s]
39
38
  end
40
39
 
41
40
  # Specifies an index with configuration
@@ -47,14 +46,14 @@ module Neo4j
47
46
 
48
47
  args.uniq.each do |field|
49
48
  @_index_type[field.to_s] = conf[:type] || :exact
50
- @_numeric_types << field.to_s if conf[:numeric] == true
49
+ @_field_types[field.to_s] = conf[:field_type] || String
51
50
  end
52
51
  end
53
52
 
54
- # @return [Class] the specified type of the property or String
53
+ # @return [Class,nil] the specified type of the property or nil
55
54
  # @see #decl_type
56
55
  def decl_type_on(prop)
57
- @_decl_type[prop] || String
56
+ @_field_types[prop]
58
57
  end
59
58
 
60
59
  # @return [true, false] if the props can/should trigger an index operation
@@ -83,7 +82,7 @@ module Neo4j
83
82
 
84
83
  def rm_index_config
85
84
  @_index_type = {}
86
- @_numeric_types = []
85
+ @_field_types = {}
87
86
  end
88
87
 
89
88
  def index_type(field)
@@ -103,7 +102,8 @@ module Neo4j
103
102
  end
104
103
 
105
104
  def numeric?(field)
106
- return true if @_numeric_types.include?(field)
105
+ raise "No index on #{field.inspect}, has fields: #{@field_types.inspect}" unless @_field_types[field]
106
+ @_field_types[field] != String
107
107
  end
108
108
 
109
109
  private
@@ -39,11 +39,7 @@ module Neo4j
39
39
  @query = query
40
40
  @index_config = index_config
41
41
  @params = params
42
-
43
- if params.include?(:sort)
44
- @order = {}
45
- params[:sort].each_pair { |k, v| @order[k] = (v == :desc) }
46
- end
42
+ @order = params[:sort] if params.include?(:sort)
47
43
  end
48
44
 
49
45
  # Implements the Ruby +Enumerable+ interface
@@ -85,30 +81,26 @@ module Neo4j
85
81
  # Performs a range query
86
82
  # Notice that if you don't specify a type when declaring a property a String range query will be performed.
87
83
  #
88
- def between(lower, upper, lower_incusive=false, upper_inclusive=false)
84
+ def between(lower, upper, lower_inclusive=false, upper_inclusive=false)
89
85
  raise "Expected a symbol. Syntax for range queries example: index(:weight).between(a,b)" unless Symbol === @query
90
- # raise "Can't only do range queries on Neo4j::NodeMixin, Neo4j::Model, Neo4j::RelationshipMixin" unless @decl_props
91
- # check that we perform a range query on the same values as we have declared with the property :key, :type => ...
92
- type = @index_config.decl_type_on(@query)
93
- raise "find(#{@query}).between(#{lower}, #{upper}): #{lower} not a #{type}" if type && !type === lower.class
94
- raise "find(#{@query}).between(#{lower}, #{upper}): #{upper} not a #{type}" if type && !type === upper.class
95
-
96
- # Make it possible to convert those values
97
- @query = range_query(@query, lower, upper, lower_incusive, upper_inclusive)
86
+ @query = range_query(@query, lower, upper, lower_inclusive, upper_inclusive)
98
87
  self
99
88
  end
100
89
 
101
- def range_query(field, lower, upper, lower_incusive, upper_inclusive)
102
- lower = TypeConverters.convert(lower)
103
- upper = TypeConverters.convert(upper)
90
+ def range_query(field, lower, upper, lower_inclusive, upper_inclusive)
91
+ type = @index_config.field_type(field)
92
+ raise "no index on field #{field}" unless type
93
+ # check that we perform a range query on the same values as we have declared with the property :key, :type => ...
94
+ raise "find(#{field}).between(#{lower}, #{upper}): #{lower} not a #{type}" unless type == lower.class
95
+ raise "find(#{field}).between(#{lower}, #{upper}): #{upper} not a #{type}" unless type == upper.class
104
96
 
105
97
  case lower
106
98
  when Fixnum
107
- Java::OrgApacheLuceneSearch::NumericRangeQuery.new_long_range(field.to_s, lower, upper, lower_incusive, upper_inclusive)
99
+ Java::OrgApacheLuceneSearch::NumericRangeQuery.new_long_range(field.to_s, lower, upper, lower_inclusive, upper_inclusive)
108
100
  when Float
109
- Java::OrgApacheLuceneSearch::NumericRangeQuery.new_double_range(field.to_s, lower, upper, lower_incusive, upper_inclusive)
101
+ Java::OrgApacheLuceneSearch::NumericRangeQuery.new_double_range(field.to_s, lower, upper, lower_inclusive, upper_inclusive)
110
102
  else
111
- Java::OrgApacheLuceneSearch::TermRangeQuery.new(field.to_s, lower, upper, lower_incusive, upper_inclusive)
103
+ Java::OrgApacheLuceneSearch::TermRangeQuery.new(field.to_s, lower, upper, lower_inclusive, upper_inclusive)
112
104
  end
113
105
  end
114
106
 
@@ -156,19 +148,28 @@ module Neo4j
156
148
  # Sort descending the given fields.
157
149
  # @param [Symbol] fields it should sort
158
150
  def desc(*fields)
159
- @order = fields.inject(@order || {}) { |memo, field| memo[field] = true; memo }
151
+ @order ||= []
152
+ @order += fields.map { |f| [f, :desc] }
160
153
  self
161
154
  end
162
155
 
163
156
  # Sort ascending the given fields.
164
157
  # @param [Symbol] fields it should sort
165
158
  def asc(*fields)
166
- @order = fields.inject(@order || {}) { |memo, field| memo[field] = false; memo }
159
+ @order ||= []
160
+ @order += fields.map { |f| [f, :asc] }
167
161
  self
168
162
  end
169
163
 
170
164
  protected
171
165
 
166
+ def parse_query(query)
167
+ version = Java::OrgApacheLuceneUtil::Version::LUCENE_30
168
+ analyzer = Java::OrgApacheLuceneAnalysisStandard::StandardAnalyzer.new(version)
169
+ parser = Java::org.apache.lucene.queryParser.QueryParser.new(version, 'name', analyzer)
170
+ parser.parse(query)
171
+ end
172
+
172
173
  def build_and_query(query)
173
174
  build_composite_query(@left_and_query.build_query, query, Java::OrgApacheLuceneSearch::BooleanClause::Occur::MUST)
174
175
  end
@@ -179,6 +180,9 @@ module Neo4j
179
180
 
180
181
  def build_not_query(query)
181
182
  right_query = @right_not_query.build_query
183
+ query = parse_query(query) if query.is_a?(String)
184
+ right_query = parse_query(right_query) if right_query.is_a?(String)
185
+
182
186
  composite_query = Java::OrgApacheLuceneSearch::BooleanQuery.new
183
187
  composite_query.add(query, Java::OrgApacheLuceneSearch::BooleanClause::Occur::MUST_NOT)
184
188
  composite_query.add(right_query, Java::OrgApacheLuceneSearch::BooleanClause::Occur::MUST)
@@ -186,31 +190,27 @@ module Neo4j
186
190
  end
187
191
 
188
192
  def build_composite_query(left_query, right_query, operator) #:nodoc:
193
+ left_query = parse_query(left_query) if left_query.is_a?(String)
194
+ right_query = parse_query(right_query) if right_query.is_a?(String)
189
195
  composite_query = Java::OrgApacheLuceneSearch::BooleanQuery.new
190
- version = Java::OrgApacheLuceneUtil::Version::LUCENE_35
191
- analyzer = org.apache.lucene.analysis.standard::StandardAnalyzer.new(version)
192
- parser = Java::org.apache.lucene.queryParser.QueryParser.new(version,'name', analyzer )
193
-
194
- left_query = parser.parse(left_query) if left_query.is_a?(String)
195
- right_query = parser.parse(right_query) if right_query.is_a?(String)
196
-
197
196
  composite_query.add(left_query, operator)
198
197
  composite_query.add(right_query, operator)
199
198
  composite_query
200
199
  end
201
200
 
202
201
  def build_sort_query(query) #:nodoc:
203
- java_sort_fields = @order.keys.inject([]) do |memo, field|
204
- decl_type = @index_config.decl_type_on(field)
202
+ java_sort_fields = @order.inject([]) do |memo, val|
203
+ field = val[0]
204
+ field_type = @index_config.field_type(field)
205
205
  type = case
206
- when Float == decl_type
206
+ when Float == field_type
207
207
  Java::OrgApacheLuceneSearch::SortField::DOUBLE
208
- when Fixnum == decl_type || DateTime == decl_type || Date == decl_type || Time == decl_type
208
+ when Fixnum == field_type
209
209
  Java::OrgApacheLuceneSearch::SortField::LONG
210
210
  else
211
211
  Java::OrgApacheLuceneSearch::SortField::STRING
212
212
  end
213
- memo << Java::OrgApacheLuceneSearch::SortField.new(field.to_s, type, @order[field])
213
+ memo << Java::OrgApacheLuceneSearch::SortField.new(field.to_s, type, val[1] == :desc)
214
214
  end
215
215
  sort = Java::OrgApacheLuceneSearch::Sort.new(*java_sort_fields)
216
216
  Java::OrgNeo4jIndexLucene::QueryContext.new(query).sort(sort)
@@ -220,18 +220,17 @@ module Neo4j
220
220
  and_query = Java::OrgApacheLuceneSearch::BooleanQuery.new
221
221
 
222
222
  query.each_pair do |key, value|
223
- type = @index_config && @index_config[key.to_sym] && @index_config[key.to_sym][:type]
224
- if !type.nil? && type != String
223
+ type = @index_config.field_type(key)
224
+ if type != String
225
225
  if Range === value
226
- and_query.add(range_query(key, value.first, value.last, true, !value.exclude_end?), Java::OrgApacheLuceneIndex::BooleanClause::Occur::MUST)
226
+ and_query.add(range_query(key, value.first, value.last, true, !value.exclude_end?), Java::OrgApacheLuceneSearch::BooleanClause::Occur::MUST)
227
227
  else
228
- and_query.add(range_query(key, value, value, true, true), Java::OrgApacheLuceneIndex::BooleanClause::Occur::MUST)
228
+ and_query.add(range_query(key, value, value, true, true), Java::OrgApacheLuceneSearch::BooleanClause::Occur::MUST)
229
229
  end
230
230
  else
231
- conv_value = type ? TypeConverters.convert(value) : value.to_s
232
- term = Java::OrgApacheLuceneIndex::Term.new(key.to_s, conv_value)
233
- term_query = Java::OrgApacheLuceneIndex::TermQuery.new(term)
234
- and_query.add(term_query, Java::OrgApacheLuceneIndex::BooleanClause::Occur::MUST)
231
+ term = Java::OrgApacheLuceneIndex::Term.new(key.to_s, value.to_s)
232
+ term_query = Java::OrgApacheLuceneSearch::TermQuery.new(term)
233
+ and_query.add(term_query, Java::OrgApacheLuceneSearch::BooleanClause::Occur::MUST)
235
234
  end
236
235
  end
237
236
  and_query
@@ -116,11 +116,11 @@ module Neo4j
116
116
  # @return [Enumerable] of Neo4j::Relationship objects
117
117
  def _rels(dir=:both, *types)
118
118
  if types.size > 1
119
- get_relationships(ToJava.dir_to_java(dir), ToJava.types_to_java(types))
119
+ get_relationships(ToJava.dir_to_java(dir), ToJava.types_to_java(types)).iterator
120
120
  elsif types.size == 1
121
- get_relationships(ToJava.type_to_java(types[0]), ToJava.dir_to_java(dir))
121
+ get_relationships(ToJava.type_to_java(types[0]), ToJava.dir_to_java(dir)).iterator
122
122
  else
123
- get_relationships(ToJava.dir_to_java(dir))
123
+ get_relationships(ToJava.dir_to_java(dir)).iterator
124
124
  end
125
125
  end
126
126
 
@@ -1,5 +1,5 @@
1
1
  module Neo4j
2
2
  module Core
3
- VERSION = "0.0.3"
3
+ VERSION = "0.0.4"
4
4
  end
5
5
  end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: neo4j-core
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.0.3
5
+ version: 0.0.4
6
6
  platform: java
7
7
  authors:
8
8
  - Andreas Ronge
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2012-03-22 00:00:00 Z
13
+ date: 2012-03-26 00:00:00 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: neo4j-community
@@ -45,7 +45,6 @@ files:
45
45
  - lib/neo4j/neo4j.rb~
46
46
  - lib/neo4j/node.rb
47
47
  - lib/neo4j/relationship.rb
48
- - lib/neo4j/type_converters/type_converters.rb
49
48
  - lib/neo4j-core/event_handler.rb
50
49
  - lib/neo4j-core/lazy_map.rb
51
50
  - lib/neo4j-core/database.rb
@@ -1,287 +0,0 @@
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>
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
11
- #
12
- # Example of writing your own marshalling converter:
13
- #
14
- # class Foo
15
- # include Neo4j::NodeMixin
16
- # property :thing, :type => MyType
17
- # end
18
- #
19
- # module Neo4j::TypeConverters
20
- # class MyTypeConverter
21
- # class << self
22
- # def convert?(type)
23
- # type == MyType
24
- # end
25
- #
26
- # def to_java(val)
27
- # "silly:#{val}"
28
- # end
29
- #
30
- # def to_ruby(val)
31
- # val.sub(/silly:/, '')
32
- # end
33
- # end
34
- # end
35
- # end
36
- #
37
- module TypeConverters
38
-
39
- # The default converter to use if there isn't a specific converter for the type
40
- class DefaultConverter
41
- class << self
42
-
43
- def to_java(value)
44
- value
45
- end
46
-
47
- def to_ruby(value)
48
- value
49
- end
50
- end
51
- end
52
-
53
-
54
- class BooleanConverter
55
- class << self
56
-
57
- def convert?(class_or_symbol)
58
- :boolean == class_or_symbol
59
- end
60
-
61
- def to_java(value)
62
- return nil if value.nil?
63
- !!value && value != '0'
64
- end
65
-
66
- def to_ruby(value)
67
- return nil if value.nil?
68
- !!value && value != '0'
69
- end
70
- end
71
- end
72
-
73
- class SymbolConverter
74
- class << self
75
-
76
- def convert?(class_or_symbol)
77
- :symbol == class_or_symbol || Symbol == class_or_symbol
78
- end
79
-
80
- def to_java(value)
81
- return nil if value.nil?
82
- value.to_s
83
- end
84
-
85
- def to_ruby(value)
86
- return nil if value.nil?
87
- value.to_sym
88
- end
89
- end
90
- end
91
-
92
-
93
- class StringConverter
94
- class << self
95
-
96
- def convert?(class_or_symbol)
97
- [String, :string, :text].include? class_or_symbol
98
- end
99
-
100
- def to_java(value)
101
- return nil if value.nil?
102
- value.to_s
103
- end
104
-
105
- def to_ruby(value)
106
- return nil if value.nil?
107
- value.to_s
108
- end
109
- end
110
- end
111
-
112
-
113
-
114
- class FixnumConverter
115
- class << self
116
-
117
- def convert?(class_or_symbol)
118
- Fixnum == class_or_symbol || :fixnum == class_or_symbol || :numeric == class_or_symbol
119
- end
120
-
121
- def to_java(value)
122
- return nil if value.nil?
123
- value.to_i
124
- end
125
-
126
- def to_ruby(value)
127
- return nil if value.nil?
128
- value.to_i
129
- end
130
- end
131
- end
132
-
133
- class FloatConverter
134
- class << self
135
-
136
- def convert?(clazz_or_symbol)
137
- Float == clazz_or_symbol || :float == clazz_or_symbol
138
- end
139
-
140
- def to_java(value)
141
- return nil if value.nil?
142
- value.to_f
143
- end
144
-
145
- def to_ruby(value)
146
- return nil if value.nil?
147
- value.to_f
148
- end
149
- end
150
- end
151
-
152
- # Converts Date objects to Java long types. Must be timezone UTC.
153
- class DateConverter
154
- class << self
155
-
156
- def convert?(clazz_or_symbol)
157
- Date == clazz_or_symbol || :date == clazz_or_symbol
158
- end
159
-
160
- def to_java(value)
161
- return nil if value.nil?
162
- Time.utc(value.year, value.month, value.day).to_i
163
- end
164
-
165
- def to_ruby(value)
166
- return nil if value.nil?
167
- Time.at(value).utc.to_date
168
- end
169
- end
170
- end
171
-
172
- # Converts DateTime objects to and from Java long types. Must be timezone UTC.
173
- class DateTimeConverter
174
- class << self
175
-
176
- def convert?(clazz_or_symbol)
177
- DateTime == clazz_or_symbol || :datetime == clazz_or_symbol
178
- end
179
-
180
- # Converts the given DateTime (UTC) value to an Fixnum.
181
- # Only utc times are supported !
182
- def to_java(value)
183
- return nil if value.nil?
184
- if value.class == Date
185
- Time.utc(value.year, value.month, value.day, 0, 0, 0).to_i
186
- else
187
- Time.utc(value.year, value.month, value.day, value.hour, value.min, value.sec).to_i
188
- end
189
- end
190
-
191
- def to_ruby(value)
192
- return nil if value.nil?
193
- t = Time.at(value).utc
194
- DateTime.civil(t.year, t.month, t.day, t.hour, t.min, t.sec)
195
- end
196
- end
197
- end
198
-
199
- class TimeConverter
200
- class << self
201
-
202
- def convert?(clazz_or_symbol)
203
- Time == clazz_or_symbol || :time == clazz_or_symbol
204
- end
205
-
206
- # Converts the given DateTime (UTC) value to an Fixnum.
207
- # Only utc times are supported !
208
- def to_java(value)
209
- return nil if value.nil?
210
- if value.class == Date
211
- Time.utc(value.year, value.month, value.day, 0, 0, 0).to_i
212
- else
213
- value.utc.to_i
214
- end
215
- end
216
-
217
- def to_ruby(value)
218
- return nil if value.nil?
219
- Time.at(value).utc
220
- end
221
- end
222
- end
223
-
224
- class << self
225
-
226
- # Mostly for testing purpose, You can use this method in order to
227
- # add a converter while the neo4j has already started.
228
- def converters=(converters)
229
- @converters = converters
230
- end
231
-
232
- # Always returns a converter that handles to_ruby or to_java
233
- # if +enforce_type+ is set to false then it will raise in case of unknown type
234
- # otherwise it will return the DefaultConverter.
235
- def converter(type = nil, enforce_type = true)
236
- return DefaultConverter unless type
237
- @converters ||= begin
238
- Neo4j::TypeConverters.constants.find_all do |c|
239
- Neo4j::TypeConverters.const_get(c).respond_to?(:convert?)
240
- end.map do |c|
241
- Neo4j::TypeConverters.const_get(c)
242
- end
243
- end
244
- found = @converters.find {|c| c.convert?(type) }
245
- 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
246
- found or DefaultConverter
247
- end
248
-
249
- # Converts the given value to a Java type by using the registered converters.
250
- # It just looks at the class of the given value unless an attribute name is given.
251
- def convert(value, attribute = nil, klass = nil, enforce_type = true)
252
- converter(attribute_type(value, attribute, klass), enforce_type).to_java(value)
253
- end
254
-
255
- # Converts the given property (key, value) to Java if there is a type converter for given type.
256
- # The type must also be declared using Neo4j::NodeMixin#property property_name, :type => clazz
257
- # If no Converter is defined for this value then it simply returns the given value.
258
- def to_java(clazz, key, value)
259
- type = clazz._decl_props[key.to_sym] && clazz._decl_props[key.to_sym][:type]
260
- converter(type).to_java(value)
261
- end
262
-
263
- # Converts the given property (key, value) to Ruby if there is a type converter for given type.
264
- # If no Converter is defined for this value then it simply returns the given value.
265
- def to_ruby(clazz, key, value)
266
- type = clazz._decl_props[key.to_sym] && clazz._decl_props[key.to_sym][:type]
267
- converter(type).to_ruby(value)
268
- end
269
-
270
- private
271
- def attribute_type(value, attribute = nil, klass = nil)
272
- type = (attribute && klass) ? attribute_type_from_attribute_and_klass(value, attribute, klass) : nil
273
- type || attribute_type_from_value(value)
274
- end
275
-
276
- def attribute_type_from_attribute_and_klass(value, attribute, klass)
277
- if klass.respond_to?(:_decl_props)
278
- (klass._decl_props.has_key?(attribute) && klass._decl_props[attribute][:type]) ? klass._decl_props[attribute][:type] : nil
279
- end
280
- end
281
-
282
- def attribute_type_from_value(value)
283
- value.class
284
- end
285
- end
286
- end
287
- end