cwyckoff-babel_icious 0.0.4.6 → 0.0.4.7

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/README.rdoc CHANGED
@@ -62,14 +62,62 @@ if the value at "foo/bar" is empty or nil, "foo/bar" will not be translated. Ad
62
62
  will only translate if the value at "foo/bar" begins with a capital "M".
63
63
 
64
64
 
65
- === Translation
65
+ == Customized mappings
66
66
 
67
- Finally, when you want to translate the mappings, simply call:
67
+ === .to
68
68
 
69
- Babelicious::Mapper.translate(:foo, source)
69
+ If your target mapping is conditional, you may use the .to method which takes a block
70
70
 
71
- passing the tag for the mapping and the actual source you want to translate from.
71
+ m.from("foo/bar").to do |value|
72
+ if(value == "baz")
73
+ "value/is/baz"
74
+ else
75
+ "value/is/something/else"
76
+ end
77
+ end
72
78
 
79
+ Note that the .to method must be used in conjunction with .from, which takes a simple string for the source mapping.
73
80
 
74
81
 
75
-
82
+ === .customize
83
+
84
+ If you have a complex mapping and need to customize it in some way, use the .customize method and pass it a block. The block yields the source object for you to manipulate. Let's say you're mapping xml to a hash where the xml source looks like:
85
+
86
+ <event><progress><statuses><status><code>Foo</code><message>Bar</message></status></statuses></progress></event>
87
+
88
+ You need to map statuses so that the output looks like [{"name" => "Foo", "text" => "Bar"}]. Here's how you could customize your mapping:
89
+
90
+ m.map(:from => "event/progress/statuses", :to => "event/status_code").customize do |node|
91
+ res = []
92
+ node.elements.map {|nd| res << {"name" => nd.child_content("code"), "text" => nd.child_content("message")}
93
+ res
94
+ end
95
+
96
+ This mapping would produce:
97
+
98
+ {"event" => {"status_code" => [{"name" => "Foo", "text" => "Bar"}]}}
99
+
100
+ A more common use case is concatenation of nested xml nodes. Given the following xml:
101
+
102
+ <event><institutions><institution>FOO</institution><institution>BAR</institution><institution>BAZ</institution></institutions></event>
103
+
104
+ You could easily concatentate institutions with the following mapping:
105
+
106
+ m.map(:from => "event/institutions", :to => "event/concatenated_institutions").customize do |node|
107
+ node.concatenate_children("|")
108
+ end
109
+
110
+ which would produce
111
+
112
+ {"event" => {"concatenated_institutions" => "FOO|BAR|BAZ"}}
113
+
114
+ (note: 'concatentate' is a convenience method I've added to the libxml XML::Node object)
115
+
116
+
117
+ == Translation
118
+
119
+ Finally, when you want to translate the mappings, simply call:
120
+
121
+ Babelicious::Mapper.translate(:foo, source)
122
+
123
+ passing the tag for the mapping and the actual source you want to translate from.
@@ -15,6 +15,12 @@ module BabeliciousNodeHacks
15
15
  child_arr(child).first.name
16
16
  end
17
17
 
18
+ def elements
19
+ e = []
20
+ self.each_element {|elem| e << elem}
21
+ e
22
+ end
23
+
18
24
  private
19
25
 
20
26
  def child_arr(child)
@@ -8,7 +8,7 @@ module Babelicious
8
8
  eval("Babelicious::#{direction[:from].to_s.capitalize}Map").new(PathTranslator.new(opts[:from]), opts)
9
9
  end
10
10
 
11
- def target(direction, opts={}, &block)
11
+ def target(direction, opts={})
12
12
  eval("Babelicious::#{direction[:to].to_s.capitalize}Map").new(PathTranslator.new(opts[:to]), opts)
13
13
  end
14
14
 
@@ -21,6 +21,11 @@ module Babelicious
21
21
  def direction(dir={})
22
22
  current_target_mapper.direction = @direction = dir
23
23
  end
24
+
25
+ def from(from_str=nil)
26
+ current_target_mapper.register_from(from_str)
27
+ self
28
+ end
24
29
 
25
30
  def map(opts={})
26
31
  current_target_mapper.register_mapping(opts)
@@ -35,6 +40,11 @@ module Babelicious
35
40
  @mapped_targets, @direction = nil, {}
36
41
  end
37
42
 
43
+ def to(&block)
44
+ current_target_mapper.register_to(&block)
45
+ self
46
+ end
47
+
38
48
  def translate(key=nil, source=nil)
39
49
  raise MapperError, "No target mapper exists for key #{key}" unless mappings.has_key?(key)
40
50
 
@@ -1,7 +1,8 @@
1
1
  module Babelicious
2
2
 
3
3
  class BaseMap
4
-
4
+ attr_reader :opts, :path_translator
5
+
5
6
  def map_from(output, source_value)
6
7
  if map_condition?
7
8
  map_output(output, source_value) if map_condition.is_satisfied_by(source_value)
@@ -29,11 +29,7 @@ module Babelicious
29
29
  end
30
30
  end
31
31
 
32
- private
33
-
34
- def source_element(source, element)
35
- source[element.to_sym] || source[element.to_s]
36
- end
32
+ protected
37
33
 
38
34
  def map_output(hash_output, source_value)
39
35
  catch :no_value do
@@ -46,6 +42,12 @@ module Babelicious
46
42
  end
47
43
  end
48
44
  end
45
+
46
+ private
47
+
48
+ def source_element(source, element)
49
+ source[element.to_sym] || source[element.to_s]
50
+ end
49
51
 
50
52
  def map_source_value(source_value)
51
53
  if(@customized_map)
@@ -30,7 +30,7 @@ module Babelicious
30
30
  end
31
31
  end
32
32
 
33
- private
33
+ protected
34
34
 
35
35
  def map_output(xml_output, source_value)
36
36
  @index = @path_translator.last_index
@@ -43,6 +43,8 @@ module Babelicious
43
43
  end
44
44
  end
45
45
 
46
+ private
47
+
46
48
  def populate_nodes(xml_output)
47
49
  return if @index == 0
48
50
 
@@ -64,7 +66,6 @@ module Babelicious
64
66
  if xml_output.root.nil?
65
67
  xml_output.root = XML::Node.new(@path_translator[0])
66
68
  end
67
-
68
69
  end
69
70
 
70
71
  def update_node?(xml_output, source_value)
@@ -5,8 +5,7 @@ module Babelicious
5
5
  include Enumerable
6
6
 
7
7
  def initialize(untranslated_path)
8
- @full_path = untranslated_path
9
- @parsed_path = translate(untranslated_path)
8
+ set_path(untranslated_path)
10
9
  end
11
10
 
12
11
  def [](index)
@@ -25,6 +24,11 @@ module Babelicious
25
24
  @parsed_path.last
26
25
  end
27
26
 
27
+ def set_path(untranslated_path)
28
+ @full_path = untranslated_path
29
+ @parsed_path = translate(untranslated_path)
30
+ end
31
+
28
32
  def size
29
33
  @parsed_path.size
30
34
  end
@@ -23,7 +23,7 @@ module Babelicious
23
23
  filtered_source = source_element.class.filter_source(source) if filtered_source.nil?
24
24
 
25
25
  source_value = source_element.value_from(filtered_source)
26
- target_element.map_from(target, source_value)
26
+ process_target(target, target_element, source_value)
27
27
  end
28
28
  target
29
29
  end
@@ -36,6 +36,20 @@ module Babelicious
36
36
  @mappings.last[1].register_customized(&block)
37
37
  end
38
38
 
39
+ def register_from(from_str)
40
+ raise TargetMapperError, "Please specify a source mapping" if from_str.nil?
41
+ source = MapFactory.source(@direction, {:from => from_str})
42
+
43
+ @mappings << [source]
44
+ end
45
+
46
+ def register_to(&block)
47
+ raise TargetMapperError, "You must call the .from method before customizing the .to method (e.g., m.from(\"foo\").to {|value| ...}" unless @mappings.last
48
+
49
+ target = MapFactory.target(@direction, {:to => '', :to_proc => block})
50
+ @mappings.last << target
51
+ end
52
+
39
53
  def register_mapping(opts={})
40
54
  raise TargetMapperError, "Both :from and :to keys must be set (e.g., {:from => \"foo/bar\", :to => \"bar/foo\")" unless (opts[:from] && opts[:to])
41
55
  target = MapFactory.target(@direction, opts)
@@ -47,6 +61,17 @@ module Babelicious
47
61
  def reset
48
62
  @mappings, @direction = [], nil
49
63
  end
64
+
65
+ private
66
+
67
+ def process_target(target, target_element, source_value)
68
+ if(target_element.opts[:to_proc])
69
+ target_element.path_translator.set_path(target_element.opts[:to_proc].call(source_value))
70
+ target_element.map_from(target, source_value)
71
+ else
72
+ target_element.map_from(target, source_value)
73
+ end
74
+ end
50
75
  end
51
76
  end
52
77
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cwyckoff-babel_icious
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4.6
4
+ version: 0.0.4.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Wyckoff
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-04-24 00:00:00 -07:00
12
+ date: 2009-05-14 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency