embulk 0.3.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (138) hide show
  1. checksums.yaml +5 -13
  2. data/.travis.yml +16 -0
  3. data/Gemfile +0 -1
  4. data/README.md +37 -19
  5. data/Rakefile +5 -37
  6. data/bin/embulk +1 -1
  7. data/build.gradle +178 -95
  8. data/embulk-core/build.gradle +1 -1
  9. data/embulk-core/src/main/java/org/embulk/command/Runner.java +11 -10
  10. data/embulk-core/src/main/java/org/embulk/config/ConfigDiff.java +26 -0
  11. data/embulk-core/src/main/java/org/embulk/config/ConfigInject.java +14 -0
  12. data/embulk-core/src/main/java/org/embulk/config/DataSourceImpl.java +2 -2
  13. data/embulk-core/src/main/java/org/embulk/config/DataSourceSerDe.java +4 -3
  14. data/embulk-core/src/main/java/org/embulk/config/TaskSerDe.java +5 -3
  15. data/embulk-core/src/main/java/org/embulk/config/TaskValidationException.java +1 -0
  16. data/embulk-core/src/main/java/org/embulk/exec/ExecutionResult.java +6 -6
  17. data/embulk-core/src/main/java/org/embulk/exec/GuessExecutor.java +19 -19
  18. data/embulk-core/src/main/java/org/embulk/exec/LocalExecutor.java +61 -36
  19. data/embulk-core/src/main/java/org/embulk/plugin/InjectedPluginSource.java +4 -0
  20. data/embulk-core/src/main/java/org/embulk/plugin/PluginManager.java +16 -1
  21. data/embulk-core/src/main/java/org/embulk/spi/Column.java +1 -1
  22. data/embulk-core/src/main/java/org/embulk/spi/{SchemaVisitor.java → ColumnVisitor.java} +1 -1
  23. data/embulk-core/src/main/java/org/embulk/spi/Exec.java +3 -3
  24. data/embulk-core/src/main/java/org/embulk/spi/ExecSession.java +2 -2
  25. data/embulk-core/src/main/java/org/embulk/spi/FileInputPlugin.java +3 -3
  26. data/embulk-core/src/main/java/org/embulk/spi/FileInputRunner.java +3 -3
  27. data/embulk-core/src/main/java/org/embulk/spi/FileOutputPlugin.java +3 -3
  28. data/embulk-core/src/main/java/org/embulk/spi/FileOutputRunner.java +3 -3
  29. data/embulk-core/src/main/java/org/embulk/spi/FilterPlugin.java +1 -1
  30. data/embulk-core/src/main/java/org/embulk/spi/GuessPlugin.java +2 -2
  31. data/embulk-core/src/main/java/org/embulk/spi/InputPlugin.java +3 -3
  32. data/embulk-core/src/main/java/org/embulk/spi/OutputPlugin.java +3 -3
  33. data/embulk-core/src/main/java/org/embulk/spi/PluginClassLoader.java +80 -0
  34. data/embulk-core/src/main/java/org/embulk/spi/Schema.java +1 -1
  35. data/embulk-core/src/main/java/org/embulk/spi/time/TimestampFormatter.java +2 -2
  36. data/embulk-core/src/main/java/org/embulk/spi/time/TimestampParser.java +2 -2
  37. data/embulk-core/src/main/java/org/embulk/spi/util/Filters.java +1 -1
  38. data/embulk-core/src/main/java/org/embulk/spi/util/LineEncoder.java +2 -2
  39. data/embulk-core/src/main/java/org/embulk/spi/util/PagePrinter.java +6 -6
  40. data/embulk-core/src/main/java/org/embulk/spi/util/Pages.java +6 -6
  41. data/embulk-core/src/test/java/org/embulk/GuiceBinder.java +1 -1
  42. data/embulk-core/src/test/java/org/embulk/plugin/MockPluginSource.java +1 -0
  43. data/embulk-core/src/test/java/org/embulk/spi/MockFormatterPlugin.java +2 -2
  44. data/embulk-core/src/test/java/org/embulk/spi/PageTestUtils.java +1 -1
  45. data/embulk-core/src/test/java/org/embulk/spi/TestFileInputRunner.java +3 -3
  46. data/embulk-core/src/test/java/org/embulk/spi/TestFileOutputRunner.java +4 -4
  47. data/embulk-docs/Makefile +178 -0
  48. data/embulk-docs/build.gradle +20 -0
  49. data/embulk-docs/make.bat +243 -0
  50. data/embulk-docs/push-gh-pages.sh +29 -0
  51. data/embulk-docs/src/conf.py +260 -0
  52. data/embulk-docs/src/index.rst +19 -0
  53. data/embulk-docs/src/release.rst +14 -0
  54. data/embulk-docs/src/release/release-0.1.0.rst +8 -0
  55. data/embulk-docs/src/release/release-0.2.0.rst +16 -0
  56. data/embulk-docs/src/release/release-0.2.1.rst +19 -0
  57. data/embulk-docs/src/release/release-0.3.0.rst +34 -0
  58. data/embulk-docs/src/release/release-0.3.1.rst +11 -0
  59. data/embulk-docs/src/release/release-0.3.2.rst +15 -0
  60. data/embulk-docs/src/release/release-0.4.0.rst +74 -0
  61. data/embulk-standards/build.gradle +0 -1
  62. data/embulk-standards/src/main/java/org/embulk/standards/CsvFormatterPlugin.java +2 -2
  63. data/embulk-standards/src/main/java/org/embulk/standards/CsvParserPlugin.java +12 -3
  64. data/embulk-standards/src/main/java/org/embulk/standards/GzipFileDecoderPlugin.java +2 -2
  65. data/embulk-standards/src/main/java/org/embulk/standards/LocalFileInputPlugin.java +49 -26
  66. data/embulk-standards/src/main/java/org/embulk/standards/LocalFileOutputPlugin.java +16 -17
  67. data/embulk-standards/src/main/java/org/embulk/standards/NullOutputPlugin.java +4 -4
  68. data/embulk-standards/src/main/java/org/embulk/standards/StandardPluginModule.java +0 -1
  69. data/embulk-standards/src/main/java/org/embulk/standards/StdoutOutputPlugin.java +5 -5
  70. data/gradle/wrapper/gradle-wrapper.jar +0 -0
  71. data/gradle/wrapper/gradle-wrapper.properties +2 -2
  72. data/lib/embulk/buffer.rb +2 -2
  73. data/lib/embulk/column.rb +6 -6
  74. data/lib/embulk/command/embulk_example.rb +1 -1
  75. data/lib/embulk/command/embulk_new_plugin.rb +87 -0
  76. data/lib/embulk/command/embulk_run.rb +84 -26
  77. data/lib/embulk/data/bundle/Gemfile +12 -20
  78. data/lib/embulk/data/bundle/embulk/{filter_example.rb → filter/example.rb} +3 -3
  79. data/lib/embulk/data/bundle/embulk/{input_example.rb → input/example.rb} +3 -3
  80. data/lib/embulk/data/bundle/embulk/{output_example.rb → output/example.rb} +3 -3
  81. data/lib/embulk/data/new/LICENSE.txt +21 -0
  82. data/lib/embulk/data/new/README.md.erb +75 -0
  83. data/lib/embulk/data/new/gitignore.erb +12 -0
  84. data/lib/embulk/data/new/java/build.gradle.erb +57 -0
  85. data/lib/embulk/data/new/java/decoder.java.erb +40 -0
  86. data/lib/embulk/data/new/java/encoder.java.erb +40 -0
  87. data/lib/embulk/data/new/java/file_input.java.erb +64 -0
  88. data/lib/embulk/data/new/java/file_output.java.erb +66 -0
  89. data/lib/embulk/data/new/java/filter.java.erb +47 -0
  90. data/lib/embulk/data/new/java/formatter.java.erb +45 -0
  91. data/lib/embulk/data/new/java/gradle/wrapper/gradle-wrapper.jar +0 -0
  92. data/lib/embulk/data/new/java/gradle/wrapper/gradle-wrapper.properties +6 -0
  93. data/lib/embulk/data/new/java/gradlew +164 -0
  94. data/lib/embulk/data/new/java/gradlew.bat +90 -0
  95. data/lib/embulk/data/new/java/input.java.erb +69 -0
  96. data/lib/embulk/data/new/java/output.java.erb +65 -0
  97. data/lib/embulk/data/new/java/parser.java.erb +51 -0
  98. data/lib/embulk/data/new/java/plugin_loader.rb.erb +3 -0
  99. data/lib/embulk/data/new/java/test.java.erb +5 -0
  100. data/lib/embulk/data/new/ruby/Gemfile +2 -0
  101. data/lib/embulk/data/new/ruby/Rakefile +1 -0
  102. data/lib/embulk/data/new/ruby/filter.rb.erb +39 -0
  103. data/lib/embulk/data/new/ruby/gemspec.erb +19 -0
  104. data/lib/embulk/data/new/ruby/input.rb.erb +47 -0
  105. data/lib/embulk/data/new/ruby/output.rb.erb +59 -0
  106. data/lib/embulk/data/package_data.rb +64 -0
  107. data/lib/embulk/data_source.rb +2 -2
  108. data/lib/embulk/decoder_plugin.rb +27 -0
  109. data/lib/embulk/encoder_plugin.rb +27 -0
  110. data/lib/embulk/error.rb +3 -0
  111. data/lib/embulk/file_input_plugin.rb +27 -0
  112. data/lib/embulk/file_output_plugin.rb +27 -0
  113. data/lib/embulk/filter_plugin.rb +28 -9
  114. data/lib/embulk/formatter_plugin.rb +105 -0
  115. data/lib/embulk/guess_csv.rb +10 -1
  116. data/lib/embulk/guess_plugin.rb +22 -27
  117. data/lib/embulk/input_plugin.rb +34 -20
  118. data/lib/embulk/java/bootstrap.rb +5 -0
  119. data/lib/embulk/java/imports.rb +7 -0
  120. data/lib/embulk/java_plugin.rb +84 -0
  121. data/lib/embulk/output_plugin.rb +35 -19
  122. data/lib/embulk/page.rb +1 -1
  123. data/lib/embulk/page_builder.rb +1 -1
  124. data/lib/embulk/parser_plugin.rb +76 -0
  125. data/lib/embulk/plugin.rb +130 -65
  126. data/lib/embulk/plugin_registry.rb +19 -8
  127. data/lib/embulk/schema.rb +4 -4
  128. data/lib/embulk/version.rb +1 -1
  129. data/settings.gradle +1 -0
  130. metadata +123 -90
  131. data/ChangeLog +0 -46
  132. data/embulk-cli/pom.xml +0 -94
  133. data/embulk-core/pom.xml +0 -148
  134. data/embulk-core/src/main/java/org/embulk/config/NextConfig.java +0 -26
  135. data/embulk-standards/pom.xml +0 -68
  136. data/embulk-standards/src/main/java/org/embulk/standards/S3FileInputPlugin.java +0 -250
  137. data/embulk-standards/src/test/java/org/embulk/standards/TestS3FileInputPlugin.java +0 -43
  138. data/pom.xml +0 -541
