embulk 0.1.0

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 (204) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +13 -0
  3. data/Gemfile +3 -0
  4. data/Gemfile.lock +33 -0
  5. data/README.md +117 -0
  6. data/Rakefile +58 -0
  7. data/bin/embulk +63 -0
  8. data/build.gradle +149 -0
  9. data/embulk-cli/build.gradle +6 -0
  10. data/embulk-cli/pom.xml +94 -0
  11. data/embulk-cli/src/main/java/org/embulk/cli/Main.java +15 -0
  12. data/embulk-core/build.gradle +6 -0
  13. data/embulk-core/pom.xml +143 -0
  14. data/embulk-core/src/main/java/org/embulk/EmbulkService.java +39 -0
  15. data/embulk-core/src/main/java/org/embulk/command/Runner.java +199 -0
  16. data/embulk-core/src/main/java/org/embulk/command/TablePrinter.java +119 -0
  17. data/embulk-core/src/main/java/org/embulk/config/CommitReport.java +26 -0
  18. data/embulk-core/src/main/java/org/embulk/config/Config.java +15 -0
  19. data/embulk-core/src/main/java/org/embulk/config/ConfigDefault.java +15 -0
  20. data/embulk-core/src/main/java/org/embulk/config/ConfigException.java +20 -0
  21. data/embulk-core/src/main/java/org/embulk/config/ConfigLoader.java +83 -0
  22. data/embulk-core/src/main/java/org/embulk/config/ConfigSource.java +28 -0
  23. data/embulk-core/src/main/java/org/embulk/config/DataSource.java +35 -0
  24. data/embulk-core/src/main/java/org/embulk/config/DataSourceImpl.java +208 -0
  25. data/embulk-core/src/main/java/org/embulk/config/DataSourceSerDe.java +80 -0
  26. data/embulk-core/src/main/java/org/embulk/config/GenericTypeReference.java +20 -0
  27. data/embulk-core/src/main/java/org/embulk/config/ModelManager.java +125 -0
  28. data/embulk-core/src/main/java/org/embulk/config/NextConfig.java +26 -0
  29. data/embulk-core/src/main/java/org/embulk/config/Task.java +10 -0
  30. data/embulk-core/src/main/java/org/embulk/config/TaskInvocationHandler.java +180 -0
  31. data/embulk-core/src/main/java/org/embulk/config/TaskSerDe.java +343 -0
  32. data/embulk-core/src/main/java/org/embulk/config/TaskSource.java +28 -0
  33. data/embulk-core/src/main/java/org/embulk/config/TaskValidationException.java +37 -0
  34. data/embulk-core/src/main/java/org/embulk/config/TaskValidator.java +24 -0
  35. data/embulk-core/src/main/java/org/embulk/exec/ExecModule.java +45 -0
  36. data/embulk-core/src/main/java/org/embulk/exec/ExecuteInterruptedException.java +10 -0
  37. data/embulk-core/src/main/java/org/embulk/exec/ExecuteResult.java +19 -0
  38. data/embulk-core/src/main/java/org/embulk/exec/ExtensionServiceLoaderModule.java +43 -0
  39. data/embulk-core/src/main/java/org/embulk/exec/ForSystemConfig.java +16 -0
  40. data/embulk-core/src/main/java/org/embulk/exec/GuessExecutor.java +307 -0
  41. data/embulk-core/src/main/java/org/embulk/exec/LocalExecutor.java +274 -0
  42. data/embulk-core/src/main/java/org/embulk/exec/LoggerProvider.java +30 -0
  43. data/embulk-core/src/main/java/org/embulk/exec/NoSampleException.java +10 -0
  44. data/embulk-core/src/main/java/org/embulk/exec/PooledBufferAllocator.java +58 -0
  45. data/embulk-core/src/main/java/org/embulk/exec/PreviewExecutor.java +138 -0
  46. data/embulk-core/src/main/java/org/embulk/exec/PreviewResult.java +27 -0
  47. data/embulk-core/src/main/java/org/embulk/exec/PreviewedNoticeError.java +17 -0
  48. data/embulk-core/src/main/java/org/embulk/exec/SamplingParserPlugin.java +116 -0
  49. data/embulk-core/src/main/java/org/embulk/exec/SystemConfigModule.java +24 -0
  50. data/embulk-core/src/main/java/org/embulk/jruby/JRubyPluginSource.java +69 -0
  51. data/embulk-core/src/main/java/org/embulk/jruby/JRubyScriptingModule.java +100 -0
  52. data/embulk-core/src/main/java/org/embulk/plugin/BuiltinPluginSourceModule.java +17 -0
  53. data/embulk-core/src/main/java/org/embulk/plugin/InjectedPluginSource.java +92 -0
  54. data/embulk-core/src/main/java/org/embulk/plugin/PluginManager.java +34 -0
  55. data/embulk-core/src/main/java/org/embulk/plugin/PluginSource.java +6 -0
  56. data/embulk-core/src/main/java/org/embulk/plugin/PluginSourceNotMatchException.java +19 -0
  57. data/embulk-core/src/main/java/org/embulk/plugin/PluginType.java +47 -0
  58. data/embulk-core/src/main/java/org/embulk/plugin/SetThreadContextClassLoader.java +19 -0
  59. data/embulk-core/src/main/java/org/embulk/spi/Buffer.java +113 -0
  60. data/embulk-core/src/main/java/org/embulk/spi/BufferAllocator.java +8 -0
  61. data/embulk-core/src/main/java/org/embulk/spi/Column.java +92 -0
  62. data/embulk-core/src/main/java/org/embulk/spi/ColumnConfig.java +79 -0
  63. data/embulk-core/src/main/java/org/embulk/spi/DecoderPlugin.java +16 -0
  64. data/embulk-core/src/main/java/org/embulk/spi/EncoderPlugin.java +16 -0
  65. data/embulk-core/src/main/java/org/embulk/spi/Exec.java +76 -0
  66. data/embulk-core/src/main/java/org/embulk/spi/ExecAction.java +6 -0
  67. data/embulk-core/src/main/java/org/embulk/spi/ExecSession.java +105 -0
  68. data/embulk-core/src/main/java/org/embulk/spi/Extension.java +42 -0
  69. data/embulk-core/src/main/java/org/embulk/spi/FileInput.java +11 -0
  70. data/embulk-core/src/main/java/org/embulk/spi/FileInputPlugin.java +19 -0
  71. data/embulk-core/src/main/java/org/embulk/spi/FileInputRunner.java +113 -0
  72. data/embulk-core/src/main/java/org/embulk/spi/FileOutput.java +13 -0
  73. data/embulk-core/src/main/java/org/embulk/spi/FileOutputPlugin.java +20 -0
  74. data/embulk-core/src/main/java/org/embulk/spi/FileOutputRunner.java +167 -0
  75. data/embulk-core/src/main/java/org/embulk/spi/FormatterPlugin.java +18 -0
  76. data/embulk-core/src/main/java/org/embulk/spi/GuessPlugin.java +9 -0
  77. data/embulk-core/src/main/java/org/embulk/spi/InputPlugin.java +20 -0
  78. data/embulk-core/src/main/java/org/embulk/spi/OutputPlugin.java +21 -0
  79. data/embulk-core/src/main/java/org/embulk/spi/Page.java +45 -0
  80. data/embulk-core/src/main/java/org/embulk/spi/PageBuilder.java +327 -0
  81. data/embulk-core/src/main/java/org/embulk/spi/PageFormat.java +47 -0
  82. data/embulk-core/src/main/java/org/embulk/spi/PageOutput.java +11 -0
  83. data/embulk-core/src/main/java/org/embulk/spi/PageReader.java +227 -0
  84. data/embulk-core/src/main/java/org/embulk/spi/ParserPlugin.java +17 -0
  85. data/embulk-core/src/main/java/org/embulk/spi/Schema.java +101 -0
  86. data/embulk-core/src/main/java/org/embulk/spi/SchemaConfig.java +52 -0
  87. data/embulk-core/src/main/java/org/embulk/spi/SchemaVisitor.java +14 -0
  88. data/embulk-core/src/main/java/org/embulk/spi/Transactional.java +10 -0
  89. data/embulk-core/src/main/java/org/embulk/spi/TransactionalFileInput.java +17 -0
  90. data/embulk-core/src/main/java/org/embulk/spi/TransactionalFileOutput.java +19 -0
  91. data/embulk-core/src/main/java/org/embulk/spi/TransactionalPageOutput.java +17 -0
  92. data/embulk-core/src/main/java/org/embulk/spi/time/DateTimeZoneSerDe.java +57 -0
  93. data/embulk-core/src/main/java/org/embulk/spi/time/JRubyTimeParserHelper.java +8 -0
  94. data/embulk-core/src/main/java/org/embulk/spi/time/JRubyTimeParserHelperFactory.java +6 -0
  95. data/embulk-core/src/main/java/org/embulk/spi/time/Timestamp.java +159 -0
  96. data/embulk-core/src/main/java/org/embulk/spi/time/TimestampFormat.java +98 -0
  97. data/embulk-core/src/main/java/org/embulk/spi/time/TimestampFormatter.java +55 -0
  98. data/embulk-core/src/main/java/org/embulk/spi/time/TimestampParseException.java +6 -0
  99. data/embulk-core/src/main/java/org/embulk/spi/time/TimestampParser.java +60 -0
  100. data/embulk-core/src/main/java/org/embulk/spi/time/TimestampSerDe.java +50 -0
  101. data/embulk-core/src/main/java/org/embulk/spi/type/AbstractType.java +55 -0
  102. data/embulk-core/src/main/java/org/embulk/spi/type/BooleanType.java +12 -0
  103. data/embulk-core/src/main/java/org/embulk/spi/type/DoubleType.java +12 -0
  104. data/embulk-core/src/main/java/org/embulk/spi/type/LongType.java +12 -0
  105. data/embulk-core/src/main/java/org/embulk/spi/type/StringType.java +12 -0
  106. data/embulk-core/src/main/java/org/embulk/spi/type/TimestampType.java +39 -0
  107. data/embulk-core/src/main/java/org/embulk/spi/type/Type.java +15 -0
  108. data/embulk-core/src/main/java/org/embulk/spi/type/TypeDeserializer.java +47 -0
  109. data/embulk-core/src/main/java/org/embulk/spi/type/Types.java +14 -0
  110. data/embulk-core/src/main/java/org/embulk/spi/util/CharsetSerDe.java +55 -0
  111. data/embulk-core/src/main/java/org/embulk/spi/util/Decoders.java +81 -0
  112. data/embulk-core/src/main/java/org/embulk/spi/util/Encoders.java +81 -0
  113. data/embulk-core/src/main/java/org/embulk/spi/util/FileInputInputStream.java +110 -0
  114. data/embulk-core/src/main/java/org/embulk/spi/util/FileOutputOutputStream.java +94 -0
  115. data/embulk-core/src/main/java/org/embulk/spi/util/InputStreamFileInput.java +111 -0
  116. data/embulk-core/src/main/java/org/embulk/spi/util/Inputs.java +74 -0
  117. data/embulk-core/src/main/java/org/embulk/spi/util/LineDecoder.java +118 -0
  118. data/embulk-core/src/main/java/org/embulk/spi/util/LineEncoder.java +109 -0
  119. data/embulk-core/src/main/java/org/embulk/spi/util/ListFileInput.java +52 -0
  120. data/embulk-core/src/main/java/org/embulk/spi/util/Newline.java +38 -0
  121. data/embulk-core/src/main/java/org/embulk/spi/util/PagePrinter.java +102 -0
  122. data/embulk-core/src/main/java/org/embulk/spi/util/Pages.java +139 -0
  123. data/embulk-core/src/test/java/org/embulk/EmbulkTestRuntime.java +110 -0
  124. data/embulk-core/src/test/java/org/embulk/GuiceBinder.java +72 -0
  125. data/embulk-core/src/test/java/org/embulk/RandomManager.java +53 -0
  126. data/embulk-core/src/test/java/org/embulk/TestPluginSourceModule.java +23 -0
  127. data/embulk-core/src/test/java/org/embulk/TestUtilityModule.java +17 -0
  128. data/embulk-core/src/test/java/org/embulk/config/TestConfigSource.java +114 -0
  129. data/embulk-core/src/test/java/org/embulk/config/TestTaskSource.java +70 -0
  130. data/embulk-core/src/test/java/org/embulk/plugin/MockPluginSource.java +57 -0
  131. data/embulk-core/src/test/java/org/embulk/plugin/TestPluginType.java +18 -0
  132. data/embulk-core/src/test/java/org/embulk/spi/MockFileOutput.java +63 -0
  133. data/embulk-core/src/test/java/org/embulk/spi/MockFormatterPlugin.java +101 -0
  134. data/embulk-core/src/test/java/org/embulk/spi/MockParserPlugin.java +73 -0
  135. data/embulk-core/src/test/java/org/embulk/spi/PageTestUtils.java +78 -0
  136. data/embulk-core/src/test/java/org/embulk/spi/TestFileInputInputStream.java +67 -0
  137. data/embulk-core/src/test/java/org/embulk/spi/TestFileInputRunner.java +180 -0
  138. data/embulk-core/src/test/java/org/embulk/spi/TestFileOutputRunner.java +192 -0
  139. data/embulk-core/src/test/java/org/embulk/spi/TestInputStreamFileInput.java +188 -0
  140. data/embulk-core/src/test/java/org/embulk/spi/TestPageBuilderReader.java +301 -0
  141. data/embulk-core/src/test/java/org/embulk/spi/time/TestTimestamp.java +116 -0
  142. data/embulk-core/src/test/java/org/embulk/spi/time/TestTimestampFormatterParser.java +52 -0
  143. data/embulk-core/src/test/java/org/embulk/spi/type/TestTypeSerDe.java +45 -0
  144. data/embulk-core/src/test/java/org/embulk/spi/util/TestLineDecoder.java +132 -0
  145. data/embulk-core/src/test/java/org/embulk/spi/util/TestLineEncoder.java +123 -0
  146. data/embulk-standards/build.gradle +6 -0
  147. data/embulk-standards/pom.xml +68 -0
  148. data/embulk-standards/src/main/java/org/embulk/standards/CsvFormatterPlugin.java +158 -0
  149. data/embulk-standards/src/main/java/org/embulk/standards/CsvParserPlugin.java +233 -0
  150. data/embulk-standards/src/main/java/org/embulk/standards/CsvTokenizer.java +355 -0
  151. data/embulk-standards/src/main/java/org/embulk/standards/GzipFileDecoderPlugin.java +55 -0
  152. data/embulk-standards/src/main/java/org/embulk/standards/GzipFileEncoderPlugin.java +39 -0
  153. data/embulk-standards/src/main/java/org/embulk/standards/LocalFileInputPlugin.java +138 -0
  154. data/embulk-standards/src/main/java/org/embulk/standards/LocalFileOutputPlugin.java +128 -0
  155. data/embulk-standards/src/main/java/org/embulk/standards/NullOutputPlugin.java +46 -0
  156. data/embulk-standards/src/main/java/org/embulk/standards/S3FileInputPlugin.java +238 -0
  157. data/embulk-standards/src/main/java/org/embulk/standards/StandardPluginExtension.java +16 -0
  158. data/embulk-standards/src/main/java/org/embulk/standards/StandardPluginModule.java +44 -0
  159. data/embulk-standards/src/main/java/org/embulk/standards/StdoutOutputPlugin.java +71 -0
  160. data/embulk-standards/src/main/resources/META-INF/services/org.embulk.spi.Extension +1 -0
  161. data/embulk-standards/src/test/java/org/embulk/standards/TestCsvParserPlugin.java +69 -0
  162. data/embulk-standards/src/test/java/org/embulk/standards/TestCsvTokenizer.java +291 -0
  163. data/embulk-standards/src/test/java/org/embulk/standards/TestS3FileInputPlugin.java +43 -0
  164. data/embulk.gemspec +27 -0
  165. data/examples/config.yml +34 -0
  166. data/examples/csv/sample.csv.gz +0 -0
  167. data/gradle/wrapper/gradle-wrapper.jar +0 -0
  168. data/gradle/wrapper/gradle-wrapper.properties +6 -0
  169. data/gradlew +164 -0
  170. data/gradlew.bat +90 -0
  171. data/lib/embulk.rb +16 -0
  172. data/lib/embulk/buffer.rb +17 -0
  173. data/lib/embulk/column.rb +47 -0
  174. data/lib/embulk/command/embulk.rb +39 -0
  175. data/lib/embulk/command/embulk_example.rb +32 -0
  176. data/lib/embulk/command/embulk_generate_bin.rb +62 -0
  177. data/lib/embulk/command/embulk_run.rb +243 -0
  178. data/lib/embulk/data/bundle/.bundle/config +3 -0
  179. data/lib/embulk/data/bundle/Gemfile +31 -0
  180. data/lib/embulk/data/bundle/Gemfile.lock +8 -0
  181. data/lib/embulk/data/bundle/embulk/input_example.rb +40 -0
  182. data/lib/embulk/data/bundle/embulk/output_example.rb +51 -0
  183. data/lib/embulk/data_source.rb +66 -0
  184. data/lib/embulk/error.rb +5 -0
  185. data/lib/embulk/guess_charset.rb +26 -0
  186. data/lib/embulk/guess_csv.rb +195 -0
  187. data/lib/embulk/guess_gzip.rb +18 -0
  188. data/lib/embulk/guess_newline.rb +20 -0
  189. data/lib/embulk/guess_plugin.rb +113 -0
  190. data/lib/embulk/input_plugin.rb +53 -0
  191. data/lib/embulk/java/bootstrap.rb +12 -0
  192. data/lib/embulk/java/imports.rb +26 -0
  193. data/lib/embulk/java/time_helper.rb +77 -0
  194. data/lib/embulk/output_plugin.rb +104 -0
  195. data/lib/embulk/page.rb +28 -0
  196. data/lib/embulk/page_builder.rb +22 -0
  197. data/lib/embulk/plugin.rb +152 -0
  198. data/lib/embulk/plugin_registry.rb +70 -0
  199. data/lib/embulk/schema.rb +85 -0
  200. data/lib/embulk/time_format_guess.rb +331 -0
  201. data/lib/embulk/version.rb +3 -0
  202. data/pom.xml +533 -0
  203. data/settings.gradle +5 -0
  204. metadata +370 -0
