embulk 0.4.3 → 0.4.4
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.
- checksums.yaml +4 -4
- data/README.md +8 -11
- data/build.gradle +22 -2
- data/embulk-core/src/main/java/org/embulk/command/Runner.java +7 -0
- data/embulk-core/src/main/java/org/embulk/exec/GuessExecutor.java +8 -6
- data/embulk-core/src/main/java/org/embulk/exec/LocalExecutor.java +54 -46
- data/embulk-core/src/main/java/org/embulk/exec/LoggerProvider.java +20 -3
- data/embulk-core/src/main/java/org/embulk/exec/PreviewExecutor.java +41 -10
- data/embulk-core/src/main/java/org/embulk/exec/SamplingParserPlugin.java +1 -1
- data/embulk-core/src/main/java/org/embulk/exec/SetCurrentThreadName.java +19 -0
- data/embulk-core/src/main/java/org/embulk/spi/Exec.java +5 -0
- data/embulk-core/src/main/java/org/embulk/spi/ExecSession.java +24 -0
- data/embulk-core/src/main/java/org/embulk/spi/FileInputPlugin.java +4 -4
- data/embulk-core/src/main/java/org/embulk/spi/FileInputRunner.java +8 -8
- data/embulk-core/src/main/java/org/embulk/spi/FileOutputPlugin.java +4 -4
- data/embulk-core/src/main/java/org/embulk/spi/FileOutputRunner.java +8 -8
- data/embulk-core/src/main/java/org/embulk/spi/InputPlugin.java +4 -4
- data/embulk-core/src/main/java/org/embulk/spi/OutputPlugin.java +4 -4
- data/embulk-core/src/main/java/org/embulk/spi/time/TimestampFormat.java +1 -1
- data/embulk-core/src/main/java/org/embulk/spi/util/FileOutputOutputStream.java +32 -8
- data/embulk-core/src/main/java/org/embulk/spi/util/InputStreamFileInput.java +1 -1
- data/embulk-core/src/main/java/org/embulk/spi/util/LineEncoder.java +3 -4
- data/embulk-core/src/main/java/org/embulk/spi/util/OutputStreamFileOutput.java +88 -0
- data/embulk-core/src/test/java/org/embulk/spi/TestFileInputInputStream.java +1 -1
- data/embulk-core/src/test/java/org/embulk/spi/TestFileInputRunner.java +5 -5
- data/embulk-core/src/test/java/org/embulk/spi/TestFileOutputRunner.java +4 -4
- data/embulk-docs/src/release.rst +1 -0
- data/embulk-docs/src/release/release-0.4.4.rst +39 -0
- data/embulk-standards/src/main/java/org/embulk/standards/GzipFileEncoderPlugin.java +32 -7
- data/embulk-standards/src/main/java/org/embulk/standards/LocalFileInputPlugin.java +9 -9
- data/embulk-standards/src/main/java/org/embulk/standards/LocalFileOutputPlugin.java +6 -6
- data/embulk-standards/src/main/java/org/embulk/standards/NullOutputPlugin.java +5 -5
- data/embulk-standards/src/main/java/org/embulk/standards/StdoutOutputPlugin.java +5 -5
- data/lib/embulk/command/embulk_run.rb +14 -2
- data/lib/embulk/data/new/java/file_input.java.erb +7 -7
- data/lib/embulk/data/new/java/file_output.java.erb +5 -5
- data/lib/embulk/data/new/java/input.java.erb +6 -6
- data/lib/embulk/data/new/java/output.java.erb +5 -5
- data/lib/embulk/data_source.rb +3 -3
- data/lib/embulk/guess_plugin.rb +5 -5
- data/lib/embulk/input_plugin.rb +7 -7
- data/lib/embulk/output_plugin.rb +7 -7
- data/lib/embulk/version.rb +1 -1
- metadata +7 -4
@@ -53,7 +53,7 @@ class SamplingParserPlugin
|
|
53
53
|
final InputPlugin input = Exec.newPlugin(InputPlugin.class, samplingInputConfig.get(PluginType.class, "type"));
|
54
54
|
try {
|
55
55
|
input.transaction(samplingInputConfig, new InputPlugin.Control() {
|
56
|
-
public List<CommitReport> run(TaskSource taskSource, Schema schema, int
|
56
|
+
public List<CommitReport> run(TaskSource taskSource, Schema schema, int taskCount)
|
57
57
|
{
|
58
58
|
input.run(taskSource, schema, 0, new PageOutput() {
|
59
59
|
@Override
|
@@ -0,0 +1,19 @@
|
|
1
|
+
package org.embulk.exec;
|
2
|
+
|
3
|
+
public class SetCurrentThreadName
|
4
|
+
implements AutoCloseable
|
5
|
+
{
|
6
|
+
private final String original;
|
7
|
+
|
8
|
+
public SetCurrentThreadName(String name)
|
9
|
+
{
|
10
|
+
this.original = Thread.currentThread().getName();
|
11
|
+
Thread.currentThread().setName(name);
|
12
|
+
}
|
13
|
+
|
14
|
+
@Override
|
15
|
+
public void close()
|
16
|
+
{
|
17
|
+
Thread.currentThread().setName(original);
|
18
|
+
}
|
19
|
+
}
|
@@ -29,6 +29,7 @@ public class ExecSession
|
|
29
29
|
private final BufferAllocator bufferAllocator;
|
30
30
|
private final Timestamp transactionTime;
|
31
31
|
private final DateTimeZone transactionTimeZone;
|
32
|
+
private final boolean preview;
|
32
33
|
|
33
34
|
public interface SessionTask
|
34
35
|
extends Task
|
@@ -62,6 +63,24 @@ public class ExecSession
|
|
62
63
|
|
63
64
|
this.transactionTime = task.getTransactionTime().or(Timestamp.ofEpochMilli(System.currentTimeMillis())); // TODO get nanoseconds for default
|
64
65
|
this.transactionTimeZone = task.getTransactionTimeZone();
|
66
|
+
this.preview = false;
|
67
|
+
}
|
68
|
+
|
69
|
+
private ExecSession(ExecSession copy, boolean preview)
|
70
|
+
{
|
71
|
+
this.injector = copy.injector;
|
72
|
+
this.loggerFactory = copy.loggerFactory;
|
73
|
+
this.modelManager = copy.modelManager;
|
74
|
+
this.pluginManager = copy.pluginManager;
|
75
|
+
this.bufferAllocator = copy.bufferAllocator;
|
76
|
+
this.transactionTime = copy.transactionTime;
|
77
|
+
this.transactionTimeZone = copy.transactionTimeZone;
|
78
|
+
this.preview = preview;
|
79
|
+
}
|
80
|
+
|
81
|
+
public ExecSession copyForPreview()
|
82
|
+
{
|
83
|
+
return new ExecSession(this, true);
|
65
84
|
}
|
66
85
|
|
67
86
|
public ConfigSource getSessionConfigSource()
|
@@ -133,4 +152,9 @@ public class ExecSession
|
|
133
152
|
FormatterTask formatterTask = config.loadConfig(FormatterTask.class);
|
134
153
|
return new TimestampFormatter(format, formatterTask);
|
135
154
|
}
|
155
|
+
|
156
|
+
public boolean isPreview()
|
157
|
+
{
|
158
|
+
return preview;
|
159
|
+
}
|
136
160
|
}
|
@@ -11,20 +11,20 @@ public interface FileInputPlugin
|
|
11
11
|
public interface Control
|
12
12
|
{
|
13
13
|
public List<CommitReport> run(TaskSource taskSource,
|
14
|
-
int
|
14
|
+
int taskCount);
|
15
15
|
}
|
16
16
|
|
17
17
|
public ConfigDiff transaction(ConfigSource config,
|
18
18
|
FileInputPlugin.Control control);
|
19
19
|
|
20
20
|
public ConfigDiff resume(TaskSource taskSource,
|
21
|
-
int
|
21
|
+
int taskCount,
|
22
22
|
FileInputPlugin.Control control);
|
23
23
|
|
24
24
|
public void cleanup(TaskSource taskSource,
|
25
|
-
int
|
25
|
+
int taskCount,
|
26
26
|
List<CommitReport> successCommitReports);
|
27
27
|
|
28
28
|
public TransactionalFileInput open(TaskSource taskSource,
|
29
|
-
int
|
29
|
+
int taskIndex);
|
30
30
|
}
|
@@ -61,11 +61,11 @@ public class FileInputRunner
|
|
61
61
|
}
|
62
62
|
|
63
63
|
public ConfigDiff resume(TaskSource taskSource,
|
64
|
-
Schema schema, int
|
64
|
+
Schema schema, int taskCount,
|
65
65
|
InputPlugin.Control control)
|
66
66
|
{
|
67
67
|
final RunnerTask task = taskSource.loadTask(RunnerTask.class);
|
68
|
-
return fileInputPlugin.resume(task.getFileInputTaskSource(),
|
68
|
+
return fileInputPlugin.resume(task.getFileInputTaskSource(), taskCount, new RunnerControl(task, control));
|
69
69
|
}
|
70
70
|
|
71
71
|
private class RunnerControl
|
@@ -86,7 +86,7 @@ public class FileInputRunner
|
|
86
86
|
}
|
87
87
|
|
88
88
|
@Override
|
89
|
-
public List<CommitReport> run(final TaskSource fileInputTaskSource, final int
|
89
|
+
public List<CommitReport> run(final TaskSource fileInputTaskSource, final int taskCount)
|
90
90
|
{
|
91
91
|
final List<CommitReport> commitReports = new ArrayList<CommitReport>();
|
92
92
|
Decoders.transaction(decoderPlugins, task.getDecoderConfigs(), new Decoders.Control() {
|
@@ -98,7 +98,7 @@ public class FileInputRunner
|
|
98
98
|
task.setFileInputTaskSource(fileInputTaskSource);
|
99
99
|
task.setDecoderTaskSources(decoderTaskSources);
|
100
100
|
task.setParserTaskSource(parserTaskSource);
|
101
|
-
commitReports.addAll(nextControl.run(task.dump(), schema,
|
101
|
+
commitReports.addAll(nextControl.run(task.dump(), schema, taskCount));
|
102
102
|
}
|
103
103
|
});
|
104
104
|
}
|
@@ -108,21 +108,21 @@ public class FileInputRunner
|
|
108
108
|
}
|
109
109
|
|
110
110
|
public void cleanup(TaskSource taskSource,
|
111
|
-
Schema schema, int
|
111
|
+
Schema schema, int taskCount,
|
112
112
|
List<CommitReport> successCommitReports)
|
113
113
|
{
|
114
|
-
fileInputPlugin.cleanup(taskSource,
|
114
|
+
fileInputPlugin.cleanup(taskSource, taskCount, successCommitReports);
|
115
115
|
}
|
116
116
|
|
117
117
|
@Override
|
118
|
-
public CommitReport run(TaskSource taskSource, Schema schema, int
|
118
|
+
public CommitReport run(TaskSource taskSource, Schema schema, int taskIndex,
|
119
119
|
PageOutput output)
|
120
120
|
{
|
121
121
|
final RunnerTask task = taskSource.loadTask(RunnerTask.class);
|
122
122
|
List<DecoderPlugin> decoderPlugins = newDecoderPlugins(task);
|
123
123
|
ParserPlugin parserPlugin = newParserPlugin(task);
|
124
124
|
|
125
|
-
TransactionalFileInput tran = fileInputPlugin.open(task.getFileInputTaskSource(),
|
125
|
+
TransactionalFileInput tran = fileInputPlugin.open(task.getFileInputTaskSource(), taskIndex);
|
126
126
|
FileInput fileInput = tran;
|
127
127
|
try {
|
128
128
|
fileInput = Decoders.open(decoderPlugins, task.getDecoderTaskSources(), fileInput);
|
@@ -13,16 +13,16 @@ public interface FileOutputPlugin
|
|
13
13
|
public List<CommitReport> run(TaskSource taskSource);
|
14
14
|
}
|
15
15
|
|
16
|
-
public ConfigDiff transaction(ConfigSource config, int
|
16
|
+
public ConfigDiff transaction(ConfigSource config, int taskCount,
|
17
17
|
FileOutputPlugin.Control control);
|
18
18
|
|
19
19
|
public ConfigDiff resume(TaskSource taskSource,
|
20
|
-
int
|
20
|
+
int taskCount,
|
21
21
|
FileOutputPlugin.Control control);
|
22
22
|
|
23
23
|
public void cleanup(TaskSource taskSource,
|
24
|
-
int
|
24
|
+
int taskCount,
|
25
25
|
List<CommitReport> successCommitReports);
|
26
26
|
|
27
|
-
public TransactionalFileOutput open(TaskSource taskSource, int
|
27
|
+
public TransactionalFileOutput open(TaskSource taskSource, int taskIndex);
|
28
28
|
}
|
@@ -56,19 +56,19 @@ public class FileOutputRunner
|
|
56
56
|
|
57
57
|
@Override
|
58
58
|
public ConfigDiff transaction(ConfigSource config,
|
59
|
-
final Schema schema, final int
|
59
|
+
final Schema schema, final int taskCount,
|
60
60
|
final OutputPlugin.Control control)
|
61
61
|
{
|
62
62
|
final RunnerTask task = config.loadConfig(RunnerTask.class);
|
63
|
-
return fileOutputPlugin.transaction(config,
|
63
|
+
return fileOutputPlugin.transaction(config, taskCount, new RunnerControl(schema, task, control));
|
64
64
|
}
|
65
65
|
|
66
66
|
public ConfigDiff resume(TaskSource taskSource,
|
67
|
-
Schema schema, int
|
67
|
+
Schema schema, int taskCount,
|
68
68
|
final OutputPlugin.Control control)
|
69
69
|
{
|
70
70
|
final RunnerTask task = taskSource.loadTask(RunnerTask.class);
|
71
|
-
return fileOutputPlugin.resume(task.getFileOutputTaskSource(),
|
71
|
+
return fileOutputPlugin.resume(task.getFileOutputTaskSource(), taskCount, new RunnerControl(schema, task, control));
|
72
72
|
}
|
73
73
|
|
74
74
|
private class RunnerControl
|
@@ -113,14 +113,14 @@ public class FileOutputRunner
|
|
113
113
|
}
|
114
114
|
|
115
115
|
public void cleanup(TaskSource taskSource,
|
116
|
-
Schema schema, int
|
116
|
+
Schema schema, int taskCount,
|
117
117
|
List<CommitReport> successCommitReports)
|
118
118
|
{
|
119
|
-
fileOutputPlugin.cleanup(taskSource,
|
119
|
+
fileOutputPlugin.cleanup(taskSource, taskCount, successCommitReports);
|
120
120
|
}
|
121
121
|
|
122
122
|
@Override
|
123
|
-
public TransactionalPageOutput open(TaskSource taskSource, Schema schema, int
|
123
|
+
public TransactionalPageOutput open(TaskSource taskSource, Schema schema, int taskIndex)
|
124
124
|
{
|
125
125
|
final RunnerTask task = taskSource.loadTask(RunnerTask.class);
|
126
126
|
List<EncoderPlugin> encoderPlugins = newEncoderPlugins(task);
|
@@ -130,7 +130,7 @@ public class FileOutputRunner
|
|
130
130
|
FileOutput fileOutput = null;
|
131
131
|
PageOutput output = null;
|
132
132
|
try {
|
133
|
-
fileOutput = tran = fileOutputPlugin.open(task.getFileOutputTaskSource(),
|
133
|
+
fileOutput = tran = fileOutputPlugin.open(task.getFileOutputTaskSource(), taskIndex);
|
134
134
|
|
135
135
|
fileOutput = Encoders.open(encoderPlugins, task.getEncoderTaskSources(), fileOutput);
|
136
136
|
output = formatterPlugin.open(task.getFormatterTaskSource(), schema, fileOutput);
|
@@ -11,21 +11,21 @@ public interface InputPlugin
|
|
11
11
|
public interface Control
|
12
12
|
{
|
13
13
|
public List<CommitReport> run(TaskSource taskSource,
|
14
|
-
Schema schema, int
|
14
|
+
Schema schema, int taskCount);
|
15
15
|
}
|
16
16
|
|
17
17
|
public ConfigDiff transaction(ConfigSource config,
|
18
18
|
InputPlugin.Control control);
|
19
19
|
|
20
20
|
public ConfigDiff resume(TaskSource taskSource,
|
21
|
-
Schema schema, int
|
21
|
+
Schema schema, int taskCount,
|
22
22
|
InputPlugin.Control control);
|
23
23
|
|
24
24
|
public void cleanup(TaskSource taskSource,
|
25
|
-
Schema schema, int
|
25
|
+
Schema schema, int taskCount,
|
26
26
|
List<CommitReport> successCommitReports);
|
27
27
|
|
28
28
|
public CommitReport run(TaskSource taskSource,
|
29
|
-
Schema schema, int
|
29
|
+
Schema schema, int taskIndex,
|
30
30
|
PageOutput output);
|
31
31
|
}
|
@@ -14,16 +14,16 @@ public interface OutputPlugin
|
|
14
14
|
}
|
15
15
|
|
16
16
|
public ConfigDiff transaction(ConfigSource config,
|
17
|
-
Schema schema, int
|
17
|
+
Schema schema, int taskCount,
|
18
18
|
OutputPlugin.Control control);
|
19
19
|
|
20
20
|
public ConfigDiff resume(TaskSource taskSource,
|
21
|
-
Schema schema, int
|
21
|
+
Schema schema, int taskCount,
|
22
22
|
OutputPlugin.Control control);
|
23
23
|
|
24
24
|
public void cleanup(TaskSource taskSource,
|
25
|
-
Schema schema, int
|
25
|
+
Schema schema, int taskCount,
|
26
26
|
List<CommitReport> successCommitReports);
|
27
27
|
|
28
|
-
public TransactionalPageOutput open(TaskSource taskSource, Schema schema, int
|
28
|
+
public TransactionalPageOutput open(TaskSource taskSource, Schema schema, int taskIndex);
|
29
29
|
}
|
@@ -10,14 +10,23 @@ public class FileOutputOutputStream
|
|
10
10
|
{
|
11
11
|
private final FileOutput out;
|
12
12
|
private final BufferAllocator allocator;
|
13
|
+
private final CloseMode closeMode;
|
13
14
|
private int pos;
|
14
15
|
private Buffer buffer;
|
15
16
|
|
16
|
-
public
|
17
|
+
public static enum CloseMode {
|
18
|
+
FLUSH,
|
19
|
+
FLUSH_FINISH,
|
20
|
+
FLUSH_FINISH_CLOSE,
|
21
|
+
CLOSE;
|
22
|
+
}
|
23
|
+
|
24
|
+
public FileOutputOutputStream(FileOutput out, BufferAllocator allocator, CloseMode closeMode)
|
17
25
|
{
|
18
26
|
this.out = out;
|
19
27
|
this.allocator = allocator;
|
20
28
|
this.buffer = allocator.allocate();
|
29
|
+
this.closeMode = closeMode;
|
21
30
|
}
|
22
31
|
|
23
32
|
public void nextFile()
|
@@ -25,6 +34,11 @@ public class FileOutputOutputStream
|
|
25
34
|
out.nextFile();
|
26
35
|
}
|
27
36
|
|
37
|
+
public void finish()
|
38
|
+
{
|
39
|
+
out.finish();
|
40
|
+
}
|
41
|
+
|
28
42
|
@Override
|
29
43
|
public void write(int b)
|
30
44
|
{
|
@@ -77,16 +91,26 @@ public class FileOutputOutputStream
|
|
77
91
|
}
|
78
92
|
}
|
79
93
|
|
80
|
-
public void finish()
|
81
|
-
{
|
82
|
-
doFlush();
|
83
|
-
out.finish();
|
84
|
-
}
|
85
|
-
|
86
94
|
@Override
|
87
95
|
public void close()
|
88
96
|
{
|
89
|
-
|
97
|
+
switch (closeMode) {
|
98
|
+
case FLUSH:
|
99
|
+
doFlush();
|
100
|
+
break;
|
101
|
+
case FLUSH_FINISH:
|
102
|
+
doFlush();
|
103
|
+
out.finish();
|
104
|
+
break;
|
105
|
+
case FLUSH_FINISH_CLOSE:
|
106
|
+
doFlush();
|
107
|
+
out.finish();
|
108
|
+
out.close();
|
109
|
+
break;
|
110
|
+
case CLOSE:
|
111
|
+
out.close();
|
112
|
+
break;
|
113
|
+
}
|
90
114
|
buffer.release();
|
91
115
|
buffer = Buffer.EMPTY;
|
92
116
|
pos = 0;
|
@@ -64,7 +64,7 @@ public class InputStreamFileInput
|
|
64
64
|
{
|
65
65
|
// TODO check current != null and throw Illegal State - file is not opened
|
66
66
|
if (current == null) {
|
67
|
-
throw new IllegalStateException("
|
67
|
+
throw new IllegalStateException("nextFile() must be called before poll()");
|
68
68
|
}
|
69
69
|
Buffer buffer = allocator.allocate();
|
70
70
|
try {
|
@@ -44,7 +44,7 @@ public class LineEncoder
|
|
44
44
|
.onMalformedInput(CodingErrorAction.REPLACE) // TODO configurable?
|
45
45
|
.onUnmappableCharacter(CodingErrorAction.REPLACE); // TODO configurable?
|
46
46
|
this.newline = task.getNewline().getString();
|
47
|
-
this.outputStream = new FileOutputOutputStream(out, task.getBufferAllocator());
|
47
|
+
this.outputStream = new FileOutputOutputStream(out, task.getBufferAllocator(), FileOutputOutputStream.CloseMode.CLOSE);
|
48
48
|
this.writer = new OutputStreamWriter(outputStream, encoder);
|
49
49
|
}
|
50
50
|
|
@@ -93,12 +93,11 @@ public class LineEncoder
|
|
93
93
|
public void finish()
|
94
94
|
{
|
95
95
|
try {
|
96
|
-
writer.flush();
|
97
|
-
outputStream.finish();
|
98
|
-
writer.close();
|
96
|
+
writer.flush();
|
99
97
|
} catch (IOException ex) {
|
100
98
|
throw new RuntimeException(ex);
|
101
99
|
}
|
100
|
+
outputStream.finish();
|
102
101
|
}
|
103
102
|
|
104
103
|
@Override
|
@@ -0,0 +1,88 @@
|
|
1
|
+
package org.embulk.spi.util;
|
2
|
+
|
3
|
+
import java.io.OutputStream;
|
4
|
+
import java.io.Closeable;
|
5
|
+
import java.io.IOException;
|
6
|
+
import org.embulk.spi.Buffer;
|
7
|
+
import org.embulk.spi.FileOutput;
|
8
|
+
|
9
|
+
public class OutputStreamFileOutput
|
10
|
+
implements FileOutput
|
11
|
+
{
|
12
|
+
public interface Provider extends Closeable
|
13
|
+
{
|
14
|
+
public OutputStream openNext() throws IOException;
|
15
|
+
|
16
|
+
public void finish() throws IOException;
|
17
|
+
|
18
|
+
public void close() throws IOException;
|
19
|
+
}
|
20
|
+
|
21
|
+
private final Provider provider;
|
22
|
+
private OutputStream current;
|
23
|
+
|
24
|
+
public OutputStreamFileOutput(Provider provider)
|
25
|
+
{
|
26
|
+
this.provider = provider;
|
27
|
+
this.current = null;
|
28
|
+
}
|
29
|
+
|
30
|
+
public void nextFile()
|
31
|
+
{
|
32
|
+
closeCurrent();
|
33
|
+
try {
|
34
|
+
current = provider.openNext();
|
35
|
+
} catch (IOException ex) {
|
36
|
+
throw new RuntimeException(ex);
|
37
|
+
}
|
38
|
+
}
|
39
|
+
|
40
|
+
public void add(Buffer buffer)
|
41
|
+
{
|
42
|
+
if (current == null) {
|
43
|
+
throw new IllegalStateException("nextFile() must be called before poll()");
|
44
|
+
}
|
45
|
+
try {
|
46
|
+
current.write(buffer.array(), buffer.offset(), buffer.limit());
|
47
|
+
} catch (IOException ex) {
|
48
|
+
throw new RuntimeException(ex);
|
49
|
+
} finally {
|
50
|
+
buffer.release();
|
51
|
+
}
|
52
|
+
}
|
53
|
+
|
54
|
+
public void finish()
|
55
|
+
{
|
56
|
+
closeCurrent();
|
57
|
+
try {
|
58
|
+
provider.finish();
|
59
|
+
} catch (IOException ex) {
|
60
|
+
throw new RuntimeException(ex);
|
61
|
+
}
|
62
|
+
}
|
63
|
+
|
64
|
+
public void close()
|
65
|
+
{
|
66
|
+
try {
|
67
|
+
closeCurrent();
|
68
|
+
} finally {
|
69
|
+
try {
|
70
|
+
provider.close();
|
71
|
+
} catch (IOException ex) {
|
72
|
+
throw new RuntimeException(ex);
|
73
|
+
}
|
74
|
+
}
|
75
|
+
}
|
76
|
+
|
77
|
+
private void closeCurrent()
|
78
|
+
{
|
79
|
+
try {
|
80
|
+
if (current != null) {
|
81
|
+
current.close();
|
82
|
+
current = null;
|
83
|
+
}
|
84
|
+
} catch (IOException ex) {
|
85
|
+
throw new RuntimeException(ex);
|
86
|
+
}
|
87
|
+
}
|
88
|
+
}
|