@@ -22,6 +22,10 @@ module Embulk
22
22
  @schema = schema
23
23
  @index = index
24
24
  @page_builder = page_builder
25
+ init
26
+ end
27
+
28
+ def init
25
29
  end
26
30
 
27
31
  def run
@@ -29,7 +33,7 @@ module Embulk
29
33
  end
30
34
 
31
35
  if Embulk.java?
32
- def self.java_object
36
+ def self.new_java
33
37
  JavaAdapter.new(self)
34
38
  end
35
39
 
@@ -41,54 +45,64 @@ module Embulk
41
45
  end
42
46
 
43
47
  def transaction(java_config, java_control)
44
- config = DataSource.from_java_object(java_config)
45
- next_config_hash = @ruby_class.transaction(config) do |task_source_hash,columns,processor_count|
46
- java_task_source = DataSource.from_ruby_hash(task_source_hash).java_object
47
- java_schema = Schema.new(columns).java_object
48
+ config = DataSource.from_java(java_config)
49
+ config_diff_hash = @ruby_class.transaction(config) do |task_source_hash,columns,processor_count|
50
+ java_task_source = DataSource.from_ruby_hash(task_source_hash).to_java
51
+ java_schema = Schema.new(columns).to_java
48
52
  java_commit_reports = java_control.run(java_task_source, java_schema, processor_count)
