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,343 @@
1
+ package org.embulk.config;
2
+
3
+ import java.lang.reflect.Proxy;
4
+ import java.lang.reflect.Method;
5
+ import java.lang.reflect.Type;
6
+ import java.io.IOException;
7
+ import java.util.List;
8
+ import java.util.Map;
9
+ import java.util.HashMap;
10
+ import java.util.concurrent.ConcurrentHashMap;
11
+ import com.google.common.base.Optional;
12
+ import com.google.common.collect.ImmutableList;
13
+ import com.google.common.collect.ImmutableSet;
14
+ import com.google.common.collect.ImmutableMap;
15
+ import com.fasterxml.jackson.core.JsonGenerator;
16
+ import com.fasterxml.jackson.core.JsonParser;
17
+ import com.fasterxml.jackson.core.JsonToken;
18
+ import com.fasterxml.jackson.core.Version;
19
+ import com.fasterxml.jackson.databind.Module;
20
+ import com.fasterxml.jackson.databind.module.SimpleModule;
21
+ import com.fasterxml.jackson.databind.deser.Deserializers;
22
+ import com.fasterxml.jackson.databind.ObjectMapper;
23
+ import com.fasterxml.jackson.databind.JavaType;
24
+ import com.fasterxml.jackson.databind.BeanDescription;
25
+ import com.fasterxml.jackson.databind.JsonSerializer;
26
+ import com.fasterxml.jackson.databind.JsonDeserializer;
27
+ import com.fasterxml.jackson.databind.SerializerProvider;
28
+ import com.fasterxml.jackson.databind.DeserializationContext;
29
+ import com.fasterxml.jackson.databind.DeserializationConfig;
30
+ import com.fasterxml.jackson.databind.JsonMappingException;
31
+ import com.fasterxml.jackson.annotation.JacksonInject;
32
+
33
+ class TaskSerDe
34
+ {
35
+ public static class TaskSerializer
36
+ extends JsonSerializer<Task>
37
+ {
38
+ private final ObjectMapper nestedObjectMapper;
39
+
40
+ public TaskSerializer(ObjectMapper nestedObjectMapper)
41
+ {
42
+ this.nestedObjectMapper = nestedObjectMapper;
43
+ }
44
+
45
+ @Override
46
+ public void serialize(Task value, JsonGenerator jgen, SerializerProvider provider)
47
+ throws IOException
48
+ {
49
+ if (value instanceof Proxy) {
50
+ Object handler = Proxy.getInvocationHandler(value);
51
+ if (handler instanceof TaskInvocationHandler) {
52
+ TaskInvocationHandler h = (TaskInvocationHandler) handler;
53
+ Map<String, Object> objects = h.getObjects();
54
+ jgen.writeStartObject();
55
+ for (Map.Entry<String, Object> pair : objects.entrySet()) {
56
+ if (h.getInjectedFields().contains(pair.getKey())) {
57
+ continue;
58
+ }
59
+ jgen.writeFieldName(pair.getKey());
60
+ nestedObjectMapper.writeValue(jgen, pair.getValue());
61
+ }
62
+ jgen.writeEndObject();
63
+ return;
64
+ }
65
+ }
66
+ // TODO exception class & message
67
+ throw new UnsupportedOperationException("Serializing Task is not supported");
68
+ }
69
+ }
70
+
71
+ public static class TaskDeserializer <T>
72
+ extends JsonDeserializer<T>
73
+ {
74
+ private final ObjectMapper nestedObjectMapper;
75
+ private final ModelManager model;
76
+ private final Class<?> iface;
77
+ private final Map<String, FieldEntry> mappings;
78
+ private final List<InjectEntry> injects;
79
+
80
+ public TaskDeserializer(ObjectMapper nestedObjectMapper, ModelManager model, Class<T> iface)
81
+ {
82
+ this.nestedObjectMapper = nestedObjectMapper;
83
+ this.model = model;
84
+ this.iface = iface;
85
+ this.mappings = getterMappings(iface);
86
+ this.injects = injectEntries(iface);
87
+ }
88
+
89
+ protected Map<String, FieldEntry> getterMappings(Class<?> iface)
90
+ {
91
+ ImmutableMap.Builder<String, FieldEntry> builder = ImmutableMap.builder();
92
+ for (Map.Entry<String, Method> getter : TaskInvocationHandler.fieldGetters(iface).entrySet()) {
93
+ Method getterMethod = getter.getValue();
94
+ String fieldName = getter.getKey();
95
+
96
+ if (getterMethod.getAnnotation(JacksonInject.class) != null) {
97
+ // InjectEntry
98
+ continue;
99
+ }
100
+
101
+ Type fieldType = getterMethod.getGenericReturnType();
102
+
103
+ Optional<String> jsonKey = getJsonKey(getterMethod, fieldName);
104
+ if (!jsonKey.isPresent()) {
105
+ // skip this field
106
+ continue;
107
+ }
108
+ Optional<String> defaultJsonString = getDefaultJsonString(getterMethod);
109
+ builder.put(jsonKey.get(), new FieldEntry(fieldName, fieldType, defaultJsonString));
110
+ }
111
+ return builder.build();
112
+ }
113
+
114
+ protected List<InjectEntry> injectEntries(Class<?> iface)
115
+ {
116
+ ImmutableList.Builder<InjectEntry> builder = ImmutableList.builder();
117
+ for (Map.Entry<String, Method> getter : TaskInvocationHandler.fieldGetters(iface).entrySet()) {
118
+ Method getterMethod = getter.getValue();
119
+ String fieldName = getter.getKey();
120
+ JacksonInject inject = getterMethod.getAnnotation(JacksonInject.class);
121
+ if (inject != null) {
122
+ // InjectEntry
123
+ builder.add(new InjectEntry(fieldName, getterMethod.getReturnType()));
124
+ }
125
+ }
126
+ return builder.build();
127
+ }
128
+
129
+ protected Optional<String> getJsonKey(Method getterMethod, String fieldName)
130
+ {
131
+ return Optional.of(fieldName);
132
+ }
133
+
134
+ protected Optional<String> getDefaultJsonString(Method getterMethod)
135
+ {
136
+ return Optional.absent();
137
+ }
138
+
139
+ @Override
140
+ public T deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
141
+ {
142
+ Map<String, Object> objects = new ConcurrentHashMap<String, Object>();
143
+ HashMap<String, FieldEntry> unusedMappings = new HashMap<>(mappings);
144
+
145
+ JsonToken current;
146
+ current = jp.getCurrentToken();
147
+ if (current == JsonToken.START_OBJECT) {
148
+ current = jp.nextToken();
149
+ }
150
+ for (; current != JsonToken.END_OBJECT; current = jp.nextToken()) {
151
+ String key = jp.getCurrentName();
152
+ current = jp.nextToken();
153
+ FieldEntry field = mappings.get(key);
154
+ if (field == null) {
155
+ jp.skipChildren();
156
+ } else {
157
+ Object value = nestedObjectMapper.readValue(jp, new GenericTypeReference(field.getType()));
158
+ if (value == null) {
159
+ throw new JsonMappingException("Setting null to a @Config field is not allowed. Configuration object must be Optional<T> (com.google.common.base.Optional)");
160
+ }
161
+ objects.put(field.getName(), value);
162
+ unusedMappings.remove(key);
163
+ }
164
+ }
165
+
166
+ // set default values
167
+ for (Map.Entry<String, FieldEntry> unused : unusedMappings.entrySet()) {
168
+ FieldEntry field = unused.getValue();
169
+ if (field.getDefaultJsonString().isPresent()) {
170
+ Object value = nestedObjectMapper.readValue(field.getDefaultJsonString().get(), new GenericTypeReference(field.getType()));
171
+ if (value == null) {
172
+ throw new JsonMappingException("Setting null to a @Config field is not allowed. Configuration object must be Optional<T> (com.google.common.base.Optional)");
173
+ }
174
+ objects.put(field.getName(), value);
175
+ } else {
176
+ // required field
177
+ throw new JsonMappingException("Field '"+unused.getKey()+"' is required but not set", jp.getCurrentLocation());
178
+ }
179
+ }
180
+
181
+ // inject
182
+ ImmutableSet.Builder<String> injectedFields = ImmutableSet.builder();
183
+ for (InjectEntry inject : injects) {
184
+ objects.put(inject.getName(), model.getInjectedInstance(inject.getType()));
185
+ injectedFields.add(inject.getName());
186
+ }
187
+
188
+ return (T) Proxy.newProxyInstance(
189
+ iface.getClassLoader(), new Class<?>[] { iface },
190
+ new TaskInvocationHandler(model, iface, objects, injectedFields.build()));
191
+ }
192
+
193
+ private static class FieldEntry
194
+ {
195
+ private final String name;
196
+ private final Type type;
197
+ private final Optional<String> defaultJsonString;
198
+
199
+ public FieldEntry(String name, Type type, Optional<String> defaultJsonString)
200
+ {
201
+ this.name = name;
202
+ this.type = type;
203
+ this.defaultJsonString = defaultJsonString;
204
+ }
205
+
206
+ public String getName()
207
+ {
208
+ return name;
209
+ }
210
+
211
+ public Type getType()
212
+ {
213
+ return type;
214
+ }
215
+
216
+ public Optional<String> getDefaultJsonString()
217
+ {
218
+ return defaultJsonString;
219
+ }
220
+ }
221
+
222
+ private static class InjectEntry
223
+ {
224
+ private final String name;
225
+ private Class<?> type;
226
+
227
+ public InjectEntry(String name, Class<?> type)
228
+ {
229
+ this.name = name;
230
+ this.type = type;
231
+ }
232
+
233
+ public String getName()
234
+ {
235
+ return name;
236
+ }
237
+
238
+ public Class<?> getType()
239
+ {
240
+ return type;
241
+ }
242
+ }
243
+ }
244
+
245
+ public static class TaskSerializerModule
246
+ extends SimpleModule
247
+ {
248
+ public TaskSerializerModule(ObjectMapper nestedObjectMapper)
249
+ {
250
+ super();
251
+ addSerializer(Task.class, new TaskSerializer(nestedObjectMapper));
252
+ }
253
+ }
254
+
255
+ public static class ConfigTaskDeserializer <T>
256
+ extends TaskDeserializer<T>
257
+ {
258
+ public ConfigTaskDeserializer(ObjectMapper nestedObjectMapper, ModelManager model, Class<T> iface)
259
+ {
260
+ super(nestedObjectMapper, model, iface);
261
+ }
262
+
263
+ @Override
264
+ protected Optional<String> getJsonKey(Method getterMethod, String fieldName)
265
+ {
266
+ Config a = getterMethod.getAnnotation(Config.class);
267
+ if (a != null) {
268
+ return Optional.of(a.value());
269
+ } else {
270
+ return Optional.absent(); // skip this field
271
+ }
272
+ }
273
+
274
+ @Override
275
+ public Optional<String> getDefaultJsonString(Method getterMethod)
276
+ {
277
+ ConfigDefault a = getterMethod.getAnnotation(ConfigDefault.class);
278
+ if (a != null && !a.value().isEmpty()) {
279
+ return Optional.of(a.value());
280
+ }
281
+ return super.getDefaultJsonString(getterMethod);
282
+ }
283
+ }
284
+
285
+ public static class TaskDeserializerModule
286
+ extends Module // can't use just SimpleModule, due to generic types
287
+ {
288
+ protected final ObjectMapper nestedObjectMapper;
289
+ protected final ModelManager model;
290
+
291
+ public TaskDeserializerModule(ObjectMapper nestedObjectMapper, ModelManager model)
292
+ {
293
+ this.nestedObjectMapper = nestedObjectMapper;
294
+ this.model = model;
295
+ }
296
+
297
+ @Override
298
+ public String getModuleName() { return "embulk.config.TaskSerDe"; }
299
+
300
+ @Override
301
+ public Version version() { return Version.unknownVersion(); }
302
+
303
+ @Override
304
+ public void setupModule(SetupContext context)
305
+ {
306
+ context.addDeserializers(new Deserializers.Base() {
307
+ @Override
308
+ public JsonDeserializer<?> findBeanDeserializer(JavaType type, DeserializationConfig config,
309
+ BeanDescription beanDesc) throws JsonMappingException
310
+ {
311
+ Class<?> raw = type.getRawClass();
312
+ if (Task.class.isAssignableFrom(raw)) {
313
+ return newTaskDeserializer(raw);
314
+ }
315
+ return super.findBeanDeserializer(type, config, beanDesc);
316
+ }
317
+ });
318
+ }
319
+
320
+ protected JsonDeserializer<?> newTaskDeserializer(Class<?> raw)
321
+ {
322
+ return new TaskDeserializer(nestedObjectMapper, model, raw);
323
+ }
324
+ }
325
+
326
+ public static class ConfigTaskDeserializerModule
327
+ extends TaskDeserializerModule
328
+ {
329
+ public ConfigTaskDeserializerModule(ObjectMapper nestedObjectMapper, ModelManager model)
330
+ {
331
+ super(nestedObjectMapper, model);
332
+ }
333
+
334
+ @Override
335
+ public String getModuleName() { return "embulk.config.ConfigTaskSerDe"; }
336
+
337
+ @Override
338
+ protected JsonDeserializer<?> newTaskDeserializer(Class<?> raw)
339
+ {
340
+ return new ConfigTaskDeserializer(nestedObjectMapper, model, raw);
341
+ }
342
+ }
343
+ }
@@ -0,0 +1,28 @@
1
+ package org.embulk.config;
2
+
3
+ public interface TaskSource
4
+ extends DataSource
5
+ {
6
+ public <T extends Task> T loadTask(Class<T> taskType);
7
+
8
+ @Override
9
+ public TaskSource getNested(String attrName);
10
+
11
+ @Override
12
+ public TaskSource getNestedOrSetEmpty(String attrName);
13
+
14
+ @Override
15
+ public TaskSource set(String attrName, Object v);
16
+
17
+ @Override
18
+ public TaskSource setNested(String attrName, DataSource v);
19
+
20
+ @Override
21
+ public TaskSource setAll(DataSource other);
22
+
23
+ @Override
24
+ public TaskSource deepCopy();
25
+
26
+ @Override
27
+ public TaskSource merge(DataSource other);
28
+ }
@@ -0,0 +1,37 @@
1
+ package org.embulk.config;
2
+
3
+ import java.util.Set;
4
+ import javax.validation.ConstraintViolation;
5
+
6
+ public class TaskValidationException
7
+ extends RuntimeException
8
+ {
9
+ @SuppressWarnings("unchecked")
10
+ private final Set violations;
11
+
12
+ public <T> TaskValidationException(Set<ConstraintViolation<T>> violations)
13
+ {
14
+ super(formatMessage(violations));
15
+ this.violations = violations;
16
+ }
17
+
18
+ public Set<ConstraintViolation<?>> getViolations()
19
+ {
20
+ return violations;
21
+ }
22
+
23
+ private static <T> String formatMessage(Set<ConstraintViolation<T>> violations)
24
+ {
25
+ StringBuilder sb = new StringBuilder();
26
+ sb.append("Configuration task validation failed.");
27
+ for(ConstraintViolation<T> violation : violations) {
28
+ sb.append(" ");
29
+ sb.append(violation.getPropertyPath());
30
+ sb.append(" ");
31
+ sb.append(violation.getMessage());
32
+ sb.append(" but got ");
33
+ sb.append(violation.getInvalidValue());
34
+ }
35
+ return sb.toString();
36
+ }
37
+ }
@@ -0,0 +1,24 @@
1
+ package org.embulk.config;
2
+
3
+ import java.util.Set;
4
+ import javax.validation.Validator;
5
+ import javax.validation.ConstraintViolation;
6
+
7
+ public class TaskValidator
8
+ {
9
+ private final Validator validator;
10
+
11
+ public TaskValidator(Validator validator)
12
+ {
13
+ this.validator = validator;
14
+ }
15
+
16
+ public <T> void validateModel(T model) throws TaskValidationException
17
+ {
18
+ Set<ConstraintViolation<T>> violations = validator.validate(model);
19
+ if (!violations.isEmpty()) {
20
+ throw new TaskValidationException(violations);
21
+ }
22
+ }
23
+ }
24
+
@@ -0,0 +1,45 @@
1
+ package org.embulk.exec;
2
+
3
+ import org.slf4j.ILoggerFactory;
4
+ import com.google.common.base.Preconditions;
5
+ import com.google.inject.Module;
6
+ import com.google.inject.name.Names;
7
+ import com.google.inject.Binder;
8
+ import com.google.inject.Scopes;
9
+ import com.fasterxml.jackson.module.guice.ObjectMapperModule;
10
+ import com.fasterxml.jackson.datatype.guava.GuavaModule;
11
+ import com.fasterxml.jackson.datatype.joda.JodaModule;
12
+ import org.embulk.config.ModelManager;
13
+ import org.embulk.spi.time.DateTimeZoneSerDe;
14
+ import org.embulk.spi.time.TimestampSerDe;
15
+ import org.embulk.spi.ParserPlugin;
16
+ import org.embulk.spi.BufferAllocator;
17
+ import org.embulk.spi.util.CharsetSerDe;
18
+ import static org.embulk.plugin.InjectedPluginSource.registerPluginTo;
19
+
20
+ public class ExecModule
21
+ implements Module
22
+ {
23
+ @Override
24
+ public void configure(Binder binder)
25
+ {
26
+ Preconditions.checkNotNull(binder, "binder is null.");
27
+
28
+ binder.bind(ILoggerFactory.class).toProvider(LoggerProvider.class);
29
+ binder.bind(ModelManager.class).in(Scopes.SINGLETON);
30
+ binder.bind(BufferAllocator.class).to(PooledBufferAllocator.class).in(Scopes.SINGLETON);
31
+
32
+ // GuessExecutor
33
+ registerPluginTo(binder, ParserPlugin.class, "system_guess", GuessExecutor.GuessParserPlugin.class);
34
+ registerPluginTo(binder, ParserPlugin.class, "system_sampling", SamplingParserPlugin.class);
35
+
36
+ // serde
37
+ ObjectMapperModule mapper = new ObjectMapperModule();
38
+ DateTimeZoneSerDe.configure(mapper);
39
+ TimestampSerDe.configure(mapper);
40
+ CharsetSerDe.configure(mapper);
41
+ mapper.registerModule(new GuavaModule()); // jackson-datatype-guava
42
+ mapper.registerModule(new JodaModule()); // jackson-datatype-joda
43
+ mapper.configure(binder);
44
+ }
45
+ }