embulk 0.6.2 → 0.6.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -1
- data/bin/embulk +2 -2
- data/build.gradle +11 -2
- data/embulk-cli/src/main/java/org/embulk/cli/Main.java +0 -2
- data/embulk-core/build.gradle +1 -1
- data/embulk-core/src/main/java/org/embulk/command/Runner.java +10 -0
- data/embulk-core/src/main/java/org/embulk/exec/GuessExecutor.java +3 -2
- data/embulk-core/src/main/java/org/embulk/exec/PreviewExecutor.java +1 -1
- data/embulk-core/src/main/java/org/embulk/jruby/JRubyScriptingModule.java +18 -6
- data/embulk-core/src/main/java/org/embulk/plugin/PluginManager.java +14 -11
- data/embulk-core/src/main/java/org/embulk/spi/Column.java +5 -5
- data/embulk-core/src/main/java/org/embulk/spi/ColumnConfig.java +4 -4
- data/embulk-core/src/main/java/org/embulk/spi/Exec.java +6 -0
- data/embulk-core/src/main/java/org/embulk/spi/FileInputRunner.java +1 -1
- data/embulk-core/src/main/java/org/embulk/spi/Schema.java +2 -2
- data/embulk-core/src/main/java/org/embulk/spi/SchemaConfig.java +2 -2
- data/embulk-core/src/main/java/org/embulk/spi/unit/ByteSize.java +148 -0
- data/embulk-core/src/test/java/org/embulk/spi/unit/TestByteSize.java +79 -0
- data/embulk-docs/build.gradle +5 -1
- data/embulk-docs/src/customization.rst +184 -0
- data/embulk-docs/src/index.rst +10 -1
- data/embulk-docs/src/release.rst +1 -0
- data/embulk-docs/src/release/release-0.6.3.rst +23 -0
- data/lib/embulk/command/embulk_run.rb +41 -3
- data/lib/embulk/data/new/gitignore.erb +1 -0
- data/lib/embulk/data/new/java/build.gradle.erb +20 -4
- data/lib/embulk/java/bootstrap.rb +2 -2
- data/lib/embulk/plugin.rb +1 -1
- data/lib/embulk/version.rb +1 -1
- data/test/helper.rb +7 -0
- metadata +8 -6
- data/embulk-docs/plugins/index.html.erb +0 -73
- data/embulk-docs/plugins/plugins.css +0 -148
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b37c9dd1d3a700e0057040d27f0a29e917e21b13
|
4
|
+
data.tar.gz: 3372de3c3f382dc6f83bea6936d84af3b815194c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7d0c416b6c063508b95d23941c5cf97149bcf6fd11134392f79d0d7540f106df019e502fc7296ba47a94a945a64c8b34a4d4aaf682227d390300592d598c0f1a
|
7
|
+
data.tar.gz: b370deb8322442973cc3109ca2a0b8eb3931d11840f55e7d230f56c10de45c93a71d39cb892dad491ef67870c9e77932fabee4d82cf99ea601ba3417ea3e7cc8
|
data/.travis.yml
CHANGED
data/bin/embulk
CHANGED
@@ -69,9 +69,9 @@ unless jruby_complete
|
|
69
69
|
end
|
70
70
|
|
71
71
|
if overwrite_optimize == true || (default_optimize == true && overwrite_optimize != false)
|
72
|
-
|
72
|
+
java_args = %w[-XX:+AggressiveOpts -XX:+UseConcMarkSweepGC] + java_args
|
73
73
|
else
|
74
|
-
|
74
|
+
java_args = %w[-XX:+AggressiveOpts -XX:+TieredCompilation -XX:TieredStopAtLevel=1 -Xverify:none] + java_args
|
75
75
|
end
|
76
76
|
|
77
77
|
# java ... -jar ruby-complete.jar $EMBULK_HOME/lib/embulk/command/embulk.rb "$@"
|
data/build.gradle
CHANGED
@@ -5,14 +5,17 @@ plugins {
|
|
5
5
|
id 'com.github.jruby-gradle.base' version '0.1.5'
|
6
6
|
id 'com.github.johnrengelman.shadow' version '1.2.0'
|
7
7
|
}
|
8
|
-
import com.github.jrubygradle.JRubyExec
|
9
8
|
|
10
9
|
def java_projects = [project(":embulk-core"), project(":embulk-standards"), project(":embulk-cli")]
|
11
10
|
def release_projects = [project(":embulk-core"), project(":embulk-standards")]
|
12
11
|
|
13
12
|
allprojects {
|
14
13
|
group = 'org.embulk'
|
15
|
-
version = '0.6.
|
14
|
+
version = '0.6.3'
|
15
|
+
|
16
|
+
ext {
|
17
|
+
jrubyVersion = '1.7.19'
|
18
|
+
}
|
16
19
|
|
17
20
|
apply plugin: 'java'
|
18
21
|
apply plugin: 'maven-publish'
|
@@ -137,6 +140,11 @@ subprojects {
|
|
137
140
|
}
|
138
141
|
}
|
139
142
|
|
143
|
+
import com.github.jrubygradle.JRubyExec
|
144
|
+
jruby {
|
145
|
+
execVersion = project.jrubyVersion
|
146
|
+
}
|
147
|
+
|
140
148
|
dependencies {
|
141
149
|
jrubyExec 'rubygems:test-unit:3.0.+'
|
142
150
|
}
|
@@ -187,6 +195,7 @@ task rubyTest(type: JRubyExec) {
|
|
187
195
|
jrubyArgs '-Ilib', '-Itest', '-rtest/unit', '-eTest::Unit::AutoRunner.run(true, *ARGV)'
|
188
196
|
script 'test'
|
189
197
|
}
|
198
|
+
rubyTest.dependsOn('classpath')
|
190
199
|
|
191
200
|
//
|
192
201
|
// gem task
|
@@ -4,8 +4,6 @@ public class Main
|
|
4
4
|
{
|
5
5
|
public static void main(String[] args)
|
6
6
|
{
|
7
|
-
// TODO set GEM_HOME to point the internal gem repository created by gem-maven-plugin?
|
8
|
-
|
9
7
|
// $ java -jar jruby-complete.jar classpath:embulk/command/embulk.rb "$@"
|
10
8
|
String[] jrubyArgs = new String[args.length + 1];
|
11
9
|
jrubyArgs[0] = "classpath:embulk/command/embulk.rb";
|
data/embulk-core/build.gradle
CHANGED
@@ -27,7 +27,7 @@ dependencies {
|
|
27
27
|
compile 'log4j:log4j:1.2.17'
|
28
28
|
compile 'org.slf4j:slf4j-api:1.7.10'
|
29
29
|
compile 'org.slf4j:slf4j-log4j12:1.7.10'
|
30
|
-
compile 'org.jruby:jruby-complete:
|
30
|
+
compile 'org.jruby:jruby-complete:' + project.jrubyVersion
|
31
31
|
compile 'com.google.code.findbugs:annotations:3.0.0'
|
32
32
|
compile 'org.yaml:snakeyaml:1.14'
|
33
33
|
compile 'javax.validation:validation-api:1.1.0.Final'
|
@@ -50,6 +50,9 @@ public class Runner
|
|
50
50
|
|
51
51
|
private List<PluginType> guessPlugins;
|
52
52
|
public List<PluginType> getGuessPlugins() { return guessPlugins; }
|
53
|
+
|
54
|
+
private boolean useGlobalRubyRuntime;
|
55
|
+
public boolean getUseGlobalRubyRuntime() { return useGlobalRubyRuntime; }
|
53
56
|
}
|
54
57
|
|
55
58
|
private final Options options;
|
@@ -72,16 +75,23 @@ public class Runner
|
|
72
75
|
{
|
73
76
|
String logLevel = options.getLogLevel();
|
74
77
|
if (logLevel != null) {
|
78
|
+
// used by LoggerProvider
|
75
79
|
systemConfig.set("log_level", logLevel);
|
76
80
|
}
|
77
81
|
|
78
82
|
List<PluginType> guessPlugins = options.getGuessPlugins();
|
79
83
|
if (guessPlugins != null && !guessPlugins.isEmpty()) {
|
84
|
+
// used by GuessExecutor
|
80
85
|
List<PluginType> list = new ArrayList<PluginType>() { };
|
81
86
|
list = systemConfig.get((Class<List<PluginType>>) list.getClass(), "guess_plugins", list);
|
82
87
|
list.addAll(guessPlugins);
|
83
88
|
systemConfig.set("guess_plugins", list);
|
84
89
|
}
|
90
|
+
|
91
|
+
if (options.getUseGlobalRubyRuntime()) {
|
92
|
+
// used by JRubyScriptingModule
|
93
|
+
systemConfig.set("use_global_ruby_runtime", true);
|
94
|
+
}
|
85
95
|
}
|
86
96
|
|
87
97
|
public void main(String command, String[] args)
|
@@ -3,6 +3,7 @@ package org.embulk.exec;
|
|
3
3
|
import java.util.List;
|
4
4
|
import java.util.Set;
|
5
5
|
import java.util.ArrayList;
|
6
|
+
import java.util.concurrent.ExecutionException;
|
6
7
|
import com.google.common.collect.ImmutableList;
|
7
8
|
import com.google.common.base.Throwables;
|
8
9
|
import com.google.inject.Inject;
|
@@ -87,8 +88,8 @@ public class GuessExecutor
|
|
87
88
|
}
|
88
89
|
}
|
89
90
|
});
|
90
|
-
} catch (
|
91
|
-
throw Throwables.propagate(ex);
|
91
|
+
} catch (ExecutionException ex) {
|
92
|
+
throw Throwables.propagate(ex.getCause());
|
92
93
|
}
|
93
94
|
}
|
94
95
|
|
@@ -16,10 +16,12 @@ import com.google.inject.Key;
|
|
16
16
|
import com.google.inject.spi.Dependency;
|
17
17
|
import com.google.inject.spi.ProviderWithDependencies;
|
18
18
|
import org.jruby.CompatVersion;
|
19
|
+
import org.jruby.embed.LocalContextScope;
|
19
20
|
import org.jruby.embed.ScriptingContainer;
|
20
21
|
import org.embulk.plugin.PluginSource;
|
21
22
|
import org.embulk.config.ConfigSource;
|
22
23
|
import org.embulk.config.ModelManager;
|
24
|
+
import org.embulk.exec.ForSystemConfig;
|
23
25
|
import org.embulk.spi.BufferAllocator;
|
24
26
|
|
25
27
|
public class JRubyScriptingModule
|
@@ -27,15 +29,12 @@ public class JRubyScriptingModule
|
|
27
29
|
{
|
28
30
|
public JRubyScriptingModule(ConfigSource systemConfig)
|
29
31
|
{
|
30
|
-
// TODO get jruby-home from systemConfig to call jruby.container.setHomeDirectory
|
31
|
-
// TODO get jruby-load-paths from systemConfig to call jruby.container.setLoadPaths
|
32
32
|
}
|
33
33
|
|
34
34
|
@Override
|
35
35
|
public void configure(Binder binder)
|
36
36
|
{
|
37
37
|
binder.bind(ScriptingContainer.class).toProvider(ScriptingContainerProvider.class).in(Scopes.SINGLETON);
|
38
|
-
//binder.bind(JRubyModule.class).in(Scopes.SINGLETON);
|
39
38
|
|
40
39
|
Multibinder<PluginSource> multibinder = Multibinder.newSetBinder(binder, PluginSource.class);
|
41
40
|
multibinder.addBinding().to(JRubyPluginSource.class);
|
@@ -45,16 +44,25 @@ public class JRubyScriptingModule
|
|
45
44
|
implements ProviderWithDependencies<ScriptingContainer>
|
46
45
|
{
|
47
46
|
private final Injector injector;
|
47
|
+
private final boolean useGlobalRubyRuntime;
|
48
48
|
|
49
49
|
@Inject
|
50
|
-
public ScriptingContainerProvider(Injector injector)
|
50
|
+
public ScriptingContainerProvider(Injector injector, @ForSystemConfig ConfigSource systemConfig)
|
51
51
|
{
|
52
52
|
this.injector = injector;
|
53
|
+
|
54
|
+
// use_global_ruby_runtime is valid only when it's guaranteed that just one Injector is
|
55
|
+
// instantiated in this JVM.
|
56
|
+
this.useGlobalRubyRuntime = systemConfig.get(boolean.class, "use_global_ruby_runtime", false);
|
57
|
+
|
58
|
+
// TODO get jruby-home from systemConfig to call jruby.container.setHomeDirectory
|
59
|
+
// TODO get jruby-load-paths from systemConfig to call jruby.container.setLoadPaths
|
53
60
|
}
|
54
61
|
|
55
62
|
public ScriptingContainer get()
|
56
63
|
{
|
57
|
-
|
64
|
+
LocalContextScope scope = (useGlobalRubyRuntime ? LocalContextScope.SINGLETON : LocalContextScope.SINGLETHREAD);
|
65
|
+
ScriptingContainer jruby = new ScriptingContainer(scope);
|
58
66
|
jruby.setCompatVersion(CompatVersion.RUBY1_9);
|
59
67
|
|
60
68
|
// Search embulk/java/bootstrap.rb from a $LOAD_PATH.
|
@@ -72,9 +80,13 @@ public class JRubyScriptingModule
|
|
72
80
|
// jruby searches embulk/java/bootstrap.rb from the beginning of $LOAD_PATH.
|
73
81
|
jruby.runScriptlet("require 'embulk/java/bootstrap'");
|
74
82
|
|
83
|
+
// TODO validate Embulk::Java::Injected::Injector doesn't exist? If it already exists,
|
84
|
+
// Injector is created more than once in this JVM although use_global_ruby_runtime
|
85
|
+
// is set to true.
|
86
|
+
|
75
87
|
// set some constants
|
76
88
|
jruby.callMethod(
|
77
|
-
jruby.runScriptlet("Embulk::Java"),
|
89
|
+
jruby.runScriptlet("Embulk::Java::Injected"),
|
78
90
|
"const_set", "Injector", injector);
|
79
91
|
jruby.callMethod(
|
80
92
|
jruby.runScriptlet("Embulk::Java::Injected"),
|
@@ -13,7 +13,7 @@ public class PluginManager
|
|
13
13
|
private final List<PluginSource> sources;
|
14
14
|
private final Injector injector;
|
15
15
|
|
16
|
-
// Set<PluginSource> is injected BuiltinPluginSourceModule or extensions
|
16
|
+
// Set<PluginSource> is injected by BuiltinPluginSourceModule or extensions
|
17
17
|
// using Multibinder<PluginSource>.
|
18
18
|
@Inject
|
19
19
|
public PluginManager(Set<PluginSource> pluginSources, Injector injector)
|
@@ -32,31 +32,34 @@ public class PluginManager
|
|
32
32
|
throw new ConfigException(String.format("%s type is not set (if you intend to use NullOutputPlugin, you should enclose null in quotes such as {type: \"null\"}.", iface.getSimpleName()));
|
33
33
|
}
|
34
34
|
|
35
|
-
List<
|
35
|
+
List<PluginSourceNotMatchException> exceptions = new ArrayList<>();
|
36
36
|
for (PluginSource source : sources) {
|
37
37
|
try {
|
38
38
|
return source.newPlugin(iface, type);
|
39
39
|
} catch (PluginSourceNotMatchException e) {
|
40
|
-
|
41
|
-
causes.add(e.getCause());
|
42
|
-
} else {
|
43
|
-
causes.add(e);
|
44
|
-
}
|
40
|
+
exceptions.add(e);
|
45
41
|
}
|
46
42
|
}
|
47
43
|
|
44
|
+
throw buildPluginNotFoundException(iface, type, exceptions);
|
45
|
+
}
|
46
|
+
|
47
|
+
private static ConfigException buildPluginNotFoundException(Class<?> iface, PluginType type,
|
48
|
+
List<PluginSourceNotMatchException> exceptions)
|
49
|
+
{
|
48
50
|
StringBuilder message = new StringBuilder();
|
49
51
|
message.append(String.format("%s '%s' is not found.", iface.getSimpleName(), type.getName()));
|
50
|
-
for (
|
52
|
+
for (PluginSourceNotMatchException exception : exceptions) {
|
53
|
+
Throwable cause = (exception.getCause() == null ? exception : exception.getCause());
|
51
54
|
if (cause.getMessage() != null) {
|
52
55
|
message.append(String.format("%n"));
|
53
56
|
message.append(cause.getMessage());
|
54
57
|
}
|
55
58
|
}
|
56
59
|
ConfigException e = new ConfigException(message.toString());
|
57
|
-
for (
|
58
|
-
e.addSuppressed(
|
60
|
+
for (PluginSourceNotMatchException exception : exceptions) {
|
61
|
+
e.addSuppressed(exception);
|
59
62
|
}
|
60
|
-
|
63
|
+
return e;
|
61
64
|
}
|
62
65
|
}
|
@@ -1,6 +1,6 @@
|
|
1
1
|
package org.embulk.spi;
|
2
2
|
|
3
|
-
import
|
3
|
+
import java.util.Objects;
|
4
4
|
import com.fasterxml.jackson.annotation.JsonCreator;
|
5
5
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
6
6
|
import org.embulk.spi.type.Type;
|
@@ -72,15 +72,15 @@ public class Column
|
|
72
72
|
return false;
|
73
73
|
}
|
74
74
|
Column other = (Column) obj;
|
75
|
-
return Objects.
|
76
|
-
Objects.
|
77
|
-
Objects.
|
75
|
+
return Objects.equals(index, other.index) &&
|
76
|
+
Objects.equals(name, other.name) &&
|
77
|
+
Objects.equals(type, other.type);
|
78
78
|
}
|
79
79
|
|
80
80
|
@Override
|
81
81
|
public int hashCode()
|
82
82
|
{
|
83
|
-
return Objects.
|
83
|
+
return Objects.hash(index, name, type);
|
84
84
|
}
|
85
85
|
|
86
86
|
@Override
|
@@ -1,6 +1,6 @@
|
|
1
1
|
package org.embulk.spi;
|
2
2
|
|
3
|
-
import
|
3
|
+
import java.util.Objects;
|
4
4
|
import com.fasterxml.jackson.annotation.JsonCreator;
|
5
5
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
6
6
|
import org.embulk.spi.type.Type;
|
@@ -60,14 +60,14 @@ public class ColumnConfig
|
|
60
60
|
return false;
|
61
61
|
}
|
62
62
|
ColumnConfig other = (ColumnConfig) obj;
|
63
|
-
return Objects.
|
64
|
-
Objects.
|
63
|
+
return Objects.equals(this.name, other.name) &&
|
64
|
+
Objects.equals(type, other.type);
|
65
65
|
}
|
66
66
|
|
67
67
|
@Override
|
68
68
|
public int hashCode()
|
69
69
|
{
|
70
|
-
return Objects.
|
70
|
+
return Objects.hash(name, type);
|
71
71
|
}
|
72
72
|
|
73
73
|
@Override
|
@@ -2,6 +2,7 @@ package org.embulk.spi;
|
|
2
2
|
|
3
3
|
import java.util.concurrent.ExecutionException;
|
4
4
|
import org.slf4j.Logger;
|
5
|
+
import com.google.inject.Injector;
|
5
6
|
import org.embulk.config.Task;
|
6
7
|
import org.embulk.config.ModelManager;
|
7
8
|
import org.embulk.config.CommitReport;
|
@@ -38,6 +39,11 @@ public class Exec
|
|
38
39
|
return session;
|
39
40
|
}
|
40
41
|
|
42
|
+
public static Injector getInjector()
|
43
|
+
{
|
44
|
+
return session().getInjector();
|
45
|
+
}
|
46
|
+
|
41
47
|
public static Logger getLogger(String name)
|
42
48
|
{
|
43
49
|
return session().getLogger(name);
|
@@ -80,7 +80,7 @@ public class FileInputRunner
|
|
80
80
|
throw new NoSampleException("Can't get sample data because the first input file is empty");
|
81
81
|
}
|
82
82
|
|
83
|
-
GuessExecutor guessExecutor = Exec.
|
83
|
+
GuessExecutor guessExecutor = Exec.getInjector().getInstance(GuessExecutor.class);
|
84
84
|
return guessExecutor.guessParserConfig(sample, config, Exec.session().getExecConfig());
|
85
85
|
}
|
86
86
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
package org.embulk.spi;
|
2
2
|
|
3
3
|
import java.util.List;
|
4
|
-
import
|
4
|
+
import java.util.Objects;
|
5
5
|
import com.fasterxml.jackson.annotation.JsonCreator;
|
6
6
|
import com.fasterxml.jackson.annotation.JsonValue;
|
7
7
|
import org.embulk.spi.type.Type;
|
@@ -78,7 +78,7 @@ public class Schema
|
|
78
78
|
return false;
|
79
79
|
}
|
80
80
|
Schema other = (Schema) obj;
|
81
|
-
return Objects.
|
81
|
+
return Objects.equals(columns, other.columns);
|
82
82
|
}
|
83
83
|
|
84
84
|
@Override
|
@@ -1,7 +1,7 @@
|
|
1
1
|
package org.embulk.spi;
|
2
2
|
|
3
3
|
import java.util.List;
|
4
|
-
import
|
4
|
+
import java.util.Objects;
|
5
5
|
import com.google.common.collect.ImmutableList;
|
6
6
|
import com.fasterxml.jackson.annotation.JsonCreator;
|
7
7
|
import com.fasterxml.jackson.annotation.JsonValue;
|
@@ -41,7 +41,7 @@ public class SchemaConfig
|
|
41
41
|
return false;
|
42
42
|
}
|
43
43
|
SchemaConfig other = (SchemaConfig) obj;
|
44
|
-
return Objects.
|
44
|
+
return Objects.equals(columns, other.columns);
|
45
45
|
}
|
46
46
|
|
47
47
|
@Override
|
@@ -0,0 +1,148 @@
|
|
1
|
+
package org.embulk.spi.unit;
|
2
|
+
|
3
|
+
import java.util.Objects;
|
4
|
+
import java.util.Locale;
|
5
|
+
import java.util.regex.Matcher;
|
6
|
+
import java.util.regex.Pattern;
|
7
|
+
import com.google.common.base.Preconditions;
|
8
|
+
import com.fasterxml.jackson.annotation.JsonCreator;
|
9
|
+
import com.fasterxml.jackson.annotation.JsonValue;
|
10
|
+
|
11
|
+
public class ByteSize
|
12
|
+
implements Comparable<ByteSize>
|
13
|
+
{
|
14
|
+
private static final Pattern PATTERN = Pattern.compile("\\A(\\d+(?:\\.\\d+)?)\\s?([a-zA-Z]*)\\z");
|
15
|
+
|
16
|
+
private final long bytes;
|
17
|
+
private final Unit displayUnit;
|
18
|
+
|
19
|
+
public ByteSize(double size, Unit unit)
|
20
|
+
{
|
21
|
+
Preconditions.checkArgument(!Double.isInfinite(size), "size is infinite");
|
22
|
+
Preconditions.checkArgument(!Double.isNaN(size), "size is not a number");
|
23
|
+
Preconditions.checkArgument(size >= 0, "size is negative");
|
24
|
+
Preconditions.checkNotNull(unit, "unit is null");
|
25
|
+
Preconditions.checkArgument(size * unit.getFactor() <= (double) Long.MAX_VALUE, "size is large than (2^63)-1 in bytes");
|
26
|
+
this.bytes = (long) (size * unit.getFactor());
|
27
|
+
this.displayUnit = unit;
|
28
|
+
}
|
29
|
+
|
30
|
+
@JsonCreator
|
31
|
+
public ByteSize(long bytes)
|
32
|
+
{
|
33
|
+
Preconditions.checkArgument(bytes >= 0, "size is negative");
|
34
|
+
this.bytes = bytes;
|
35
|
+
this.displayUnit = Unit.BYTES;
|
36
|
+
}
|
37
|
+
|
38
|
+
public long getBytes()
|
39
|
+
{
|
40
|
+
return bytes;
|
41
|
+
}
|
42
|
+
|
43
|
+
public long roundTo(Unit unit)
|
44
|
+
{
|
45
|
+
return (long) Math.floor(getValue(unit) + 0.5);
|
46
|
+
}
|
47
|
+
|
48
|
+
public double getValue(Unit unit)
|
49
|
+
{
|
50
|
+
return bytes / (double) unit.getFactor();
|
51
|
+
}
|
52
|
+
|
53
|
+
@JsonCreator
|
54
|
+
public static ByteSize parseByteSize(String size)
|
55
|
+
{
|
56
|
+
Preconditions.checkNotNull(size, "size is null");
|
57
|
+
Preconditions.checkArgument(!size.isEmpty(), "size is empty");
|
58
|
+
|
59
|
+
Matcher matcher = PATTERN.matcher(size);
|
60
|
+
if (!matcher.matches()) {
|
61
|
+
throw new IllegalArgumentException("Invalid byte size string '" + size + "'");
|
62
|
+
}
|
63
|
+
|
64
|
+
double value = Double.parseDouble(matcher.group(1)); // NumberFormatException extends IllegalArgumentException.
|
65
|
+
|
66
|
+
String unitString = matcher.group(2);
|
67
|
+
if (unitString.isEmpty()) {
|
68
|
+
return new ByteSize(value, Unit.BYTES);
|
69
|
+
} else {
|
70
|
+
String upperUnitString = unitString.toUpperCase(Locale.ENGLISH);
|
71
|
+
for (Unit unit : Unit.values()) {
|
72
|
+
if (unit.getUnitString().toUpperCase(Locale.ENGLISH).equals(upperUnitString)) {
|
73
|
+
return new ByteSize(value, unit);
|
74
|
+
}
|
75
|
+
}
|
76
|
+
}
|
77
|
+
|
78
|
+
throw new IllegalArgumentException("Unknown unit '" + unitString + "'");
|
79
|
+
}
|
80
|
+
|
81
|
+
@JsonValue
|
82
|
+
@Override
|
83
|
+
public String toString()
|
84
|
+
{
|
85
|
+
double value = getValue(displayUnit);
|
86
|
+
String integer = String.format(Locale.ENGLISH, "%d", (long) value);
|
87
|
+
String decimal = String.format(Locale.ENGLISH, "%.2f", value);
|
88
|
+
if (decimal.equals(integer + ".00")) {
|
89
|
+
return integer + displayUnit.getUnitString();
|
90
|
+
} else {
|
91
|
+
return decimal + displayUnit.getUnitString();
|
92
|
+
}
|
93
|
+
}
|
94
|
+
|
95
|
+
@Override
|
96
|
+
public int compareTo(ByteSize o)
|
97
|
+
{
|
98
|
+
return Long.compare(bytes, o.bytes);
|
99
|
+
}
|
100
|
+
|
101
|
+
@Override
|
102
|
+
public boolean equals(Object obj)
|
103
|
+
{
|
104
|
+
if (this == obj) {
|
105
|
+
return true;
|
106
|
+
}
|
107
|
+
if (!(obj instanceof ByteSize)) {
|
108
|
+
return false;
|
109
|
+
}
|
110
|
+
ByteSize o = (ByteSize) obj;
|
111
|
+
return this.bytes == o.bytes;
|
112
|
+
}
|
113
|
+
|
114
|
+
@Override
|
115
|
+
public int hashCode()
|
116
|
+
{
|
117
|
+
return Objects.hashCode(bytes);
|
118
|
+
}
|
119
|
+
|
120
|
+
public enum Unit
|
121
|
+
{
|
122
|
+
BYTES(1L, "B"),
|
123
|
+
KB(1L << 10, "KB"),
|
124
|
+
MB(1L << 20, "MB"),
|
125
|
+
GB(1L << 30, "GB"),
|
126
|
+
TB(1L << 40, "TB"),
|
127
|
+
PT(1L << 50, "PB");
|
128
|
+
|
129
|
+
private final long factor;
|
130
|
+
private final String unitString;
|
131
|
+
|
132
|
+
Unit(long factor, String unitString)
|
133
|
+
{
|
134
|
+
this.factor = factor;
|
135
|
+
this.unitString = unitString;
|
136
|
+
}
|
137
|
+
|
138
|
+
long getFactor()
|
139
|
+
{
|
140
|
+
return factor;
|
141
|
+
}
|
142
|
+
|
143
|
+
String getUnitString()
|
144
|
+
{
|
145
|
+
return unitString;
|
146
|
+
}
|
147
|
+
}
|
148
|
+
}
|