49
53
  java_commit_reports.map {|java_commit_report|
50
- DataSource.from_java_object(java_commit_report)
54
+ DataSource.from_java(java_commit_report)
51
55
  }
52
56
  end
53
57
  # TODO check return type of #transaction
54
- return DataSource.from_ruby_hash(next_config_hash).java_object
58
+ return DataSource.from_ruby_hash(config_diff_hash).to_java
55
59
  end
56
60
 
57
61
  def resume(java_task_source, java_schema, processor_count, java_control)
58
- task_source = DataSource.from_java_object(java_task_source)
59
- schema = Schema.from_java_object(java_schema)
60
- next_config_hash = @ruby_class.resume(task_source, schema, processor_count) do |task_source_hash,columns,processor_count|
61
- java_task_source = DataSource.from_ruby_hash(task_source_hash).java_object
62
- java_schema = Schema.new(columns).java_object
62
+ task_source = DataSource.from_java(java_task_source)
63
+ schema = Schema.from_java(java_schema)
64
+ config_diff_hash = @ruby_class.resume(task_source, schema, processor_count) do |task_source_hash,columns,processor_count|
65
+ java_task_source = DataSource.from_ruby_hash(task_source_hash).to_java
66
+ java_schema = Schema.new(columns).to_java
63
67
  java_commit_reports = java_control.run(java_task_source, java_schema, processor_count)
64
68
  java_commit_reports.map {|java_commit_report|
65
- DataSource.from_java_object(java_commit_report)
69
+ DataSource.from_java(java_commit_report)
66
70
  }
67
71
  end
68
72
  # TODO check return type of #resume
69
- return DataSource.from_ruby_hash(next_config_hash).java_object
73
+ return DataSource.from_ruby_hash(config_diff_hash).to_java
70
74
  end
71
75
 
72
76
  def cleanup(java_task_source, java_schema, processor_count, java_commit_reports)
73
- task_source = DataSource.from_java_object(java_task_source)
74
- schema = Schema.from_java_object(java_schema)
75
- commit_reports = java_commit_reports.map {|c| DataSource.from_java_object(c) }
77
+ task_source = DataSource.from_java(java_task_source)
78
+ schema = Schema.from_java(java_schema)
79
+ commit_reports = java_commit_reports.map {|c| DataSource.from_java(c) }
76
80
  @ruby_class.cleanup(task_source, schema, processor_count, commit_reports)
77
81
  return nil
78
82
  end
79
83
 
80
84
  def run(java_task_source, java_schema, processor_index, java_output)
81
- task_source = DataSource.from_java_object(java_task_source)
82
- schema = Schema.from_java_object(java_schema)
85
+ task_source = DataSource.from_java(java_task_source)
86
+ schema = Schema.from_java(java_schema)
83
87
  page_builder = PageBuilder.new(schema, java_output)
84
88
  begin
85
89
  commit_report_hash = @ruby_class.new(task_source, schema, processor_index, page_builder).run