@@ -0,0 +1,119 @@
1
+ package org.embulk.command;
2
+
3
+ import java.util.List;
4
+ import java.util.ArrayList;
5
+ import java.util.Locale;
6
+ import java.io.PrintStream;
7
+ import java.io.Flushable;
8
+ import java.io.IOException;
9
+
10
+ class TablePrinter
11
+ {
12
+ private static final int SAMPLES = 10;
13
+
14
+ private PrintStream out;
15
+
16
+ private String[] header;
17
+
18
+ private List<Object[]> samples;
19
+ private String format;
20
+ private String border;
21
+
22
+ public TablePrinter(PrintStream out, String... header)
23
+ {
24
+ this.out = out;
25
+ this.header = header;
26
+ this.samples = new ArrayList<Object[]>(SAMPLES);
27
+ samples.add(header);
28
+ }
29
+
30
+ public void add(Object... values) throws IOException
31
+ {
32
+ int min = header.length < values.length ? header.length : values.length;
33
+ Object[] cols = new Object[header.length];
34
+ for(int i=0; i < min; i++) {
35
+ if(values[i] == null) {
36
+ cols[i] = "";
37
+ } else {
38
+ cols[i] = valueToString(values[i]);
39
+ }
40
+ }
41
+ for(int i=min; i < header.length; i++) {
42
+ cols[i] = "";
43
+ }
44
+
45
+ if(samples == null) {
46
+ out.format(format, cols);
47
+ return;
48
+ }
49
+
50
+ samples.add(cols);
51
+ if(samples.size() < SAMPLES) {
52
+ return;
53
+ }
54
+ }
55
+
56
+ protected String valueToString(Object obj)
57
+ {
58
+ return obj.toString();
59
+ }
60
+
61
+ private void flushSamples()
62
+ {
63
+ StringBuilder borderBuilder = new StringBuilder();
64
+
65
+ StringBuilder sb = new StringBuilder();
66
+ sb.append("| ");
67
+ borderBuilder.append("+-");
68
+ for(int i=0; i < header.length; i++) {
69
+ if(i != 0) {
70
+ sb.append(" | ");
71
+ borderBuilder.append("-+-");
72
+ }
73
+ int colLen = maxLengthInColumn(i);
74
+ sb.append("%"+colLen+"s");
75
+ for(int b=0; b < colLen; b++) {
76
+ borderBuilder.append("-");
77
+ }
78
+ }
79
+ sb.append(" |");
80
+ borderBuilder.append("-+");
81
+ sb.append("\n");
82
+
83
+ this.format = sb.toString();
84
+ this.border = borderBuilder.toString();
85
+
86
+ out.println(border);
87
+
88
+ for(int i=0; i < samples.size(); i++) {
89
+ out.format(format, samples.get(i));
90
+ if(i == 0) {
91
+ out.println(border);
92
+ }
93
+ }
94
+
95
+ this.samples = null;
96
+ }
97
+
98
+ private int maxLengthInColumn(int i)
99
+ {
100
+ int max = 0;
101
+ for(Object[] cols : samples) {
102
+ String s = (String) cols[i];
103
+ int len = (s == null) ? 0 : s.length();
104
+ if(max < len) {
105
+ max = len;
106
+ }
107
+ }
108
+ return max;
109
+ }
110
+
111
+ public void finish() throws IOException
112
+ {
113
+ if(!samples.isEmpty()) {
114
+ flushSamples();
115
+ }
116
+ out.println(border);
117
+ }
118
+ }
119
+
@@ -0,0 +1,26 @@
1
+ package org.embulk.config;
2
+
3
+ public interface CommitReport
4
+ extends DataSource
5
+ {
6
+ @Override
7
+ public CommitReport getNested(String attrName);
8
+
9
+ @Override
10
+ public CommitReport getNestedOrSetEmpty(String attrName);
11
+
12
+ @Override
13
+ public CommitReport set(String attrName, Object v);
14
+
15
+ @Override
16
+ public CommitReport setNested(String attrName, DataSource v);
17
+
18
+ @Override
19
+ public CommitReport setAll(DataSource other);
20
+
21
+ @Override
22
+ public CommitReport deepCopy();
23
+
24
+ @Override
25
+ public CommitReport merge(DataSource other);
26
+ }
@@ -0,0 +1,15 @@
1
+ package org.embulk.config;
2
+
3
+ import java.lang.annotation.Documented;
4
+ import java.lang.annotation.ElementType;
5
+ import java.lang.annotation.Retention;
6
+ import java.lang.annotation.RetentionPolicy;
7
+ import java.lang.annotation.Target;
8
+
9
+ @Documented
10
+ @Retention(RetentionPolicy.RUNTIME)
11
+ @Target(ElementType.METHOD)
12
+ public @interface Config
13
+ {
14
+ String value();
15
+ }
@@ -0,0 +1,15 @@
1
+ package org.embulk.config;
2
+
3
+ import java.lang.annotation.Documented;
4
+ import java.lang.annotation.ElementType;
5
+ import java.lang.annotation.Retention;
6
+ import java.lang.annotation.RetentionPolicy;
7
+ import java.lang.annotation.Target;
8
+
9
+ @Documented
10
+ @Retention(RetentionPolicy.RUNTIME)
11
+ @Target(ElementType.METHOD)
12
+ public @interface ConfigDefault
13
+ {
14
+ String value();
15
+ }
@@ -0,0 +1,20 @@
1
+ package org.embulk.config;
2
+
3
+ public class ConfigException
4
+ extends RuntimeException
5
+ {
6
+ public ConfigException(String message)
7
+ {
8
+ super(message);
9
+ }
10
+
11
+ public ConfigException(Throwable cause)
12
+ {
13
+ super(cause);
14
+ }
15
+
16
+ public ConfigException(String message, Throwable cause)
17
+ {
18
+ super(message, cause);
19
+ }
20
+ }
@@ -0,0 +1,83 @@
1
+ package org.embulk.config;
2
+
3
+ import java.io.File;
4
+ import java.io.FileInputStream;
5
+ import java.io.IOException;
6
+ import java.util.Properties;
7
+ import com.google.inject.Inject;
8
+ import com.fasterxml.jackson.databind.ObjectMapper;
9
+ import com.fasterxml.jackson.core.JsonParser;
10
+ import com.fasterxml.jackson.databind.JsonNode;
11
+ import com.fasterxml.jackson.databind.node.ObjectNode;
12
+ import com.fasterxml.jackson.databind.node.JsonNodeFactory;
13
+ import org.yaml.snakeyaml.Yaml;
14
+
15
+ public class ConfigLoader
16
+ {
17
+ private final ModelManager model;
18
+
19
+ @Inject
20
+ public ConfigLoader(ModelManager model)
21
+ {
22
+ this.model = model;
23
+ }
24
+
25
+ public ConfigSource fromJson(JsonParser parser) throws IOException
26
+ {
27
+ // TODO check parsed.isObject()
28
+ ObjectNode source = (ObjectNode) new ObjectMapper().readTree(parser);
29
+ return new DataSourceImpl(model, source);
30
+ }
31
+
32
+ public ConfigSource fromYamlFile(File path) throws IOException
33
+ {
34
+ Yaml yaml = new Yaml();
35
+ Object parsedYaml;
36
+ try (FileInputStream is = new FileInputStream(path)) {
37
+ parsedYaml = yaml.load(is);
38
+ }
39
+ ObjectNode source = objectToJsonObject(parsedYaml);
40
+ return new DataSourceImpl(model, source);
41
+ }
42
+
43
+ public ConfigSource fromPropertiesYamlLiteral(Properties props, String keyPrefix)
44
+ {
45
+ // TODO exception handling
46
+ ObjectNode source = new ObjectNode(JsonNodeFactory.instance);
47
+ Yaml yaml = new Yaml();
48
+ for (String key : props.stringPropertyNames()) {
49
+ // TODO handle "." and "[...]" as map and array acccessor for example:
50
+ // in.parser.type=csv => {"in": {"parser": {"type": "csv"}}}
51
+ if (!key.startsWith(keyPrefix)) {
52
+ continue;
53
+ }
54
+ String yamlValue = props.getProperty(key);
55
+ String keyName = key.substring(keyPrefix.length());
56
+ Object parsedValue = yaml.load(yamlValue);
57
+ JsonNode typedValue = objectToJson(parsedValue);
58
+ source.set(keyName, typedValue);
59
+ }
60
+ return new DataSourceImpl(model, source);
61
+ }
62
+
63
+ private JsonNode objectToJson(Object object)
64
+ {
65
+ // TODO exception
66
+ ObjectMapper objectMapper = new ObjectMapper();
67
+ try {
68
+ return objectMapper.readTree(objectMapper.writeValueAsString(object));
69
+ } catch (IOException ex) {
70
+ throw new RuntimeException(ex);
71
+ }
72
+ }
73
+
74
+ private ObjectNode objectToJsonObject(Object object)
75
+ {
76
+ // TODO exception
77
+ JsonNode json = objectToJson(object);
78
+ if (!json.isObject()) {
79
+ throw new RuntimeException("Expected object to deserialize ConfigSource but got "+json);
80
+ }
81
+ return (ObjectNode) json;
82
+ }
83
+ }
@@ -0,0 +1,28 @@
1
+ package org.embulk.config;
2
+
3
+ public interface ConfigSource
4
+ extends DataSource
5
+ {
6
+ public <T extends Task> T loadConfig(Class<T> taskType);
7
+
8
+ @Override
9
+ public ConfigSource getNested(String attrName);
10
+
11
+ @Override
12
+ public ConfigSource getNestedOrSetEmpty(String attrName);
13
+
14
+ @Override
15
+ public ConfigSource set(String attrName, Object v);
16
+
17
+ @Override
18
+ public ConfigSource setNested(String attrName, DataSource v);
19
+
20
+ @Override
21
+ public ConfigSource setAll(DataSource other);
22
+
23
+ @Override
24
+ public ConfigSource deepCopy();
25
+
26
+ @Override
27
+ public ConfigSource merge(DataSource other);
28
+ }
@@ -0,0 +1,35 @@
1
+ package org.embulk.config;
2
+
3
+ import java.util.List;
4
+ import java.util.Map;
5
+ import com.fasterxml.jackson.databind.JsonNode;
6
+ import com.fasterxml.jackson.databind.node.ObjectNode;
7
+
8
+ public interface DataSource
9
+ {
10
+ public List<String> getAttributeNames();
11
+
12
+ public Iterable<Map.Entry<String, JsonNode>> getAttributes();
13
+
14
+ public boolean isEmpty();
15
+
16
+ public <E> E get(Class<E> type, String attrName);
17
+
18
+ public <E> E get(Class<E> type, String attrName, E defaultValue);
19
+
20
+ public DataSource getNested(String attrName);
21
+
22
+ public DataSource getNestedOrSetEmpty(String attrName);
23
+
24
+ public DataSource set(String attrName, Object v);
25
+
26
+ public DataSource setNested(String attrName, DataSource v);
27
+
28
+ public DataSource setAll(DataSource other);
29
+
30
+ public DataSource deepCopy();
31
+
32
+ public DataSource merge(DataSource other);
33
+
34
+ public ObjectNode getObjectNode();
35
+ }
@@ -0,0 +1,208 @@
1
+ package org.embulk.config;
2
+
3
+ import java.util.List;
4
+ import java.util.Map;
5
+ import java.util.Iterator;
6
+ import com.google.common.collect.ImmutableList;
7
+ import com.fasterxml.jackson.core.JsonParser;
8
+ import com.fasterxml.jackson.databind.ObjectMapper;
9
+ import com.fasterxml.jackson.databind.JsonNode;
10
+ import com.fasterxml.jackson.databind.JsonMappingException;
11
+ import com.fasterxml.jackson.databind.node.ObjectNode;
12
+ import com.fasterxml.jackson.databind.node.ArrayNode;
13
+ import com.fasterxml.jackson.databind.node.JsonNodeFactory;
14
+
15
+ public class DataSourceImpl
16
+ implements ConfigSource, TaskSource, CommitReport, NextConfig
17
+ {
18
+ protected final ObjectNode data;
19
+ protected final ModelManager model;
20
+
21
+ public DataSourceImpl(ModelManager model)
22
+ {
23
+ this(model, new ObjectNode(JsonNodeFactory.instance));
24
+ }
25
+
26
+ // visible for DataSourceSerDe, ConfigSourceLoader and TaskInvocationHandler.dump
27
+ public DataSourceImpl(ModelManager model, ObjectNode data)
28
+ {
29
+ this.data = data;
30
+ this.model = model;
31
+ }
32
+
33
+ protected DataSourceImpl newInstance(ModelManager model, ObjectNode data)
34
+ {
35
+ return new DataSourceImpl(model, (ObjectNode) data);
36
+ }
37
+
38
+ // visible for DataSourceSerDe.DataSourceSerializer
39
+ @Override
40
+ public ObjectNode getObjectNode()
41
+ {
42
+ return data;
43
+ }
44
+
45
+ @Override
46
+ public List<String> getAttributeNames()
47
+ {
48
+ return ImmutableList.copyOf(data.fieldNames());
49
+ }
50
+
51
+ @Override
52
+ public Iterable<Map.Entry<String, JsonNode>> getAttributes()
53
+ {
54
+ return new Iterable() {
55
+ public Iterator<Map.Entry<String, JsonNode>> iterator()
56
+ {
57
+ return data.fields();
58
+ }
59
+ };
60
+ }
61
+
62
+ @Override
63
+ public boolean isEmpty()
64
+ {
65
+ return !data.fieldNames().hasNext();
66
+ }
67
+
68
+ @Override
69
+ public <E> E get(Class<E> type, String attrName)
70
+ {
71
+ JsonNode json = data.get(attrName);
72
+ if (json == null) {
73
+ throw new ConfigException("Attribute "+attrName+" is required but not set");
74
+ }
75
+ return model.readObject(type, json.traverse());
76
+ }
77
+
78
+ @Override
79
+ public <E> E get(Class<E> type, String attrName, E defaultValue)
80
+ {
81
+ JsonNode json = data.get(attrName);
82
+ if (json == null) {
83
+ return defaultValue;
84
+ }
85
+ return model.readObject(type, json.traverse());
86
+ }
87
+
88
+ @Override
89
+ public DataSourceImpl getNested(String attrName)
90
+ {
91
+ JsonNode json = data.get(attrName);
92
+ if (json == null) {
93
+ throw new ConfigException("Attribute "+attrName+" is required but not set");
94
+ }
95
+ if (!json.isObject()) {
96
+ throw new ConfigException("Attribute "+attrName+" must be an object");
97
+ }
98
+ return newInstance(model, (ObjectNode) json);
99
+ }
100
+
101
+ @Override
102
+ public DataSourceImpl getNestedOrSetEmpty(String attrName)
103
+ {
104
+ JsonNode json = data.get(attrName);
105
+ if (json == null) {
106
+ json = data.objectNode();
107
+ data.set(attrName, json);
108
+ } else if (!json.isObject()) {
109
+ throw new ConfigException("Attribute "+attrName+" must be an object");
110
+ }
111
+ return newInstance(model, (ObjectNode) json);
112
+ }
113
+
114
+ @Override
115
+ public DataSourceImpl set(String attrName, Object v)
116
+ {
117
+ if (v == null) {
118
+ data.remove(attrName);
119
+ } else {
120
+ data.put(attrName, model.writeObjectAsJsonNode(v));
121
+ }
122
+ return this;
123
+ }
124
+
125
+ @Override
126
+ public DataSourceImpl setNested(String attrName, DataSource v)
127
+ {
128
+ data.put(attrName, v.getObjectNode());
129
+ return this;
130
+ }
131
+
132
+ @Override
133
+ public DataSourceImpl setAll(DataSource other)
134
+ {
135
+ for (Map.Entry<String, JsonNode> field : other.getAttributes()) {
136
+ data.put(field.getKey(), field.getValue());
137
+ }
138
+ return this;
139
+ }
140
+
141
+ @Override
142
+ public DataSourceImpl deepCopy()
143
+ {
144
+ return newInstance(model, data.deepCopy());
145
+ }
146
+
147
+ @Override
148
+ public DataSourceImpl merge(DataSource other)
149
+ {
150
+ mergeJsonObject(data, other.deepCopy().getObjectNode());
151
+ return this;
152
+ }
153
+
154
+ private static void mergeJsonObject(ObjectNode src, ObjectNode other)
155
+ {
156
+ Iterator<Map.Entry<String, JsonNode>> ite = other.fields();
157
+ while (ite.hasNext()) {
158
+ Map.Entry<String, JsonNode> pair = ite.next();
159
+ JsonNode s = src.get(pair.getKey());
160
+ JsonNode v = pair.getValue();
161
+ if (v.isObject() && s != null && s.isObject()) {
162
+ mergeJsonObject((ObjectNode) s, (ObjectNode) v);
163
+ } else if (v.isArray() && s != null && s.isArray()) {
164
+ mergeJsonArray((ArrayNode) s, (ArrayNode) v);
165
+ } else {
166
+ src.replace(pair.getKey(), v);
167
+ }
168
+ }
169
+ }
170
+
171
+ private static void mergeJsonArray(ArrayNode src, ArrayNode other)
172
+ {
173
+ src.addAll(other);
174
+ }
175
+
176
+ @Override
177
+ public <T extends Task> T loadTask(Class<T> taskType)
178
+ {
179
+ return model.readObject(taskType, data.traverse());
180
+ }
181
+
182
+ @Override
183
+ public <T extends Task> T loadConfig(Class<T> taskType)
184
+ {
185
+ return model.readObjectWithConfigSerDe(taskType, data.traverse());
186
+ }
187
+
188
+ @Override
189
+ public String toString()
190
+ {
191
+ return data.toString();
192
+ }
193
+
194
+ @Override
195
+ public boolean equals(Object other)
196
+ {
197
+ if (!(other instanceof DataSource)) {
198
+ return false;
199
+ }
200
+ return data.equals(((DataSource) other).getObjectNode());
201
+ }
202
+
203
+ @Override
204
+ public int hashCode()
205
+ {
206
+ return data.hashCode();
207
+ }
208
+ }