86
- return DataSource.from_ruby_hash(commit_report_hash).java_object
90
+ return DataSource.from_ruby_hash(commit_report_hash).to_java
87
91
  ensure
88
92
  page_builder.close
89
93
  end
90
94
  end
91
95
  end
96
+
97
+ def self.from_java(java_class)
98
+ JavaPlugin.ruby_adapter_class(java_class, InputPlugin, RubyAdapter)
99
+ end
100
+
101
+ module RubyAdapter
102
+ module ClassMethods
103
+ end
104
+ # TODO
105
+ end
92
106
  end
93
107
  end
94
108
 
@@ -8,5 +8,10 @@ module Embulk
8
8
  # ModelManager
9
9
  # BufferAllocator
10
10
  end
11
+
12
+ def self.injector
13
+ # TODO use org.embulk.spi.Exec.getInjector
14
+ Injector
15
+ end
11
16
  end
12
17
  end
@@ -13,6 +13,10 @@ module Embulk::Java
13
13
  java_import 'org.embulk.spi.OutputPlugin'
14
14
  java_import 'org.embulk.spi.FilterPlugin'
15
15
  java_import 'org.embulk.spi.InputPlugin'
16
+ java_import 'org.embulk.spi.ParserPlugin'
17
+ java_import 'org.embulk.spi.FormatterPlugin'
18
+ java_import 'org.embulk.spi.EncoderPlugin'
19
+ java_import 'org.embulk.spi.DecoderPlugin'
16
20
  java_import 'org.embulk.spi.TransactionalPageOutput'
17
21
  java_import 'org.embulk.spi.PageReader'
18
22
  java_import 'org.embulk.spi.PageBuilder'
@@ -22,6 +26,9 @@ module Embulk::Java
22
26
  java_import 'org.embulk.spi.Column'
23
27
  java_import 'org.embulk.spi.type.Type'
24
28
  java_import 'org.embulk.spi.type.Types'
29
+ java_import 'org.embulk.spi.PluginClassLoader'
30
+ java_import 'org.embulk.spi.FileInputRunner'
31
+ java_import 'org.embulk.spi.FileOutputRunner'
25
32
 
26
33
  # TODO
27
34
  end
@@ -0,0 +1,84 @@
1
+ module Embulk
2
+
3
+ require 'embulk/plugin'
4
+
5
+ class JavaPlugin
6
+ def self.classloader(dir)
7
+ jars = Dir["#{dir}/**/*.jar"]
8
+ urls = jars.map {|jar| java.net.URL.new "file://#{File.expand_path(jar)}" }
9
+ classloader = Java::PluginClassLoader.new(JRuby.runtime, urls)
10
+ end
11
+
12
+ def self.register_input(name, class_fqdn, jar_dir)
13
+ java_class = classloader(jar_dir).loadClass(class_fqdn) # TODO handle class not found error
14
+ Plugin.register_java_input(name, java_class)
15
+ end
16
+
17
+ def self.register_output(name, class_fqdn, jar_dir)
18
+ java_class = classloader(jar_dir).loadClass(class_fqdn)
19
+ Plugin.register_java_output(name, java_class)
20
+ end
21
+
22
+ def self.register_filter(name, class_fqdn, jar_dir)
23
+ java_class = classloader(jar_dir).loadClass(class_fqdn)
24
+ Plugin.register_java_filter(name, java_class)
25
+ end
26
+
27
+ def self.register_parser(name, class_fqdn, jar_dir)
28
+ java_class = classloader(jar_dir).loadClass(class_fqdn)
29
+ Plugin.register_java_parser(name, java_class)
30
+ end
31
+
32
+ def self.register_formatter(name, class_fqdn, jar_dir)
33
+ java_class = classloader(jar_dir).loadClass(class_fqdn)
34
+ Plugin.register_java_formatter(name, java_class)
35
+ end
36
+
37
+ def self.register_decoder(name, class_fqdn, jar_dir)
38
+ java_class = classloader(jar_dir).loadClass(class_fqdn)
39
+ Plugin.register_java_decoder(name, java_class)
40
+ end
41
+
42
+ def self.register_encoder(name, class_fqdn, jar_dir)
43
+ java_class = classloader(jar_dir).loadClass(class_fqdn)
44
+ Plugin.register_java_encoder(name, java_class)
45
+ end
46
+
47
+ def self.register_guess(name, class_fqdn, jar_dir)
48
+ java_class = classloader(jar_dir).loadClass(class_fqdn)
49
+ Plugin.register_java_guess(name, java_class)
50
+ end
51
+
52
+ def self.ruby_adapter_class(java_class, ruby_base_class, ruby_module)
53
+ Class.new(ruby_base_class) do
54
+ const_set(:JAVA_CLASS, java_class)
55
+
56
+ include ruby_module
57
+ extend ruby_module::ClassMethods
58
+
59
+ unless method_defined?(:java_object)
60
+ def java_object
61
+ @java_object ||= self.class.new_java
62
+ end
63
+ end
64
+
65
+ unless (class<<self;self;end).method_defined?(:java_class)
66
+ def self.java_class
67
+ self::JAVA_CLASS
68
+ end
69
+ end
70
+
71
+ # TODO ruby_base_class already implements new_java. So
72
+ # this line returns always true:
73
+ #unless (class<<self;self;end).method_defined?(:new_java)
74
+ # but this line could return false unexpectedly if
75
+ # ruby_module::ClassMethods includes other modules.
76
+ unless ruby_module::ClassMethods.method_defined?(:new_java)
77
+ def self.new_java
78
+ Java.injector.getInstance(java_class)
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
@@ -22,10 +22,14 @@ module Embulk
22
22
  @task = task
23
23
  @schema = schema
24
24
  @index = index
25
+ init
25
26
  end
26
27
 
27
28
  attr_reader :task, :schema, :index
28
29
 
30
+ def init
31
+ end
32
+
29
33
  def add(page)
30
34
  raise NotImplementedError, "OutputPlugin#add(page) must be implemented"
31
35
  end
@@ -44,7 +48,7 @@ module Embulk
44
48
  end
45
49
 
46
50
  if Embulk.java?
47
- def self.java_object
51
+ def self.new_java
48
52
  JavaAdapter.new(self)
49
53
  end
50
54
 
@@ -56,44 +60,44 @@ module Embulk
56
60
  end
57
61
 
58
62
  def transaction(java_config, java_schema, processor_count, java_control)
59
- config = DataSource.from_java_object(java_config)
60
- schema = Schema.from_java_object(java_schema)
61
- next_config_hash = @ruby_class.transaction(config, schema, processor_count) do |task_source_hash|
62
- java_task_source = DataSource.from_ruby_hash(task_source_hash).java_object
63
+ config = DataSource.from_java(java_config)
64
+ schema = Schema.from_java(java_schema)
65
+ config_diff_hash = @ruby_class.transaction(config, schema, processor_count) do |task_source_hash|
66
+ java_task_source = DataSource.from_ruby_hash(task_source_hash).to_java
63
67
  java_commit_reports = java_control.run(java_task_source)
64
68
  java_commit_reports.map {|java_commit_report|
65
- DataSource.from_java_object(java_commit_report)
69
+ DataSource.from_java(java_commit_report)
66
70
  }
67
71
  end
68
72
  # TODO check return type of #transaction
69
- return DataSource.from_ruby_hash(next_config_hash).java_object
73
+ return DataSource.from_ruby_hash(config_diff_hash).to_java
70
74
  end
71
75
 
72
76
  def resume(java_task_source, java_schema, processor_count, java_control)
73
- task_source = DataSource.from_java_object(java_task_source)
74
- schema = Schema.from_java_object(java_schema)
75
- next_config_hash = @ruby_class.resume(task_source, schema, processor_count) do |task_source_hash,columns,processor_count|
76
- java_task_source = DataSource.from_ruby_hash(task_source_hash).java_object
77
+ task_source = DataSource.from_java(java_task_source)
78
+ schema = Schema.from_java(java_schema)
79
+ config_diff_hash = @ruby_class.resume(task_source, schema, processor_count) do |task_source_hash,columns,processor_count|
80
+ java_task_source = DataSource.from_ruby_hash(task_source_hash).to_java
77
81
  java_commit_reports = java_control.run(java_task_source)
78
82
  java_commit_reports.map {|java_commit_report|
79
- DataSource.from_java_object(java_commit_report)
83
+ DataSource.from_java(java_commit_report)
80
84
  }
81
85
  end
82
86
  # TODO check return type of #resume
83
- return DataSource.from_ruby_hash(next_config_hash).java_object
87
+ return DataSource.from_ruby_hash(config_diff_hash).to_java
84
88
  end
85
89
 
86
90
  def cleanup(java_task_source, java_schema, processor_count, java_commit_reports)
87
- task_source = DataSource.from_java_object(java_task_source)
88
- schema = Schema.from_java_object(java_schema)
89
- commit_reports = java_commit_reports.map {|c| DataSource.from_java_object(c) }
91
+ task_source = DataSource.from_java(java_task_source)
92
+ schema = Schema.from_java(java_schema)
93
+ commit_reports = java_commit_reports.map {|c| DataSource.from_java(c) }
90
94
  @ruby_class.cleanup(task_source, schema, processor_count, commit_reports)
91
95
  return nil
92
96
  end
93
97
 
94
98
  def open(java_task_source, java_schema, processor_index)
95
- task_source = DataSource.from_java_object(java_task_source)
96
- schema = Schema.from_java_object(java_schema)
99
+ task_source = DataSource.from_java(java_task_source)
100
+ schema = Schema.from_java(java_schema)
97
101
  ruby_object = @ruby_class.new(task_source, schema, processor_index)
98
102
  return OutputAdapter.new(ruby_object, schema)
99
103
  end
@@ -107,6 +111,7 @@ module Embulk
107
111
  end
108
112
 
109
113
  def add(java_page)
114
+ # TODO reuse page reader
110
115
  @ruby_object.add Page.new(java_page, @schema)
111
116
  end
112
117
 
@@ -124,10 +129,21 @@ module Embulk
124
129
 
125
130
  def commit
126
131
  commit_report_hash = @ruby_object.commit
127
- return DataSource.from_ruby_hash(commit_report_hash).java_object
132
+ return DataSource.from_ruby_hash(commit_report_hash).to_java
128
133
  end
129
134
  end
130
135
  end
136
+
137
+ def self.from_java(java_class)
138
+ JavaPlugin.ruby_adapter_class(java_class, OutputPlugin, RubyAdapter)
139
+ end
140
+
141
+ module RubyAdapter
142
+ module ClassMethods
143
+ # TODO transaction, resume, cleanup
144
+ end
145
+ # TODO add, finish, close, abort, commit
146
+ end
131
147
  end
132
148
  end
133
149
 
data/lib/embulk/page.rb CHANGED
@@ -15,7 +15,7 @@ module Embulk
15
15
 
16
16
  def each
17
17
  schema = @schema
18
- reader = Java::PageReader.new(schema.java_object)
18
+ reader = Java::PageReader.new(schema.to_java)
19
19
  begin
20
20
  reader.setPage(@java_page)
21
21
  while reader.nextRecord
@@ -2,7 +2,7 @@ module Embulk
2
2
 
3
3
  class PageBuilder
4
4
  def initialize(schema, java_page_output)
5
- @page_builder = Java::PageBuilder.new(Java::Injected::BufferAllocator, schema.java_object, java_page_output)
5
+ @page_builder = Java::PageBuilder.new(Java::Injected::BufferAllocator, schema.to_java, java_page_output)
6
6
  @schema = schema
7
7
  end
8
8
 
@@ -0,0 +1,76 @@
1
+ module Embulk
2
+
3
+ require 'embulk/data_source'
4
+ require 'embulk/schema'
5
+ require 'embulk/page_builder'
6
+ #require 'embulk/file_input' TODO not implemented
7
+
8
+ class ParserPlugin
9
+ def self.transaction(config, &control)
10
+ raise NotImplementedError, "ParserPlugin.transaction(config, &control) must be implemented"
11
+ end
12
+
13
+ def initialize(task, schema, page_builder)
14
+ @task = task
15
+ @schema = schema
16
+ @page_builder = page_builder
17
+ init
18
+ end
19
+
20
+ def init
21
+ end
22
+
23
+ def run(file_input)
24
+ raise NotImplementedError, "ParserPlugin#run(file_input) must be implemented"
25
+ end
26
+
27
+ if Embulk.java?
28
+ def self.new_java
29
+ JavaAdapter.new(self)
30
+ end
31
+
32
+ class JavaAdapter
33
+ include Java::ParserPlugin
34
+
35
+ def initialize(ruby_class)
36
+ @ruby_class = ruby_class
37
+ end
38
+
39
+ def transaction(java_config, java_control)
40
+ config = DataSource.from_java(java_config)
41
+ @ruby_class.transaction(config) do |task_source_hash,columns|
42
+ java_task_source = DataSource.from_ruby_hash(task_source_hash).to_java
43
+ java_schema = Schema.new(columns).to_java
44
+ java_control.run(java_task_source, java_schema)
45
+ end
46
+ nil
47
+ end
48
+
49
+ def run(java_task_source, java_schema, java_file_input, java_output)
50
+ task_source = DataSource.from_java(java_task_source)
51
+ schema = Schema.from_java(java_schema)
52
+ file_input = FileInput.from_java(java_file_input)
53
+ page_builder = PageBuilder.new(schema, java_output)
54
+ begin
55
+ @ruby_class.new(task_source, schema, page_builder).run(file_input)
56
+ nil
57
+ ensure
58
+ page_builder.close
59
+ # FileInput is closed by FileInputRunner
60
+ end
61
+ end
62
+ end
63
+
64
+ def self.from_java(java_class)
65
+ JavaPlugin.ruby_adapter_class(java_class, ParserPlugin, RubyAdapter)
66
+ end
67
+
68
+ module RubyAdapter
69
+ module ClassMethods
70
+ end
71
+ # TODO
72
+ end
73
+ end
74
+ end
75
+
76
+ end
data/lib/embulk/plugin.rb CHANGED
@@ -4,19 +4,22 @@ module Embulk
4
4
  require 'embulk/error'
5
5
  require 'embulk/plugin_registry'
6
6
  require 'embulk/input_plugin'
7
- require 'embulk/filter_plugin'
7
+ require 'embulk/file_input_plugin'
8
8
  require 'embulk/output_plugin'
9
- #require 'embulk/parser_plugin'
10
- #require 'embulk/formatter_plugin'
11
- #require 'embulk/decoder_plugin'
12
- #require 'embulk/encoder_plugin'
9
+ require 'embulk/file_output_plugin'
10
+ require 'embulk/filter_plugin'
11
+ require 'embulk/parser_plugin'
12
+ require 'embulk/formatter_plugin'
13
+ require 'embulk/decoder_plugin'
14
+ require 'embulk/encoder_plugin'
13
15
  require 'embulk/guess_plugin'
16
+ require 'embulk/java_plugin' if Embulk.java?
14
17
 
15
18
  class PluginManager
16
19
  def initialize
17
20
  @registries = {}
18
21
  %w[input output parser formatter decoder encoder line_filter filter guess].each do |category|
19
- @registries[category.to_sym] = PluginRegistry.new(category, "embulk/#{category}_")
22
+ @registries[category.to_sym] = PluginRegistry.new(category, "embulk/#{category}/")
20
23
  end
21
24
  end
22
25
 
@@ -29,101 +32,150 @@ module Embulk
29
32
  "Output plugin #{klass} must extend OutputPlugin")
30
33
  end
31
34
 
32
- def register_parser(type, klass)
33
- register_plugin(:parser, type, klass, ParserPlugin)
35
+ def register_filter(type, klass)
36
+ register_plugin(:filter, type, klass, FilterPlugin)
34
37
  end
35
38
 
36
- def register_formatter(type, klass)
37
- register_plugin(:formatter, type, klass, FormatterPlugin)
38
- end
39
+ ## TODO FileInput is not implemented yet.
40
+ #def register_parser(type, klass)
41
+ # register_plugin(:parser, type, klass, ParserPlugin)
42
+ #end
39
43
 
40
- def register_decoder(type, klass)
41
- register_plugin(:decoder, type, klass, DecoderPlugin)
42
- end
44
+ ## TODO FileOutput is not implemented yet.
45
+ #def register_formatter(type, klass)
46
+ # register_plugin(:formatter, type, klass, FormatterPlugin)
47
+ #end
43
48
 
44
- def register_encoder(type, klass)
45
- register_plugin(:encoder, type, klass, EncoderPlugin)
46
- end
49
+ ## TODO DecoderPlugin JRuby API is not written by anyone yet
50
+ #def register_decoder(type, klass)
51
+ # register_plugin(:decoder, type, klass, DecoderPlugin)
52
+ #end
47
53
 
48
- def register_filter(type, klass)
49
- register_plugin(:filter, type, klass, FilterPlugin)
50
- end
54
+ ## TODO EncoderPlugin JRuby API is not written by anyone yet
55
+ #def register_encoder(type, klass)
56
+ # register_plugin(:encoder, type, klass, EncoderPlugin)
57
+ #end
51
58
 
52
59
  def register_guess(type, klass)
53
60
  register_plugin(:guess, type, klass, GuessPlugin,
54
61
  "Guess plugin #{klass} must extend GuessPlugin, LineGuessPlugin, or TextGuessPlugin class")
55
62
  end
56
63
 
57
- def get_input(type)
58
- # TODO not implemented yet
64
+ # TODO InputPlugin::RubyAdapter is not written by anyone yet
65
+ #def get_input(type)
66
+ # lookup(:input, type)
67
+ #end
68
+
69
+ # TODO OutputPlugin::RubyAdapter is not written by anyone yet
70
+ #def get_output(type)
71
+ # lookup(:output, type)
72
+ #end
73
+
74
+ # TODO FilterPlugin::RubyAdapter is not written by anyone yet
75
+ #def get_filter(type)
76
+ # lookup(:filter, type)
77
+ #end
78
+
79
+ # TODO FilterPlugin::RubyAdapter is not written by anyone yet
80
+ #def get_parser(type)
81
+ # # TODO not implemented yet
82
+ # lookup(:parser, type)
83
+ #end
84
+
85
+ # TODO FormatterPlugin::RubyAdapter is not written by anyone yet
86
+ #def get_formatter(type)
87
+ # # TODO not implemented yet
88
+ # lookup(:formatter, type)
89
+ #end
90
+
91
+ # TODO DecoderPlugin::RubyAdapter is not written by anyone yet
92
+ #def get_decoder(type)
93
+ # # TODO not implemented yet
94
+ # lookup(:decoder, type)
95
+ #end
96
+
97
+ # TODO EncoderPlugin::RubyAdapter is not written by anyone yet
98
+ #def get_encoder(type)
99
+ # # TODO not implemented yet
100
+ # lookup(:encoder, type)
101
+ #end
102
+
103
+ def get_guess(type)
59
104
  lookup(:guess, type)
60
105
  end
61
106
 
62
- def get_output(type)
63
- # TODO not implemented yet
64
- lookup(:guess, type)
107
+ def register_java_input(type, klass)
108
+ register_java_plugin(:input, type, klass,
109
+ "org.embulk.spi.InputPlugin" => InputPlugin,
110
+ "org.embulk.spi.FileInputPlugin" => FileInputPlugin)
65
111
  end
66
112
 
67
- def get_parser(type)
68
- # TODO not implemented yet
69
- lookup(:guess, type)
113
+ def register_java_output(type, klass)
114
+ register_java_plugin(:output, type, klass,
115
+ "org.embulk.spi.OutputPlugin" => OutputPlugin,
116
+ "org.embulk.spi.FileOutputPlugin" => FileOutputPlugin)
70
117
  end
71
118
 
72
- def get_formatter(type)
73
- # TODO not implemented yet
74
- lookup(:guess, type)
119
+ def register_java_filter(type, klass)
120
+ register_java_plugin(:filter, type, klass,
121
+ "org.embulk.spi.FilterPlugin" => FilterPlugin)
75
122
  end
76
123
 
77
- def get_decoder(type)
78
- # TODO not implemented yet
79
- lookup(:guess, type)
124
+ def register_java_parser(type, klass)
125
+ register_java_plugin(:parser, type, klass,
126
+ "org.embulk.spi.ParserPlugin" => ParserPlugin)
80
127
  end
81
128
 
82
- def get_encoder(type)
83
- # TODO not implemented yet
84
- lookup(:guess, type)
129
+ def register_java_formatter(type, klass)
130
+ register_java_plugin(:formatter, type, klass,
131
+ "org.embulk.spi.FormatterPlugin" => FormatterPlugin)
85
132
  end
86
133
 
87
- def get_filter(type)
88
- # TODO not implemented yet
89
- lookup(:guess, type)
134
+ def register_java_decoder(type, klass)
135
+ register_java_plugin(:decoder, type, klass,
136
+ "org.embulk.spi.DecoderPlugin" => DecoderPlugin)
90
137
  end
91
138
 
92
- def get_guess(type)
93
- # TODO not implemented yet
94
- lookup(:guess, type)
139
+ def register_java_encoder(type, klass)
140
+ register_java_plugin(:encoder, type, klass,
141
+ "org.embulk.spi.EncoderPlugin" => EncoderPlugin)
142
+ end
143
+
144
+ def register_java_guess(type, klass)
145
+ register_java_plugin(:guess, type, klass,
146
+ "org.embulk.spi.GuessPlugin" => GuessPlugin)
95
147
  end
96
148
 
97
149
  def new_java_input(type)
98
- lookup(:input, type).java_object
150
+ lookup(:input, type).new_java
99
151
  end
100
152
 
101
153
  def new_java_output(type)
102
- lookup(:output, type).java_object
154
+ lookup(:output, type).new_java
155
+ end
156
+
157
+ def new_java_filter(type)
158
+ lookup(:filter, type).new_java
103
159
  end
104
160
 
105
161
  def new_java_parser(type)
106
- lookup(:parser, type).java_object
162
+ lookup(:parser, type).new_java
107
163
  end
108
164
 
109
165
  def new_java_formatter(type)
110
- lookup(:formatter, type).java_object
166
+ lookup(:formatter, type).new_java
111
167
  end
112
168
 
113
169
  def new_java_decoder(type)
114
- lookup(:decoder, type).java_object
170
+ lookup(:decoder, type).new_java
115
171
  end
116
172
 
117
173
  def new_java_encoder(type)
118
- lookup(:encoder, type).java_object
119
- end
120
-
121
- def new_java_filter(type)
122
- lookup(:filter, type).java_object
174
+ lookup(:encoder, type).new_java
123
175
  end
124
176
 
125
177
  def new_java_guess(type)
126
- lookup(:guess, type).java_object
178
+ lookup(:guess, type).new_java
127
179
  end
128
180
 
129
181
  private
@@ -136,13 +188,26 @@ module Embulk
136
188
  @registries[category].lookup(type)
137
189
  end
138
190
 
139
- def register_plugin(category, type, klass, iface, message=nil)
140
- unless klass < iface
141
- message ||= "Plugin #{klass} must implement #{iface}"
191
+ def register_plugin(category, type, klass, base_class, message=nil)
192
+ unless klass < base_class
193
+ message ||= "Plugin #{klass} must inherit #{base_class}"
142
194
  raise message
143
195
  end
144
196
  @registries[category].register(type, klass)
145
197
  end
198
+
199
+ def register_java_plugin(category, type, klass, iface_map, message=nil)
200
+ found = iface_map.find do |iface_name,ruby_base_class|
201
+ iface = JRuby.runtime.getJRubyClassLoader.load_class(iface_name)
202
+ iface.isAssignableFrom(klass)
203
+ end
204
+ unless found
205
+ message ||= "Java plugin #{klass} must implement #{iface_map.keys.join(' or ')}"
206
+ raise message
207
+ end
208
+ adapted = found.last.from_java(klass)
209
+ @registries[category].register(type, adapted)
210
+ end
146
211
  end
147
212
 
148
213
  module Plugin
@@ -152,14 +217,14 @@ module Embulk
152
217
  extend Forwardable
153
218
 
154
219
  def_delegators 'INSTANCE',
155
- :register_input, :get_input, :new_java_input,
156
- :register_output, :get_output, :new_java_output,
157
- :register_parser, :get_parser, :new_java_parser,
158
- :register_formatter, :get_formatter, :new_java_formatter,
159
- :register_decoder, :get_decoder, :new_java_decoder,
160
- :register_encoder, :get_encoder, :new_java_encoder,
161
- :register_filter, :get_filter, :new_java_filter,
162
- :register_guess, :get_guess, :new_java_guess
220
+ :register_input, :get_input, :register_java_input, :new_java_input,
221
+ :register_output, :get_output, :register_java_output, :new_java_output,
222
+ :register_filter, :get_filter, :register_java_filter, :new_java_filter,
223
+ :register_parser, :get_parser, :register_java_parser, :new_java_parser,
224
+ :register_formatter, :get_formatter, :register_java_formatter, :new_java_formatter,
225
+ :register_decoder, :get_decoder, :register_java_decoder, :new_java_decoder,
226
+ :register_encoder, :get_encoder, :register_java_encoder, :new_java_encoder,
227
+ :register_guess, :get_guess, :register_java_guess, :new_java_guess
163
228
  end
164
229
  end
165
230
  end