add json parsers and benchmarks
This commit is contained in:
parent
3a6dedfd46
commit
ace846e5ad
1107 changed files with 113765 additions and 101222 deletions
21
benchmark/build.gradle
Normal file
21
benchmark/build.gradle
Normal file
|
@ -0,0 +1,21 @@
|
|||
plugins {
|
||||
id "io.morethan.jmhreport" version "0.9.0"
|
||||
}
|
||||
|
||||
jmhReport {
|
||||
jmhResultPath = project.file('build/reports/jmh/result.json')
|
||||
jmhReportOutput = project.file('build/reports/jmh')
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation project(':datastructures-json')
|
||||
implementation project(':datastructures-json-dsl')
|
||||
implementation project(':datastructures-json-flat')
|
||||
implementation project(':datastructures-json-iterator')
|
||||
implementation project(':datastructures-json-minimal')
|
||||
implementation project(':datastructures-json-noggit')
|
||||
implementation project(':datastructures-json-simple')
|
||||
implementation "com.google.code.gson:gson:${project.property('gson.version')}"
|
||||
implementation "com.fasterxml.jackson.core:jackson-databind:${project.property('jackson.version')}"
|
||||
implementation "org.json:json:${project.property('orgjson.version')}"
|
||||
}
|
|
@ -0,0 +1,129 @@
|
|||
package org.xbib.datastructures.benchmark;
|
||||
|
||||
import com.dslplatform.json.DslJson;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.google.gson.Gson;
|
||||
import org.openjdk.jmh.annotations.Benchmark;
|
||||
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||
import org.openjdk.jmh.annotations.Fork;
|
||||
import org.openjdk.jmh.annotations.Level;
|
||||
import org.openjdk.jmh.annotations.Measurement;
|
||||
import org.openjdk.jmh.annotations.Mode;
|
||||
import org.openjdk.jmh.annotations.Scope;
|
||||
import org.openjdk.jmh.annotations.Setup;
|
||||
import org.openjdk.jmh.annotations.State;
|
||||
import org.openjdk.jmh.annotations.Threads;
|
||||
import org.openjdk.jmh.annotations.Timeout;
|
||||
import org.openjdk.jmh.annotations.Warmup;
|
||||
import org.xbib.datastructures.json.EmptyJsonListener;
|
||||
import org.xbib.datastructures.json.StandardJsonListener;
|
||||
import org.xbib.datastructures.json.StringParser;
|
||||
import org.xbib.datastructures.json.TinyJsonListener;
|
||||
import org.xbib.datastructures.json.flat.Json;
|
||||
import org.xbib.datastructures.json.noggit.ObjectBuilder;
|
||||
import org.xbib.datastructures.json.simple.JSONParser;
|
||||
import org.xbib.datastructures.json.simple.ParseException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@State(Scope.Benchmark)
|
||||
@BenchmarkMode(Mode.Throughput)
|
||||
@Warmup(iterations = 5)
|
||||
@Measurement(iterations = 5)
|
||||
@Fork(value = 1, jvmArgsAppend = "-Xmx1024m")
|
||||
@Threads(4)
|
||||
@Timeout(time = 10, timeUnit = TimeUnit.MINUTES)
|
||||
public class JsonLargeBenchmark {
|
||||
|
||||
private String largeInput;
|
||||
|
||||
private Gson gson;
|
||||
|
||||
private ObjectMapper objectMapper;
|
||||
|
||||
private DslJson<?> dslJson;
|
||||
|
||||
@Setup(Level.Trial)
|
||||
public void setup() throws IOException {
|
||||
try (InputStream inputStream = JsonLargeBenchmark.class.getResourceAsStream("large.json")) {
|
||||
if (inputStream != null) {
|
||||
byte[] b = inputStream.readAllBytes();
|
||||
this.largeInput = new String(b, StandardCharsets.UTF_8);
|
||||
}
|
||||
}
|
||||
gson = new Gson();
|
||||
objectMapper = new ObjectMapper();
|
||||
dslJson = new DslJson<>();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public Object noggit() throws IOException {
|
||||
return ObjectBuilder.fromJSON(largeInput).toString();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public Object simple() throws ParseException {
|
||||
return new JSONParser().parse(largeInput).toString();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public Object orgjson() {
|
||||
return new org.json.JSONArray(largeInput).toString();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public Object gson() {
|
||||
return gson.fromJson(largeInput, List.class).toString();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public Object jackson() throws IOException {
|
||||
return objectMapper.readValue(largeInput, List.class).toString();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public Object minimal() throws IOException {
|
||||
return org.xbib.datastructures.json.minimal.Json.parse(largeInput).asArray().toString();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public Object flat() throws IOException {
|
||||
return Json.parse(largeInput).asList().toString();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public Object jsoniter() {
|
||||
return org.xbib.datastructures.json.iterator.JsonIterator.deserialize(largeInput).asList().toString();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public Object jsondsl() throws IOException {
|
||||
byte[] b = largeInput.getBytes(StandardCharsets.UTF_8);
|
||||
return dslJson.deserialize(Map.class, b, b.length);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public Object datastructuresEmpty() {
|
||||
StringParser stringParser = new StringParser(new EmptyJsonListener());
|
||||
stringParser.parse(largeInput);
|
||||
return stringParser.getNode(); // there is no object in get()
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public Object datastructuresTiny() {
|
||||
StringParser stringParser = new StringParser(new TinyJsonListener());
|
||||
stringParser.parse(largeInput);
|
||||
return stringParser.getNode().get().toString();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public Object datastructuresStandard() {
|
||||
StringParser stringParser = new StringParser(new StandardJsonListener());
|
||||
stringParser.parse(largeInput);
|
||||
return stringParser.getNode().get().toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
package org.xbib.datastructures.benchmark;
|
||||
|
||||
import com.dslplatform.json.DslJson;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.google.gson.Gson;
|
||||
import org.openjdk.jmh.annotations.Benchmark;
|
||||
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||
import org.openjdk.jmh.annotations.Fork;
|
||||
import org.openjdk.jmh.annotations.Level;
|
||||
import org.openjdk.jmh.annotations.Measurement;
|
||||
import org.openjdk.jmh.annotations.Mode;
|
||||
import org.openjdk.jmh.annotations.Scope;
|
||||
import org.openjdk.jmh.annotations.Setup;
|
||||
import org.openjdk.jmh.annotations.State;
|
||||
import org.openjdk.jmh.annotations.Threads;
|
||||
import org.openjdk.jmh.annotations.Warmup;
|
||||
import org.openjdk.jmh.annotations.Timeout;
|
||||
import org.xbib.datastructures.json.EmptyJsonListener;
|
||||
import org.xbib.datastructures.json.StandardJsonListener;
|
||||
import org.xbib.datastructures.json.StringParser;
|
||||
import org.xbib.datastructures.json.TinyJsonListener;
|
||||
import org.xbib.datastructures.json.flat.Json;
|
||||
import org.xbib.datastructures.json.noggit.ObjectBuilder;
|
||||
import org.xbib.datastructures.json.simple.JSONParser;
|
||||
import org.xbib.datastructures.json.simple.ParseException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@State(Scope.Benchmark)
|
||||
@BenchmarkMode(Mode.Throughput)
|
||||
@Warmup(iterations = 5)
|
||||
@Measurement(iterations = 5)
|
||||
@Fork(value = 1, jvmArgsAppend = "-Xmx512m")
|
||||
@Threads(4)
|
||||
@Timeout(time = 10, timeUnit = TimeUnit.MINUTES)
|
||||
public class JsonMediumBenchmark {
|
||||
|
||||
private String mediumInput;
|
||||
|
||||
private Gson gson;
|
||||
|
||||
private ObjectMapper objectMapper;
|
||||
|
||||
private DslJson<?> dslJson;
|
||||
|
||||
@Setup(Level.Trial)
|
||||
public void setup() throws IOException {
|
||||
try (InputStream inputStream = JsonMediumBenchmark.class.getResourceAsStream("medium.json")) {
|
||||
if (inputStream != null) {
|
||||
byte[] b = inputStream.readAllBytes();
|
||||
this.mediumInput = new String(b, StandardCharsets.UTF_8);
|
||||
}
|
||||
}
|
||||
gson = new Gson();
|
||||
objectMapper = new ObjectMapper();
|
||||
dslJson = new DslJson<>();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public Object noggit() throws IOException {
|
||||
return ObjectBuilder.fromJSON(mediumInput).toString();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public Object simple() throws ParseException {
|
||||
return new JSONParser().parse(mediumInput).toString();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public Object orgjson() {
|
||||
return new org.json.JSONObject(mediumInput).toString();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public Object gson() {
|
||||
return gson.fromJson(mediumInput, Map.class).toString();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public Object jackson() throws IOException {
|
||||
return objectMapper.readValue(mediumInput, Map.class).toString();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public Object minimal() throws IOException {
|
||||
return org.xbib.datastructures.json.minimal.Json.parse(mediumInput).asObject().toString();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public Object flat() throws IOException {
|
||||
return Json.parse(mediumInput).asMap().toString();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public Object jsoniter() {
|
||||
return org.xbib.datastructures.json.iterator.JsonIterator.deserialize(mediumInput).asMap().toString();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public Object jsondsl() throws IOException {
|
||||
byte[] b = mediumInput.getBytes(StandardCharsets.UTF_8);
|
||||
return dslJson.deserialize(Map.class, b, b.length);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public Object datastructuresEmpty() {
|
||||
StringParser stringParser = new StringParser(new EmptyJsonListener());
|
||||
stringParser.parse(mediumInput);
|
||||
return stringParser.getNode(); // there is no object in get()
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public Object datastructuresTiny() {
|
||||
StringParser stringParser = new StringParser(new TinyJsonListener());
|
||||
stringParser.parse(mediumInput);
|
||||
return stringParser.getNode().get().toString();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public Object datastructuresStandard() {
|
||||
StringParser stringParser = new StringParser(new StandardJsonListener());
|
||||
stringParser.parse(mediumInput);
|
||||
return stringParser.getNode().get().toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,129 @@
|
|||
package org.xbib.datastructures.benchmark;
|
||||
|
||||
import com.dslplatform.json.DslJson;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.google.gson.Gson;
|
||||
import org.openjdk.jmh.annotations.Benchmark;
|
||||
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||
import org.openjdk.jmh.annotations.Fork;
|
||||
import org.openjdk.jmh.annotations.Level;
|
||||
import org.openjdk.jmh.annotations.Measurement;
|
||||
import org.openjdk.jmh.annotations.Mode;
|
||||
import org.openjdk.jmh.annotations.Scope;
|
||||
import org.openjdk.jmh.annotations.Setup;
|
||||
import org.openjdk.jmh.annotations.State;
|
||||
import org.openjdk.jmh.annotations.Threads;
|
||||
import org.openjdk.jmh.annotations.Timeout;
|
||||
import org.openjdk.jmh.annotations.Warmup;
|
||||
import org.xbib.datastructures.json.EmptyJsonListener;
|
||||
import org.xbib.datastructures.json.StandardJsonListener;
|
||||
import org.xbib.datastructures.json.StringParser;
|
||||
import org.xbib.datastructures.json.TinyJsonListener;
|
||||
import org.xbib.datastructures.json.flat.Json;
|
||||
import org.xbib.datastructures.json.noggit.ObjectBuilder;
|
||||
import org.xbib.datastructures.json.simple.JSONParser;
|
||||
import org.xbib.datastructures.json.simple.ParseException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@State(Scope.Benchmark)
|
||||
@BenchmarkMode(Mode.Throughput)
|
||||
@Warmup(iterations = 5)
|
||||
@Measurement(iterations = 5)
|
||||
@Fork(value = 1, jvmArgsAppend = "-Xmx256m")
|
||||
@Threads(4)
|
||||
@Timeout(time = 10, timeUnit = TimeUnit.MINUTES)
|
||||
public class JsonSmallBenchmark {
|
||||
|
||||
private String smallInput;
|
||||
|
||||
private Gson gson;
|
||||
|
||||
private ObjectMapper objectMapper;
|
||||
|
||||
private DslJson<?> dslJson;
|
||||
|
||||
@Setup(Level.Trial)
|
||||
public void setup() throws IOException {
|
||||
try (InputStream inputStream = JsonSmallBenchmark.class.getResourceAsStream("small.json")) {
|
||||
if (inputStream != null) {
|
||||
byte[] b = inputStream.readAllBytes();
|
||||
this.smallInput = new String(b, StandardCharsets.UTF_8);
|
||||
}
|
||||
}
|
||||
// reentrant
|
||||
gson = new Gson();
|
||||
objectMapper = new ObjectMapper();
|
||||
dslJson = new DslJson<>();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public Object noggit() throws IOException {
|
||||
return ObjectBuilder.fromJSON(smallInput).toString();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public Object simple() throws ParseException {
|
||||
return new JSONParser().parse(smallInput).toString();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public Object orgjson() {
|
||||
return new org.json.JSONObject(smallInput).toString();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public Object gson() {
|
||||
return gson.fromJson(smallInput, Map.class).toString();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public Object jackson() throws IOException {
|
||||
return objectMapper.readValue(smallInput, Map.class).toString();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public Object minimal() throws IOException {
|
||||
return org.xbib.datastructures.json.minimal.Json.parse(smallInput).asObject().toString();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public Object flat() throws IOException {
|
||||
return Json.parse(smallInput).asMap().toString();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public Object jsoniter() {
|
||||
return org.xbib.datastructures.json.iterator.JsonIterator.deserialize(smallInput).asMap().toString();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public Object jsondsl() throws IOException {
|
||||
byte[] b = smallInput.getBytes(StandardCharsets.UTF_8);
|
||||
return dslJson.deserialize(Map.class, b, b.length);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public Object datastructuresEmpty() {
|
||||
StringParser stringParser = new StringParser(new EmptyJsonListener());
|
||||
stringParser.parse(smallInput);
|
||||
return stringParser.getNode(); // there is no object in get()
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public Object datastructuresTiny() {
|
||||
StringParser stringParser = new StringParser(new TinyJsonListener());
|
||||
stringParser.parse(smallInput);
|
||||
return stringParser.getNode().get().toString();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public Object datastructuresStandard() {
|
||||
StringParser stringParser = new StringParser(new StandardJsonListener());
|
||||
stringParser.parse(smallInput);
|
||||
return stringParser.getNode().get().toString();
|
||||
}
|
||||
}
|
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,57 @@
|
|||
{
|
||||
"colors": [
|
||||
{
|
||||
"color": "black",
|
||||
"category": "hue",
|
||||
"type": "primary",
|
||||
"code": {
|
||||
"rgba": [255,255,255,1],
|
||||
"hex": "#000"
|
||||
}
|
||||
},
|
||||
{
|
||||
"color": "white",
|
||||
"category": "value",
|
||||
"code": {
|
||||
"rgba": [0,0,0,1],
|
||||
"hex": "#FFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
"category": "hue",
|
||||
"type": "primary",
|
||||
"code": {
|
||||
"rgba": [255,0,0,1],
|
||||
"hex": "#FF0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"color": "blue",
|
||||
"category": "hue",
|
||||
"type": "primary",
|
||||
"code": {
|
||||
"rgba": [0,0,255,1],
|
||||
"hex": "#00F"
|
||||
}
|
||||
},
|
||||
{
|
||||
"color": "yellow",
|
||||
"category": "hue",
|
||||
"type": "primary",
|
||||
"code": {
|
||||
"rgba": [255,255,0,1],
|
||||
"hex": "#FF0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"color": "green",
|
||||
"category": "hue",
|
||||
"type": "secondary",
|
||||
"code": {
|
||||
"rgba": [0,255,0,1],
|
||||
"hex": "#0F0"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
package org.xbib.datastructures.benchmark;
|
||||
|
||||
import com.dslplatform.json.DslJson;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.google.gson.Gson;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.xbib.datastructures.json.flat.Json;
|
||||
import org.xbib.datastructures.json.noggit.ObjectBuilder;
|
||||
import org.xbib.datastructures.json.simple.JSONParser;
|
||||
import org.xbib.datastructures.json.simple.ParseException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class JsonTest {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(JsonTest.class.getName());
|
||||
|
||||
private static String input;
|
||||
|
||||
@BeforeAll
|
||||
public static void setup() throws IOException {
|
||||
try (InputStream inputStream = JsonTest.class.getResourceAsStream("small.json")) {
|
||||
if (inputStream != null) {
|
||||
byte[] b = inputStream.readAllBytes();
|
||||
input = new String(b, StandardCharsets.UTF_8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMap() throws IOException, ParseException {
|
||||
logger.log(Level.INFO, "noggit = " + ObjectBuilder.fromJSON(input).toString());
|
||||
logger.log(Level.INFO, "simple = " + new JSONParser().parse(input).toString()); // JSON
|
||||
logger.log(Level.INFO, "orgjson = " + new org.json.JSONObject(input).toString()); // JSON
|
||||
logger.log(Level.INFO, "gson = " + new Gson().fromJson(input, Map.class).toString());
|
||||
logger.log(Level.INFO, "jackson = " + new ObjectMapper().readValue(input, Map.class).toString());
|
||||
logger.log(Level.INFO, "minimal = " + org.xbib.datastructures.json.minimal.Json.parse(input).asObject().toString()); // JSON
|
||||
logger.log(Level.INFO, "flat = " + Json.parse(input).asMap().toString()); // JSON
|
||||
logger.log(Level.INFO, "jsoniter = " + org.xbib.datastructures.json.iterator.JsonIterator.deserialize(input).asMap().toString()); // JSON
|
||||
byte[] b = input.getBytes(StandardCharsets.UTF_8);
|
||||
logger.log(Level.INFO, "jsondsl = " + new DslJson<>().deserialize(Map.class, b, b.length));
|
||||
}
|
||||
}
|
|
@ -24,7 +24,7 @@ import java.util.TreeMap;
|
|||
@Warmup(iterations = 5)
|
||||
@Fork(1)
|
||||
@Measurement(iterations = 5)
|
||||
public class StructuresBenchmark {
|
||||
public class StrictBenchmark {
|
||||
|
||||
Integer[] integers = new Integer[1000];
|
||||
|
||||
|
@ -66,10 +66,7 @@ public class StructuresBenchmark {
|
|||
|
||||
@Benchmark
|
||||
public String linkedHashSet() {
|
||||
LinkedHashSet<Integer> set = new LinkedHashSet<>();
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
set.add(integers[i]);
|
||||
}
|
||||
LinkedHashSet<Integer> set = new LinkedHashSet<>(Arrays.asList(integers).subList(0, 1000));
|
||||
return set.toString();
|
||||
}
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
This work is a derived work of
|
||||
|
||||
https://github.com/boonproject/boon/tree/master/boon/src/main/java/org/boon/json
|
||||
|
||||
Apache License 2.0, master branch, as of 2021-02-01
|
File diff suppressed because it is too large
Load diff
|
@ -1,254 +0,0 @@
|
|||
|
||||
/*
|
||||
* Copyright 2013-2014 Richard M. Hightower
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* __________ _____ __ .__
|
||||
* \______ \ ____ ____ ____ /\ / \ _____ | | _|__| ____ ____
|
||||
* | | _// _ \ / _ \ / \ \/ / \ / \\__ \ | |/ / |/ \ / ___\
|
||||
* | | ( <_> | <_> ) | \ /\ / Y \/ __ \| <| | | \/ /_/ >
|
||||
* |______ /\____/ \____/|___| / \/ \____|__ (____ /__|_ \__|___| /\___ /
|
||||
* \/ \/ \/ \/ \/ \//_____/
|
||||
* ____. ___________ _____ ______________.___.
|
||||
* | |____ ___ _______ \_ _____/ / _ \ / _____/\__ | |
|
||||
* | \__ \\ \/ /\__ \ | __)_ / /_\ \ \_____ \ / | |
|
||||
* /\__| |/ __ \\ / / __ \_ | \/ | \/ \ \____ |
|
||||
* \________(____ /\_/ (____ / /_______ /\____|__ /_______ / / ______|
|
||||
* \/ \/ \/ \/ \/ \/
|
||||
*/
|
||||
|
||||
package org.boon;
|
||||
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
|
||||
import static org.boon.Boon.sputs;
|
||||
import static org.boon.Exceptions.requireNonNull;
|
||||
import static org.boon.Lists.*;
|
||||
|
||||
public class Classpaths {
|
||||
|
||||
|
||||
public static List<URL> classpathResources( ClassLoader loader, String resource ) {
|
||||
try {
|
||||
|
||||
Enumeration<URL> resources = loader.getResources( resource );
|
||||
List<URL> list = list( resources );
|
||||
|
||||
if ( isEmpty( list ) && resource.startsWith( "/" ) ) {
|
||||
resource = resource.substring( 1 );
|
||||
return classpathResources( loader, resource );
|
||||
}
|
||||
|
||||
return list;
|
||||
|
||||
|
||||
} catch ( Exception ex ) {
|
||||
|
||||
return Exceptions.handle( List.class, sputs( "Unable to load listFromClassLoader for", resource ),
|
||||
ex );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static List<URL> classpathResources( Class<?> clazz, String resource ) {
|
||||
|
||||
|
||||
List<URL> list = classpathResources( Thread.currentThread().getContextClassLoader(), resource );
|
||||
|
||||
if ( isEmpty( list ) ) {
|
||||
list = classpathResources( clazz.getClassLoader(), resource );
|
||||
}
|
||||
|
||||
|
||||
if ( isEmpty( list ) && resource.startsWith( "/" ) ) {
|
||||
resource = resource.substring( 1 );
|
||||
return classpathResources( clazz, resource );
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public static List<String> resources( Class<?> clazz, String resource ) {
|
||||
|
||||
|
||||
List<String> list = listFromClassLoader(Thread.currentThread().getContextClassLoader(), resource);
|
||||
|
||||
if ( isEmpty( list ) ) {
|
||||
list = listFromClassLoader(clazz.getClassLoader(), resource);
|
||||
}
|
||||
|
||||
|
||||
if ( isEmpty( list ) && resource.startsWith( "/" ) ) {
|
||||
resource = resource.substring( 1 );
|
||||
return resources( clazz, resource );
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
public static List<Path> paths( Class<?> clazz, String resource ) {
|
||||
|
||||
|
||||
List<Path> list = pathsFromClassLoader(Thread.currentThread().getContextClassLoader(), resource);
|
||||
|
||||
if ( isEmpty( list ) ) {
|
||||
list = pathsFromClassLoader(clazz.getClassLoader(), resource);
|
||||
}
|
||||
|
||||
|
||||
if ( isEmpty( list ) && resource.startsWith( "/" ) ) {
|
||||
resource = resource.substring( 1 );
|
||||
return paths( clazz, resource );
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the listFromClassLoader
|
||||
* @param loader
|
||||
* @param resource
|
||||
* @return
|
||||
*/
|
||||
public static List<String> listFromClassLoader(ClassLoader loader, String resource) {
|
||||
final List<URL> resourceURLs = Classpaths.classpathResources( loader, resource );
|
||||
final List<String> resourcePaths = Lists.list( String.class );
|
||||
final Map<URI, FileSystem> pathToZipFileSystems = new HashMap<>(); //So you don't have to keep loading the same jar/zip file.
|
||||
for ( URL resourceURL : resourceURLs ) {
|
||||
|
||||
if ( resourceURL.getProtocol().equals( "jar" ) ) {
|
||||
resourcesFromJar( resourcePaths, resourceURL, pathToZipFileSystems );
|
||||
|
||||
} else {
|
||||
resourcesFromFileSystem( resourcePaths, resourceURL );
|
||||
}
|
||||
}
|
||||
return resourcePaths;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Load the listFromClassLoader
|
||||
* @param loader
|
||||
* @param resource
|
||||
* @return
|
||||
*/
|
||||
public static List<Path> pathsFromClassLoader(ClassLoader loader, String resource) {
|
||||
final List<URL> resourceURLs = Classpaths.classpathResources( loader, resource );
|
||||
final List<Path> resourcePaths = Lists.list( Path.class );
|
||||
final Map<URI, FileSystem> pathToZipFileSystems = new HashMap<>(); //So you don't have to keep loading the same jar/zip file.
|
||||
for ( URL resourceURL : resourceURLs ) {
|
||||
|
||||
if ( resourceURL.getProtocol().equals( "jar" ) ) {
|
||||
pathsFromJar( resourcePaths, resourceURL, pathToZipFileSystems );
|
||||
|
||||
} else {
|
||||
pathsFromFileSystem( resourcePaths, resourceURL );
|
||||
}
|
||||
}
|
||||
return resourcePaths;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static void resourcesFromFileSystem( List<String> resourcePaths, URL u ) {
|
||||
URI fileURI = IO.createURI( u.toString() );
|
||||
|
||||
|
||||
add( resourcePaths, IO.uriToPath( fileURI ).toString() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static void pathsFromFileSystem( List<Path> resourcePaths, URL u ) {
|
||||
URI fileURI = IO.createURI( u.toString() );
|
||||
|
||||
|
||||
add( resourcePaths, IO.uriToPath( fileURI ) );
|
||||
}
|
||||
|
||||
private static void resourcesFromJar( List<String> resourcePaths, URL resourceURL, Map<URI, FileSystem> pathToZipFileSystems ) {
|
||||
|
||||
String str = resourceURL.toString();
|
||||
|
||||
final String[] strings = StringScanner.split( str, '!' );
|
||||
|
||||
URI fileJarURI = URI.create( strings[ 0 ] );
|
||||
String resourcePath = strings[ 1 ];
|
||||
|
||||
if ( !pathToZipFileSystems.containsKey( fileJarURI ) ) {
|
||||
pathToZipFileSystems.put( fileJarURI, IO.zipFileSystem(fileJarURI) );
|
||||
}
|
||||
|
||||
FileSystem fileSystem = pathToZipFileSystems.get( fileJarURI );
|
||||
|
||||
Path path = fileSystem.getPath(resourcePath);
|
||||
|
||||
if (path != null) {
|
||||
add( resourcePaths, str);
|
||||
}
|
||||
}
|
||||
|
||||
private static void pathsFromJar( List<Path> resourcePaths, URL resourceURL, Map<URI, FileSystem> pathToZipFileSystems ) {
|
||||
|
||||
String str = resourceURL.toString();
|
||||
|
||||
final String[] strings = StringScanner.split( str, '!' );
|
||||
|
||||
URI fileJarURI = URI.create( strings[ 0 ] );
|
||||
String resourcePath = strings[ 1 ];
|
||||
|
||||
if ( !pathToZipFileSystems.containsKey( fileJarURI ) ) {
|
||||
pathToZipFileSystems.put( fileJarURI, IO.zipFileSystem(fileJarURI) );
|
||||
}
|
||||
|
||||
FileSystem fileSystem = pathToZipFileSystems.get( fileJarURI );
|
||||
|
||||
Path path = fileSystem.getPath(resourcePath);
|
||||
|
||||
if (path != null) {
|
||||
add( resourcePaths, path);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static void resourcePathsFromJar( List<Path> resourcePaths, URL resourceURL, Map<URI, FileSystem> pathToZipFileSystems ) {
|
||||
|
||||
String str = resourceURL.toString();
|
||||
|
||||
final String[] strings = StringScanner.split( str, '!' );
|
||||
|
||||
URI fileJarURI = URI.create( strings[ 0 ] );
|
||||
String resourcePath = strings[ 1 ];
|
||||
|
||||
if ( !pathToZipFileSystems.containsKey( fileJarURI ) ) {
|
||||
pathToZipFileSystems.put( fileJarURI, IO.zipFileSystem(fileJarURI) );
|
||||
}
|
||||
|
||||
FileSystem fileSystem = pathToZipFileSystems.get( fileJarURI );
|
||||
|
||||
Path path = fileSystem.getPath(resourcePath);
|
||||
|
||||
if (path != null) {
|
||||
add( resourcePaths, path);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
package org.boon;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Created by Richard on 9/9/14.
|
||||
*/
|
||||
public interface Entry<K, V> extends Comparable<Entry>, Map.Entry<K, V>,
|
||||
Serializable, Cloneable {
|
||||
K key();
|
||||
|
||||
V value();
|
||||
|
||||
boolean equals(Entry o);
|
||||
}
|
|
@ -1,504 +0,0 @@
|
|||
/*
|
||||
* Copyright 2013-2014 Richard M. Hightower
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* __________ _____ __ .__
|
||||
* \______ \ ____ ____ ____ /\ / \ _____ | | _|__| ____ ____
|
||||
* | | _// _ \ / _ \ / \ \/ / \ / \\__ \ | |/ / |/ \ / ___\
|
||||
* | | ( <_> | <_> ) | \ /\ / Y \/ __ \| <| | | \/ /_/ >
|
||||
* |______ /\____/ \____/|___| / \/ \____|__ (____ /__|_ \__|___| /\___ /
|
||||
* \/ \/ \/ \/ \/ \//_____/
|
||||
* ____. ___________ _____ ______________.___.
|
||||
* | |____ ___ _______ \_ _____/ / _ \ / _____/\__ | |
|
||||
* | \__ \\ \/ /\__ \ | __)_ / /_\ \ \_____ \ / | |
|
||||
* /\__| |/ __ \\ / / __ \_ | \/ | \/ \ \____ |
|
||||
* \________(____ /\_/ (____ / /_______ /\____|__ /_______ / / ______|
|
||||
* \/ \/ \/ \/ \/ \/
|
||||
*/
|
||||
|
||||
package org.boon;
|
||||
|
||||
import org.boon.primitive.CharBuf;
|
||||
|
||||
import java.io.PrintStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.*;
|
||||
|
||||
import static org.boon.Maps.map;
|
||||
import static org.boon.primitive.Arry.add;
|
||||
import static org.boon.primitive.Arry.array;
|
||||
import static org.boon.Boon.sputs;
|
||||
import static org.boon.Sets.set;
|
||||
import static org.boon.Str.startsWithItemInCollection;
|
||||
|
||||
public class Exceptions {
|
||||
|
||||
|
||||
|
||||
private static final Set<String> ignorePackages = set("sun.", "com.sun.",
|
||||
"javax.java", "java.", "oracle.", "com.oracle.", "org.junit", "org.boon.Exceptions",
|
||||
"com.intellij");
|
||||
|
||||
|
||||
public static void requireNonNull(Object obj) {
|
||||
if (obj == null)
|
||||
die("Required object assertion exception");
|
||||
}
|
||||
|
||||
public static void requireNonNulls(String message, Object... array) {
|
||||
|
||||
int index = 0;
|
||||
for (Object obj : array) {
|
||||
if (obj == null)
|
||||
die(message, index);
|
||||
|
||||
index++;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static void dieIfAnyParametersAreNull(String methodName, Object... parameters) {
|
||||
|
||||
requireNonNull(sputs("METHOD", methodName, "Parameter at index was null: index="));
|
||||
}
|
||||
|
||||
public static void requireNonNull(Object obj, String message) {
|
||||
if (obj == null)
|
||||
die(message);
|
||||
|
||||
}
|
||||
|
||||
public static boolean die() {
|
||||
throw new SoftenedException( "died" );
|
||||
}
|
||||
|
||||
public static boolean die( String message ) {
|
||||
throw new SoftenedException( message );
|
||||
}
|
||||
|
||||
|
||||
public static boolean die( Object... messages ) {
|
||||
throw new SoftenedException( sputs(messages) );
|
||||
}
|
||||
|
||||
|
||||
public static <T> T die( Class<T> clazz, String message ) {
|
||||
throw new SoftenedException( message );
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static <T> T die( Class<T> clazz, Object... messages ) {
|
||||
throw new SoftenedException( sputs(messages) );
|
||||
}
|
||||
|
||||
public static void handle( Exception e ) {
|
||||
throw new SoftenedException( e );
|
||||
}
|
||||
|
||||
|
||||
public static <T> T handle( Class<T> clazz, Exception e ) {
|
||||
|
||||
if ( e instanceof SoftenedException ) {
|
||||
throw ( SoftenedException ) e;
|
||||
}
|
||||
throw new SoftenedException( e );
|
||||
}
|
||||
|
||||
public static <T> T handle( Class<T> clazz, String message, Throwable e ) {
|
||||
|
||||
throw new SoftenedException( message, e );
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static <T> T handle( Class<T> clazz, Throwable e, Object... messages ) {
|
||||
|
||||
throw new SoftenedException( sputs(messages), e );
|
||||
}
|
||||
|
||||
public static void handle( Throwable e, Object... messages ) {
|
||||
|
||||
throw new SoftenedException( sputs(messages), e );
|
||||
}
|
||||
|
||||
|
||||
public static void printStackTrace(CharBuf charBuf, StackTraceElement[] stackTrace) {
|
||||
for (StackTraceElement st : stackTrace) {
|
||||
if (st.getClassName().contains("org.boon.Exceptions")) {
|
||||
continue;
|
||||
}
|
||||
charBuf.indent(10).println(st);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> T tryIt( Class<T> clazz, TrialWithReturn<T> tryIt ) {
|
||||
try {
|
||||
return tryIt.tryIt();
|
||||
} catch ( Exception ex ) {
|
||||
throw new SoftenedException( ex );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void tryIt( Trial tryIt ) {
|
||||
try {
|
||||
tryIt.tryIt();
|
||||
} catch ( Exception ex ) {
|
||||
throw new SoftenedException( ex );
|
||||
}
|
||||
}
|
||||
|
||||
public static void handle( String message, Throwable e ) {
|
||||
throw new SoftenedException( message, e );
|
||||
}
|
||||
|
||||
public static void tryIt( String message, Trial tryIt ) {
|
||||
try {
|
||||
tryIt.tryIt();
|
||||
} catch ( Exception ex ) {
|
||||
throw new SoftenedException( message, ex );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static interface Trial {
|
||||
void tryIt() throws Exception;
|
||||
}
|
||||
|
||||
public static interface TrialWithReturn<T> {
|
||||
T tryIt() throws Exception;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static StackTraceElement[] getFilteredStackTrace(StackTraceElement[] stackTrace) {
|
||||
|
||||
|
||||
if (stackTrace == null || stackTrace.length == 0) {
|
||||
return new StackTraceElement[0];
|
||||
}
|
||||
List<StackTraceElement> list = new ArrayList<>();
|
||||
Set<String> seenThisBefore = new HashSet<>();
|
||||
|
||||
for (StackTraceElement st : stackTrace) {
|
||||
if ( startsWithItemInCollection( st.getClassName(), ignorePackages ) ) {
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
String key = Boon.sputs(st.getClassName(), st.getFileName(), st.getMethodName(), st.getLineNumber());
|
||||
if (seenThisBefore.contains(key)) {
|
||||
continue;
|
||||
} else {
|
||||
seenThisBefore.add(key);
|
||||
}
|
||||
|
||||
list.add(st);
|
||||
}
|
||||
|
||||
return array( StackTraceElement.class, list );
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static class SoftenedException extends RuntimeException {
|
||||
|
||||
public SoftenedException( String message ) {
|
||||
super( message );
|
||||
}
|
||||
|
||||
public SoftenedException( String message, Throwable cause ) {
|
||||
super( message, cause );
|
||||
}
|
||||
|
||||
public SoftenedException( Throwable cause ) {
|
||||
super( "Wrapped Exception", cause );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return super.getMessage() + ( getCause() == null ? "" :
|
||||
getCauseMessage() );
|
||||
}
|
||||
|
||||
private String getCauseMessage() {
|
||||
return "\n CAUSE " + getCause().getClass().getName() + " :: " +
|
||||
getCause().getMessage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLocalizedMessage() {
|
||||
return this.getMessage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public StackTraceElement[] getStackTrace() {
|
||||
if ( getRootCause() != null ) {
|
||||
return add(getRootCause().getStackTrace(), super.getStackTrace());
|
||||
} else {
|
||||
return super.getStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Throwable getCause() {
|
||||
return super.getCause();
|
||||
}
|
||||
|
||||
|
||||
public Throwable getRootCause() {
|
||||
|
||||
Throwable cause = super.getCause();
|
||||
|
||||
Throwable lastCause = super.getCause();
|
||||
|
||||
while (cause != null) {
|
||||
lastCause = cause;
|
||||
cause = cause.getCause();
|
||||
|
||||
}
|
||||
return lastCause;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void printStackTrace( CharBuf charBuf) {
|
||||
|
||||
|
||||
charBuf.puts("MESSAGE:", this.getMessage());
|
||||
if (this.getRootCause() !=null) {
|
||||
charBuf.puts("ROOT CAUSE MESSAGE:", this.getRootCause().getMessage());
|
||||
} else if (this.getCause()!=null) {
|
||||
charBuf.puts("CAUSE MESSAGE:", this.getCause().getMessage());
|
||||
}
|
||||
|
||||
|
||||
StackTraceElement[] stackTrace = this.getFilteredStackTrace();
|
||||
|
||||
if (stackTrace.length > 0) {
|
||||
charBuf.indent(5).addLine("This happens around this area in your code.");
|
||||
Exceptions.printStackTrace(charBuf, stackTrace);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if ( getRootCause() != null ) {
|
||||
charBuf.addLine().puts("Caused by:", "message:", this.getRootCause().getMessage(), "type", this.getRootCause().getClass().getName());
|
||||
stackTrace = this.getRootCause().getStackTrace();
|
||||
Exceptions.printStackTrace(charBuf, stackTrace);
|
||||
}
|
||||
|
||||
charBuf.addLine().multiply('-', 50).addLine().multiply('-', 50).addLine();
|
||||
|
||||
StringWriter writer = new StringWriter();
|
||||
|
||||
super.printStackTrace( new PrintWriter(writer) );
|
||||
|
||||
charBuf.add(writer);
|
||||
|
||||
charBuf.addLine().multiply('-', 50).addLine();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public StackTraceElement[] getFilteredStackTrace() {
|
||||
|
||||
|
||||
StackTraceElement[] filteredStackTrace = Exceptions.getFilteredStackTrace(super.getStackTrace());
|
||||
if ( filteredStackTrace.length > 0 ) {
|
||||
|
||||
if (super.getCause() != null) {
|
||||
StackTraceElement[] cause = Exceptions.getFilteredStackTrace(super.getCause().getStackTrace());
|
||||
|
||||
if (cause.length > 0) {
|
||||
filteredStackTrace= add(cause, filteredStackTrace);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (super.getCause() != null) {
|
||||
|
||||
filteredStackTrace = Exceptions.getFilteredStackTrace(super.getCause().getStackTrace());
|
||||
}
|
||||
}
|
||||
|
||||
return Exceptions.getFilteredStackTrace(super.getStackTrace());
|
||||
|
||||
}
|
||||
|
||||
|
||||
public CharBuf printStackTraceIntoCharBuf( ) {
|
||||
|
||||
CharBuf out = CharBuf.create(100);
|
||||
printStackTrace(out);
|
||||
return out;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printStackTrace( PrintStream s ) {
|
||||
s.print(printStackTraceIntoCharBuf().toString());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void printStackTrace( PrintWriter s ) {
|
||||
s.print(printStackTraceIntoCharBuf().toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printStackTrace() {
|
||||
System.err.print(printStackTraceIntoCharBuf().toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static String toString( Exception ex ) {
|
||||
CharBuf buffer = CharBuf.create( 255 );
|
||||
buffer.addLine( ex.getLocalizedMessage() );
|
||||
|
||||
final StackTraceElement[] stackTrace = ex.getStackTrace();
|
||||
for ( StackTraceElement element : stackTrace ) {
|
||||
buffer.add( element.getClassName() );
|
||||
sputs( " ", buffer, "class", element.getClassName(),
|
||||
"method", element.getMethodName(), "line", element.getLineNumber() );
|
||||
}
|
||||
|
||||
return buffer.toString();
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static String asJson(Exception ex) {
|
||||
CharBuf buffer = CharBuf.create( 255 );
|
||||
|
||||
buffer.add('{');
|
||||
|
||||
buffer.addLine().indent(5).addJsonFieldName("message")
|
||||
.asJsonString(ex.getMessage()).addLine(',');
|
||||
|
||||
if (ex.getCause()!=null) {
|
||||
buffer.addLine().indent(5).addJsonFieldName("causeMessage")
|
||||
.asJsonString(ex.getCause().getMessage()).addLine(',');
|
||||
|
||||
|
||||
if (ex.getCause().getCause()!=null) {
|
||||
buffer.addLine().indent(5).addJsonFieldName("cause2Message")
|
||||
.asJsonString(ex.getCause().getCause().getMessage()).addLine(',');
|
||||
|
||||
if (ex.getCause().getCause().getCause()!=null) {
|
||||
buffer.addLine().indent(5).addJsonFieldName("cause3Message")
|
||||
.asJsonString(ex.getCause().getCause().getCause().getMessage()).addLine(',');
|
||||
|
||||
if (ex.getCause().getCause().getCause().getCause()!=null) {
|
||||
buffer.addLine().indent(5).addJsonFieldName("cause4Message")
|
||||
.asJsonString(ex.getCause().getCause().getCause().getCause().getMessage()).addLine(',');
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
StackTraceElement[] stackTrace = getFilteredStackTrace(ex.getStackTrace());
|
||||
|
||||
if ( stackTrace!=null && stackTrace.length > 0 ) {
|
||||
|
||||
buffer.addLine().indent(5).addJsonFieldName("stackTrace").addLine();
|
||||
|
||||
stackTraceToJson(buffer, stackTrace);
|
||||
|
||||
buffer.add(',');
|
||||
}
|
||||
|
||||
buffer.addLine().indent(5).addJsonFieldName("fullStackTrace").addLine();
|
||||
stackTrace = ex.getStackTrace();
|
||||
stackTraceToJson(buffer, stackTrace);
|
||||
|
||||
buffer.add( '}' );
|
||||
return buffer.toString();
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static Map asMap(Exception ex) {
|
||||
StackTraceElement[] stackTrace = getFilteredStackTrace(ex.getStackTrace());
|
||||
|
||||
List stackTraceList = Lists.list(stackTrace);
|
||||
|
||||
List fullStackTrace = Lists.list(ex.getStackTrace());
|
||||
|
||||
|
||||
return map(
|
||||
|
||||
"message", ex.getMessage(),
|
||||
"causeMessage", ex.getCause()!=null ? ex.getCause().getMessage() : "none",
|
||||
"stackTrace", stackTraceList,
|
||||
"fullStackTrace", fullStackTrace
|
||||
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static void stackTraceToJson(CharBuf buffer, StackTraceElement[] stackTrace) {
|
||||
|
||||
if (stackTrace.length==0) {
|
||||
buffer.addLine("[]");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
buffer.multiply(' ', 16).addLine('[');
|
||||
|
||||
for ( int index = 0; index < stackTrace.length; index++ ) {
|
||||
StackTraceElement element = stackTrace[ index ];
|
||||
|
||||
if (element.getClassName().contains("org.boon.Exceptions")) {
|
||||
continue;
|
||||
}
|
||||
buffer.indent(17).add("[ ").asJsonString(element.getMethodName())
|
||||
.add(',');
|
||||
|
||||
|
||||
buffer.indent(3).asJsonString(element.getClassName());
|
||||
|
||||
|
||||
if (element.getLineNumber()>0) {
|
||||
buffer.add(",");
|
||||
buffer.indent(3).asJsonString(""+element.getLineNumber())
|
||||
.addLine(" ],");
|
||||
} else {
|
||||
buffer.addLine(" ],");
|
||||
}
|
||||
|
||||
}
|
||||
buffer.removeLastChar(); //trailing \n
|
||||
buffer.removeLastChar(); //trailing ,
|
||||
|
||||
buffer.addLine().multiply(' ', 15).add(']');
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,180 +0,0 @@
|
|||
/*
|
||||
* Copyright 2013-2014 Richard M. Hightower
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* __________ _____ __ .__
|
||||
* \______ \ ____ ____ ____ /\ / \ _____ | | _|__| ____ ____
|
||||
* | | _// _ \ / _ \ / \ \/ / \ / \\__ \ | |/ / |/ \ / ___\
|
||||
* | | ( <_> | <_> ) | \ /\ / Y \/ __ \| <| | | \/ /_/ >
|
||||
* |______ /\____/ \____/|___| / \/ \____|__ (____ /__|_ \__|___| /\___ /
|
||||
* \/ \/ \/ \/ \/ \//_____/
|
||||
* ____. ___________ _____ ______________.___.
|
||||
* | |____ ___ _______ \_ _____/ / _ \ / _____/\__ | |
|
||||
* | \__ \\ \/ /\__ \ | __)_ / /_\ \ \_____ \ / | |
|
||||
* /\__| |/ __ \\ / / __ \_ | \/ | \/ \ \____ |
|
||||
* \________(____ /\_/ (____ / /_______ /\____|__ /_______ / / ______|
|
||||
* \/ \/ \/ \/ \/ \/
|
||||
*/
|
||||
|
||||
package org.boon;
|
||||
|
||||
import org.boon.core.Function;
|
||||
import org.boon.core.reflection.Invoker;
|
||||
import org.boon.core.reflection.MethodAccess;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Created by Richard on 2/28/14.
|
||||
*/
|
||||
public class Functional {
|
||||
|
||||
|
||||
public static void each(Iterable<?> objects, Class<?> cls, String methodName) {
|
||||
|
||||
for (Object o : objects) {
|
||||
Invoker.invoke(cls, methodName, o);
|
||||
}
|
||||
}
|
||||
|
||||
public static void each( Object[] objects, Object instance, String methodName) {
|
||||
|
||||
for (Object o : objects) {
|
||||
Invoker.invoke(instance, methodName, o);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void each (Object[] objects, Class<?> cls, String methodName) {
|
||||
for (Object o : objects) {
|
||||
Invoker.invoke(cls, methodName, o);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public static void each(Iterable<?> objects, Object instance, String methodName) {
|
||||
|
||||
for (Object o : objects) {
|
||||
Invoker.invoke(instance, methodName, o);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void each(Collection<?> objects, Class<?> cls, String methodName) {
|
||||
|
||||
MethodAccess methodAccess = Invoker.invokeMethodAccess(cls, methodName);
|
||||
|
||||
for (Object o : objects) {
|
||||
methodAccess.invokeStatic(o);
|
||||
}
|
||||
}
|
||||
|
||||
public static void each(Collection<?> objects, Object function) {
|
||||
|
||||
|
||||
MethodAccess methodAccess = Invoker.invokeFunctionMethodAccess(function);
|
||||
|
||||
for (Object o : objects) {
|
||||
methodAccess.invoke(function, o);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static void each(Map<?,?> map, Object object) {
|
||||
|
||||
|
||||
MethodAccess methodAccess = Invoker.invokeFunctionMethodAccess(object);
|
||||
|
||||
for (Object o : map.entrySet()) {
|
||||
Map.Entry entry = (Map.Entry) o;
|
||||
|
||||
methodAccess.invoke(object, ((Map.Entry) o).getKey(), ((Map.Entry) o).getValue());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void each(Iterable<?> objects, Object function) {
|
||||
|
||||
|
||||
MethodAccess methodAccess = Invoker.invokeFunctionMethodAccess(function);
|
||||
|
||||
for (Object o : objects) {
|
||||
methodAccess.invoke(function, o);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void each (Object[] objects, Object function) {
|
||||
|
||||
MethodAccess methodAccess = Invoker.invokeFunctionMethodAccess(function);
|
||||
|
||||
for (Object o : objects) {
|
||||
methodAccess.invoke(function, o);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void each(Collection<?> objects, Object object, String methodName) {
|
||||
|
||||
|
||||
MethodAccess methodAccess = Invoker.invokeMethodAccess(object.getClass(), methodName);
|
||||
|
||||
for (Object o : objects) {
|
||||
methodAccess.invoke(object, o);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void each(Map<?,?> map, Object object, String methodName) {
|
||||
|
||||
|
||||
MethodAccess methodAccess = Invoker.invokeMethodAccess(object.getClass(), methodName);
|
||||
|
||||
for (Object o : map.entrySet()) {
|
||||
Map.Entry entry = (Map.Entry) o;
|
||||
|
||||
methodAccess.invoke(object, ((Map.Entry) o).getKey(), ((Map.Entry) o).getValue());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static <V, N> void each( final V[] array, Function<V, N> function ) {
|
||||
|
||||
for ( V v : array ) {
|
||||
function.apply(v);
|
||||
}
|
||||
}
|
||||
|
||||
public static <V, N> void each( final Collection<V> array, Function<V, N> function ) {
|
||||
|
||||
for ( V v : array ) {
|
||||
function.apply(v);
|
||||
}
|
||||
}
|
||||
|
||||
public static <V, N> void each( final Iterable<V> array, Function<V, N> function ) {
|
||||
|
||||
for ( V v : array ) {
|
||||
function.apply(v);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,639 +0,0 @@
|
|||
/*
|
||||
* Copyright 2013-2014 Richard M. Hightower
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* __________ _____ __ .__
|
||||
* \______ \ ____ ____ ____ /\ / \ _____ | | _|__| ____ ____
|
||||
* | | _// _ \ / _ \ / \ \/ / \ / \\__ \ | |/ / |/ \ / ___\
|
||||
* | | ( <_> | <_> ) | \ /\ / Y \/ __ \| <| | | \/ /_/ >
|
||||
* |______ /\____/ \____/|___| / \/ \____|__ (____ /__|_ \__|___| /\___ /
|
||||
* \/ \/ \/ \/ \/ \//_____/
|
||||
* ____. ___________ _____ ______________.___.
|
||||
* | |____ ___ _______ \_ _____/ / _ \ / _____/\__ | |
|
||||
* | \__ \\ \/ /\__ \ | __)_ / /_\ \ \_____ \ / | |
|
||||
* /\__| |/ __ \\ / / __ \_ | \/ | \/ \ \____ |
|
||||
* \________(____ /\_/ (____ / /_______ /\____|__ /_______ / / ______|
|
||||
* \/ \/ \/ \/ \/ \/
|
||||
*/
|
||||
|
||||
package org.boon;
|
||||
|
||||
|
||||
import org.boon.core.Sys;
|
||||
import org.boon.primitive.ByteBuf;
|
||||
import org.boon.service.Response;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class HTTP {
|
||||
|
||||
public static final int DEFAULT_TIMEOUT_SECONDS = Sys.sysProp("org.boon.HTTP.timeout.seconds", 30 );
|
||||
public static final String APPLICATION_JSON = "application/json";
|
||||
|
||||
public static String get(
|
||||
final String url ) {
|
||||
|
||||
return Exceptions.tryIt( String.class, new Exceptions.TrialWithReturn<String>() {
|
||||
@Override
|
||||
public String tryIt() throws Exception {
|
||||
URLConnection connection;
|
||||
|
||||
final Map<String, String> accept = Maps.map(
|
||||
"Accept", "text/html,application/xhtml+xml,application/xml,application/json,text/plain;"
|
||||
);
|
||||
|
||||
connection = doGet( url, accept, null, null );
|
||||
return extractResponseString( connection );
|
||||
}
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static String post(
|
||||
final String url,
|
||||
final String body ) {
|
||||
|
||||
return postBodyTextWithContentType( url, "text/plain", body );
|
||||
}
|
||||
|
||||
|
||||
public static Response getResponse(
|
||||
final String url ) {
|
||||
|
||||
return Exceptions.tryIt( Response.class, new Exceptions.TrialWithReturn<Response>() {
|
||||
@Override
|
||||
public Response tryIt() throws Exception {
|
||||
URLConnection connection;
|
||||
|
||||
final Map<String, String> accept = Maps.map(
|
||||
"Accept", "text/html,application/xhtml+xml,application/xml,application/json,text/plain;"
|
||||
);
|
||||
|
||||
connection = doGet( url, accept, null, null );
|
||||
return extractResponseObject(connection);
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
public static byte[] getBytes(
|
||||
final String url, final String contentType ) {
|
||||
|
||||
return Exceptions.tryIt( byte[].class, new Exceptions.TrialWithReturn<byte[]>() {
|
||||
@Override
|
||||
public byte[] tryIt() throws Exception {
|
||||
URLConnection connection;
|
||||
connection = doGet( url, null, contentType, null, true );
|
||||
return extractResponseBytes( connection );
|
||||
}
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
public static byte[] getBytesWithHeaders(
|
||||
final String url, final String contentType, final Map<String, ?> headers ) {
|
||||
|
||||
return Exceptions.tryIt( byte[].class, new Exceptions.TrialWithReturn<byte[]>() {
|
||||
@Override
|
||||
public byte[] tryIt() throws Exception {
|
||||
URLConnection connection;
|
||||
connection = doGet( url, headers, contentType, null, true );
|
||||
return extractResponseBytes( connection );
|
||||
}
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
public static String getWithHeaders(
|
||||
final String url,
|
||||
final Map<String, ?> headers ) {
|
||||
|
||||
return Exceptions.tryIt( String.class, new Exceptions.TrialWithReturn<String>() {
|
||||
@Override
|
||||
public String tryIt() throws Exception {
|
||||
URLConnection connection;
|
||||
connection = doGet( url, headers, null, null );
|
||||
return extractResponseString( connection );
|
||||
}
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
public static String getWithContentType(
|
||||
final String url,
|
||||
final Map<String, ?> headers,
|
||||
final String contentType ) {
|
||||
|
||||
return Exceptions.tryIt( String.class, new Exceptions.TrialWithReturn<String>() {
|
||||
@Override
|
||||
public String tryIt() throws Exception {
|
||||
URLConnection connection;
|
||||
connection = doGet( url, headers, contentType, null );
|
||||
return extractResponseString( connection );
|
||||
}
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
public static String getWithCharSet(
|
||||
final String url,
|
||||
final Map<String, ?> headers,
|
||||
final String contentType,
|
||||
final String charSet ) {
|
||||
|
||||
|
||||
return Exceptions.tryIt( String.class, new Exceptions.TrialWithReturn<String>() {
|
||||
@Override
|
||||
public String tryIt() throws Exception {
|
||||
URLConnection connection;
|
||||
connection = doGet( url, headers, contentType, charSet );
|
||||
return extractResponseString( connection );
|
||||
}
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
public static String postText(
|
||||
final String url,
|
||||
final String body ) {
|
||||
return postBodyTextWithContentType( url, "text/plain", body );
|
||||
}
|
||||
|
||||
public static String postBodyTextWithContentType(
|
||||
final String url,
|
||||
final String contentType,
|
||||
final String body ) {
|
||||
|
||||
|
||||
return Exceptions.tryIt( String.class, new Exceptions.TrialWithReturn<String>() {
|
||||
@Override
|
||||
public String tryIt() throws Exception {
|
||||
URLConnection connection;
|
||||
connection = doPost( url, null, contentType, null, body );
|
||||
return extractResponseString( connection );
|
||||
}
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static String postJSON(
|
||||
final String url,
|
||||
final String jsonString ) {
|
||||
|
||||
return postBodyTextWithContentType( url, APPLICATION_JSON, jsonString );
|
||||
}
|
||||
|
||||
public static Response jsonRestCallViaPOST(
|
||||
final String url,
|
||||
final String jsonString ) {
|
||||
|
||||
return postBodyTextWithContentTypeReturnResponse(url, APPLICATION_JSON, jsonString);
|
||||
}
|
||||
|
||||
|
||||
public static String getJSON(
|
||||
final String url,
|
||||
final Map<String, ?> headers
|
||||
) {
|
||||
|
||||
return Exceptions.tryIt( String.class, new Exceptions.TrialWithReturn<String>() {
|
||||
@Override
|
||||
public String tryIt() throws Exception {
|
||||
URLConnection connection;
|
||||
connection = doGet( url, headers, APPLICATION_JSON, null );
|
||||
return extractResponseString( connection );
|
||||
}
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static Response jsonRestCallWithHeaders(
|
||||
final String url,
|
||||
final Map<String, ?> headers
|
||||
) {
|
||||
|
||||
return Exceptions.tryIt( Response.class, new Exceptions.TrialWithReturn<Response>() {
|
||||
@Override
|
||||
public Response tryIt() throws Exception {
|
||||
URLConnection connection;
|
||||
connection = doGet( url, headers, APPLICATION_JSON, null );
|
||||
return extractResponseObject(connection);
|
||||
}
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
public static Response jsonRestCall(
|
||||
final String url
|
||||
) {
|
||||
|
||||
return Exceptions.tryIt( Response.class, new Exceptions.TrialWithReturn<Response>() {
|
||||
@Override
|
||||
public Response tryIt() throws Exception {
|
||||
URLConnection connection;
|
||||
connection = doGet( url, null, APPLICATION_JSON, null );
|
||||
return extractResponseObject( connection );
|
||||
}
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static Response postBodyTextWithContentTypeReturnResponse( final String url,
|
||||
final String contentType,
|
||||
final String body ) {
|
||||
|
||||
|
||||
return Exceptions.tryIt( Response.class, new Exceptions.TrialWithReturn<Response>() {
|
||||
@Override
|
||||
public Response tryIt() throws Exception {
|
||||
URLConnection connection;
|
||||
connection = doPost( url, null, contentType, null, body );
|
||||
return extractResponseObject( connection );
|
||||
}
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static String getJSONWithParams(
|
||||
final String url,
|
||||
final Map<String, ?> headers, final Map<String, ?> params
|
||||
) {
|
||||
|
||||
return Exceptions.tryIt( String.class, new Exceptions.TrialWithReturn<String>() {
|
||||
@Override
|
||||
public String tryIt() throws Exception {
|
||||
URLConnection connection;
|
||||
connection = doGet( url, headers, APPLICATION_JSON, null, params );
|
||||
return extractResponseString( connection );
|
||||
}
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
public static String postXML(
|
||||
final String url,
|
||||
final String jsonString ) {
|
||||
|
||||
return postBodyTextWithContentType( url, "text/xml", jsonString );
|
||||
}
|
||||
|
||||
public static String postWithHeaders(
|
||||
final String url,
|
||||
final Map<String, ?> headers,
|
||||
final String body ) {
|
||||
|
||||
return Exceptions.tryIt( String.class, new Exceptions.TrialWithReturn<String>() {
|
||||
@Override
|
||||
public String tryIt() throws Exception {
|
||||
URLConnection connection;
|
||||
connection = doPost( url, headers, "text/plain", null, body );
|
||||
return extractResponseString( connection );
|
||||
}
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static String postWithContentType(
|
||||
final String url,
|
||||
final Map<String, ?> headers,
|
||||
final String contentType,
|
||||
final String body ) {
|
||||
|
||||
|
||||
return Exceptions.tryIt( String.class, new Exceptions.TrialWithReturn<String>() {
|
||||
@Override
|
||||
public String tryIt() throws Exception {
|
||||
URLConnection connection;
|
||||
connection = doPost( url, headers, contentType, null, body );
|
||||
return extractResponseString( connection );
|
||||
}
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static String postWithCharset(
|
||||
final String url,
|
||||
final Map<String, ?> headers,
|
||||
final String contentType,
|
||||
final String charSet,
|
||||
final String body ) {
|
||||
|
||||
|
||||
return Exceptions.tryIt( String.class, new Exceptions.TrialWithReturn<String>() {
|
||||
@Override
|
||||
public String tryIt() throws Exception {
|
||||
URLConnection connection;
|
||||
connection = doPost( url, headers, contentType, charSet, body );
|
||||
return extractResponseString( connection );
|
||||
}
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
private static URLConnection doPost( String url, Map<String, ?> headers,
|
||||
String contentType, String charset, String body
|
||||
) throws IOException {
|
||||
HttpURLConnection connection;/* Handle output. */
|
||||
|
||||
|
||||
connection = ( HttpURLConnection ) new URL( url ).openConnection();
|
||||
connection.setConnectTimeout( DEFAULT_TIMEOUT_SECONDS * 1000 );
|
||||
|
||||
connection.setDoOutput( true );
|
||||
manageContentTypeHeaders( contentType, charset, connection );
|
||||
|
||||
manageHeaders( headers, connection );
|
||||
|
||||
|
||||
IO.write( connection.getOutputStream(), body, IO.DEFAULT_CHARSET );
|
||||
return connection;
|
||||
}
|
||||
|
||||
public static String postForm( final String url, final Map<String, ?> headers,
|
||||
final Map<String, Object> formData
|
||||
) {
|
||||
return Exceptions.tryIt( String.class, new Exceptions.TrialWithReturn<String>() {
|
||||
@Override
|
||||
public String tryIt() throws Exception {
|
||||
URLConnection connection;
|
||||
connection = doPostFormData( url, headers, formData );
|
||||
return extractResponseString( connection );
|
||||
}
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
private static URLConnection doPostFormData( String url, Map<String, ?> headers,
|
||||
Map<String, Object> formData
|
||||
) throws IOException {
|
||||
HttpURLConnection connection;/* Handle output. */
|
||||
|
||||
|
||||
connection = ( HttpURLConnection ) new URL( url ).openConnection();
|
||||
connection.setConnectTimeout( DEFAULT_TIMEOUT_SECONDS * 1000 );
|
||||
|
||||
connection.setDoOutput( true );
|
||||
|
||||
connection.addRequestProperty( "Content-Type", "application/x-www-form-urlencoded" );
|
||||
|
||||
ByteBuf buf = ByteBuf.create( 244 );
|
||||
|
||||
final Set<String> keys = formData.keySet();
|
||||
|
||||
int index = 0;
|
||||
for ( String key : keys ) {
|
||||
|
||||
Object value = formData.get( key );
|
||||
|
||||
if ( index > 0 ) {
|
||||
buf.addByte( '&' );
|
||||
}
|
||||
|
||||
|
||||
buf.addUrlEncoded( key );
|
||||
buf.addByte( '=' );
|
||||
|
||||
if ( !( value instanceof byte[] ) ) {
|
||||
buf.addUrlEncoded( value.toString() );
|
||||
} else {
|
||||
buf.addUrlEncodedByteArray( ( byte[] ) value );
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
manageContentTypeHeaders( "application/x-www-form-urlencoded",
|
||||
StandardCharsets.UTF_8.name(), connection );
|
||||
|
||||
manageHeaders( headers, connection );
|
||||
|
||||
|
||||
int len = buf.len();
|
||||
IO.write( connection.getOutputStream(),
|
||||
new String( buf.readForRecycle(), 0, len, StandardCharsets.UTF_8 ), IO.DEFAULT_CHARSET );
|
||||
return connection;
|
||||
}
|
||||
|
||||
private static void manageHeaders( Map<String, ?> headers, URLConnection connection ) {
|
||||
if ( headers != null ) {
|
||||
for ( Map.Entry<String, ?> entry : headers.entrySet() ) {
|
||||
connection.setRequestProperty( entry.getKey(), entry.getValue().toString() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static void manageContentTypeHeaders( String contentType, String charset, URLConnection connection, boolean binary ) {
|
||||
|
||||
if ( !binary ) {
|
||||
connection.setRequestProperty( "Accept-Charset", charset == null ? StandardCharsets.UTF_8.displayName() : charset );
|
||||
}
|
||||
if ( contentType != null && !contentType.isEmpty() ) {
|
||||
connection.setRequestProperty( "Content-Type", contentType );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static URLConnection doGet( String url, Map<String, ?> headers,
|
||||
String contentType, String charset, boolean binary ) throws IOException {
|
||||
URLConnection connection;/* Handle output. */
|
||||
connection = new URL( url ).openConnection();
|
||||
connection.setConnectTimeout( DEFAULT_TIMEOUT_SECONDS * 1000 );
|
||||
|
||||
manageContentTypeHeaders( contentType, charset, connection, binary );
|
||||
|
||||
manageHeaders( headers, connection );
|
||||
|
||||
return connection;
|
||||
}
|
||||
|
||||
|
||||
private static String extractResponseString( URLConnection connection ) throws IOException {
|
||||
|
||||
/* Handle input. */
|
||||
HttpURLConnection http = ( HttpURLConnection ) connection;
|
||||
int status = http.getResponseCode();
|
||||
String charset = getCharset( connection.getHeaderField( "Content-Type" ) );
|
||||
|
||||
|
||||
|
||||
|
||||
if ( status == 200 ) {
|
||||
return readResponseBody( http, charset );
|
||||
} else {
|
||||
return readErrorResponseBody( http, status, charset );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static Response extractResponseObject( URLConnection connection ) throws IOException {
|
||||
|
||||
/* Handle input. */
|
||||
HttpURLConnection http = ( HttpURLConnection ) connection;
|
||||
int status = http.getResponseCode();
|
||||
|
||||
String charset = getCharset( connection.getHeaderField( "Content-Type" ) );
|
||||
|
||||
|
||||
|
||||
String body;
|
||||
|
||||
if ( status == 200 ) {
|
||||
body = readResponseBody( http, charset );
|
||||
} else {
|
||||
body = readErrorResponseBodyDoNotDie( http, status, charset );
|
||||
}
|
||||
|
||||
return Response.response(status, http.getHeaderFields(), http.getResponseMessage(), body);
|
||||
}
|
||||
|
||||
private static byte[] extractResponseBytes( URLConnection connection ) throws IOException {
|
||||
|
||||
/* Handle input. */
|
||||
HttpURLConnection http = ( HttpURLConnection ) connection;
|
||||
int status = http.getResponseCode();
|
||||
|
||||
//System.out.println("CONTENT-TYPE" + connection.getHeaderField("Content-TypeT"));
|
||||
|
||||
|
||||
if ( status == 200 ) {
|
||||
return readResponseBodyAsBytes( http );
|
||||
} else {
|
||||
String charset = getCharset( connection.getHeaderField( "Content-Type" ) );
|
||||
|
||||
readErrorResponseBody( http, status, charset );
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] readResponseBodyAsBytes( HttpURLConnection http ) {
|
||||
try {
|
||||
return IO.input( http.getInputStream() );
|
||||
} catch ( IOException e ) {
|
||||
return Exceptions.handle( byte[].class, e );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static String readErrorResponseBody( HttpURLConnection http, int status, String charset ) {
|
||||
InputStream errorStream = http.getErrorStream();
|
||||
if ( errorStream != null ) {
|
||||
String error = charset == null ? IO.read( errorStream ) :
|
||||
IO.read( errorStream, charset );
|
||||
return Exceptions.die( String.class, "STATUS CODE =" + status + "\n\n" + error );
|
||||
} else {
|
||||
return Exceptions.die( String.class, "STATUS CODE =" + status );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static String readErrorResponseBodyDoNotDie( HttpURLConnection http, int status, String charset ) {
|
||||
InputStream errorStream = http.getErrorStream();
|
||||
if ( errorStream != null ) {
|
||||
String error = charset == null ? IO.read( errorStream ) :
|
||||
IO.read( errorStream, charset );
|
||||
return error;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private static String readResponseBody( HttpURLConnection http, String charset ) throws IOException {
|
||||
if ( charset != null ) {
|
||||
return IO.read( http.getInputStream(), charset );
|
||||
} else {
|
||||
return IO.read( http.getInputStream() );
|
||||
}
|
||||
}
|
||||
|
||||
private static String getCharset( String contentType ) {
|
||||
if ( contentType == null ) {
|
||||
return null;
|
||||
}
|
||||
String charset = null;
|
||||
for ( String param : contentType.replace( " ", "" ).split( ";" ) ) {
|
||||
if ( param.startsWith( "charset=" ) ) {
|
||||
charset = param.split( "=", 2 )[ 1 ];
|
||||
break;
|
||||
}
|
||||
}
|
||||
charset = charset == null ? StandardCharsets.UTF_8.displayName() : charset;
|
||||
|
||||
return charset;
|
||||
}
|
||||
|
||||
|
||||
private static void manageContentTypeHeaders( String contentType, String charset, URLConnection connection ) {
|
||||
connection.setRequestProperty( "Accept-Charset", charset == null ? StandardCharsets.UTF_8.displayName() : charset );
|
||||
if ( contentType != null && !contentType.isEmpty() ) {
|
||||
connection.setRequestProperty( "Content-Type", contentType );
|
||||
}
|
||||
}
|
||||
|
||||
private static URLConnection doGet( String url, Map<String, ?> headers,
|
||||
String contentType, String charset ) throws IOException {
|
||||
URLConnection connection;/* Handle output. */
|
||||
connection = new URL( url ).openConnection();
|
||||
connection.setConnectTimeout( DEFAULT_TIMEOUT_SECONDS * 1000 );
|
||||
|
||||
manageContentTypeHeaders ( contentType, charset, connection );
|
||||
|
||||
manageHeaders( headers, connection );
|
||||
|
||||
return connection;
|
||||
}
|
||||
|
||||
private static URLConnection doGet( String url, Map<String, ?> headers,
|
||||
String contentType, String charset, Map<String, ?> params ) throws IOException {
|
||||
|
||||
if (charset==null) {
|
||||
charset = StandardCharsets.UTF_8.name ();
|
||||
}
|
||||
URLConnection connection;/* Handle output. */
|
||||
connection = new URL( url ).openConnection();
|
||||
connection.setConnectTimeout( DEFAULT_TIMEOUT_SECONDS * 1000 );
|
||||
|
||||
manageContentTypeHeaders( contentType, charset, connection );
|
||||
|
||||
manageHeaders( headers, connection );
|
||||
|
||||
final Set<String> keys = params.keySet();
|
||||
|
||||
for ( String key : keys ) {
|
||||
|
||||
Object value = params.get( key );
|
||||
connection.addRequestProperty ( URLEncoder.encode (key, charset), URLEncoder.encode ( value.toString(), charset) );
|
||||
}
|
||||
return connection;
|
||||
}
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -1,929 +0,0 @@
|
|||
/*
|
||||
* Copyright 2013-2014 Richard M. Hightower
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* __________ _____ __ .__
|
||||
* \______ \ ____ ____ ____ /\ / \ _____ | | _|__| ____ ____
|
||||
* | | _// _ \ / _ \ / \ \/ / \ / \\__ \ | |/ / |/ \ / ___\
|
||||
* | | ( <_> | <_> ) | \ /\ / Y \/ __ \| <| | | \/ /_/ >
|
||||
* |______ /\____/ \____/|___| / \/ \____|__ (____ /__|_ \__|___| /\___ /
|
||||
* \/ \/ \/ \/ \/ \//_____/
|
||||
* ____. ___________ _____ ______________.___.
|
||||
* | |____ ___ _______ \_ _____/ / _ \ / _____/\__ | |
|
||||
* | \__ \\ \/ /\__ \ | __)_ / /_\ \ \_____ \ / | |
|
||||
* /\__| |/ __ \\ / / __ \_ | \/ | \/ \ \____ |
|
||||
* \________(____ /\_/ (____ / /_______ /\____|__ /_______ / / ______|
|
||||
* \/ \/ \/ \/ \/ \/
|
||||
*/
|
||||
|
||||
package org.boon;
|
||||
|
||||
|
||||
import org.boon.collections.DoubleList;
|
||||
import org.boon.collections.FloatList;
|
||||
import org.boon.collections.IntList;
|
||||
import org.boon.collections.LongList;
|
||||
import org.boon.core.*;
|
||||
import org.boon.core.reflection.*;
|
||||
import org.boon.core.reflection.fields.FieldAccess;
|
||||
import org.boon.primitive.CharBuf;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
|
||||
public class Lists {
|
||||
|
||||
|
||||
public static <T> List<T> lazyAdd(List<T> list, T... items) {
|
||||
list = list == null ? new ArrayList<T>() : list;
|
||||
|
||||
for (T item : items) {
|
||||
list.add(item);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
public static <T> List<T> lazyAdd(ArrayList<T> list, T... items) {
|
||||
list = list == null ? new ArrayList<T>() : list;
|
||||
|
||||
for (T item : items) {
|
||||
list.add(item);
|
||||
}
|
||||
return list; }
|
||||
|
||||
public static <T> List<T> safeLazyAdd(CopyOnWriteArrayList<T> list, T... items) {
|
||||
list = list == null ? new CopyOnWriteArrayList<T>() : list;
|
||||
for (T item : items) {
|
||||
list.add(item);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public static <T> List<T> lazyAdd(CopyOnWriteArrayList<T> list, T... items) {
|
||||
list = list == null ? new CopyOnWriteArrayList<T>() : list;
|
||||
for (T item : items) {
|
||||
list.add(item);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static <T> List<T> lazyCreate(List<T> list) {
|
||||
return list == null ? new ArrayList<T>() : list;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static <T> List<T> lazyCreate(ArrayList<T> list) {
|
||||
return list == null ? new ArrayList<T>() : list;
|
||||
}
|
||||
|
||||
|
||||
public static <T> List<T> lazyCreate(CopyOnWriteArrayList<T> list) {
|
||||
return list == null ? new CopyOnWriteArrayList<T>() : list;
|
||||
}
|
||||
|
||||
|
||||
public static <T> List<T> safeLazyCreate(CopyOnWriteArrayList<T> list) {
|
||||
return list == null ? new CopyOnWriteArrayList<T>() : list;
|
||||
}
|
||||
|
||||
public static <T> T fromList( List<Object> list, Class<T> clazz ) {
|
||||
return MapObjectConversion.fromList( list, clazz );
|
||||
}
|
||||
|
||||
public static <V> List<V> list( Class<V> clazz ) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
|
||||
public static <V> List<V> copy( Collection<V> collection ) {
|
||||
return new ArrayList<>( collection );
|
||||
}
|
||||
|
||||
|
||||
public static <V> List<V> deepCopy( Collection<V> collection ) {
|
||||
List<V> list = new ArrayList<>(collection.size());
|
||||
|
||||
for (V v : collection) {
|
||||
list.add( BeanUtils.copy( v ));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public static <V> List<V> deepCopyToList( Collection<V> src, List<V> dst) {
|
||||
|
||||
for (V v : src) {
|
||||
dst.add( BeanUtils.copy( v ));
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
|
||||
public static <V,T> List<T> deepCopy( Collection<V> src, Class<T> dest ) {
|
||||
List<T> list = new ArrayList<>(src.size());
|
||||
|
||||
for (V v : src) {
|
||||
list.add( BeanUtils.createFromSrc( v, dest ));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clones each list item into a new instance with copied fields.
|
||||
* It is like doing a clone operation.
|
||||
*
|
||||
* If the passed list is a LinkedList then the returned list will be a
|
||||
* LinkedList.
|
||||
*
|
||||
* If the passed list is a CopyOnWriteArrayList then the returned list will
|
||||
* be a CopyOnWriteArrayList list.
|
||||
*
|
||||
* All other lists become ArrayList.
|
||||
*
|
||||
* @param list list to clone
|
||||
* @param <V> generics
|
||||
* @return new list
|
||||
*/
|
||||
@Universal
|
||||
public static <V> List<V> deepCopy( List<V> list ) {
|
||||
if ( list instanceof LinkedList ) {
|
||||
return deepCopyToList( list, new LinkedList<V>( ) );
|
||||
} else if ( list instanceof CopyOnWriteArrayList ) {
|
||||
return deepCopyToList( list, new CopyOnWriteArrayList<V>( ));
|
||||
} else {
|
||||
return deepCopy( (Collection)list);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static <V> List<List<V>> lists( Collection<V>... collections ) {
|
||||
List<List<V>> lists = new ArrayList<>(collections.length);
|
||||
for (Collection<V> collection : collections) {
|
||||
lists.add(new ArrayList<>(collection));
|
||||
}
|
||||
return lists;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static <V> List<V> list( Iterable<V> iterable ) {
|
||||
List<V> list = new ArrayList<>();
|
||||
for ( V o : iterable ) {
|
||||
list.add( o );
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static <V> List<V> list( Collection<V> collection ) {
|
||||
return new ArrayList<>(collection);
|
||||
}
|
||||
|
||||
public static <V> List<V> linkedList( Iterable<V> iterable ) {
|
||||
List<V> list = new LinkedList<>();
|
||||
for ( V o : iterable ) {
|
||||
list.add( o );
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public static List<?> toListOrSingletonList( Object item ) {
|
||||
if ( item == null ) {
|
||||
return new ArrayList<>();
|
||||
} else if ( item.getClass().isArray() ) {
|
||||
final int length = Array.getLength( item );
|
||||
List<Object> list = new ArrayList<>();
|
||||
for ( int index = 0; index < length; index++ ) {
|
||||
list.add( Array.get( item, index ) );
|
||||
}
|
||||
return list;
|
||||
} else if ( item instanceof Collection ) {
|
||||
return list( ( Collection ) item );
|
||||
} else if ( item instanceof Iterator ) {
|
||||
return list( ( Iterator ) item );
|
||||
} else if ( item instanceof Enumeration ) {
|
||||
return list( ( Enumeration ) item );
|
||||
} else if ( item instanceof Iterable ) {
|
||||
return list( ( Iterable ) item );
|
||||
} else {
|
||||
List<Object> list = new ArrayList<>();
|
||||
list.add( item );
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static <PROP> List<PROP> toList( List<?> inputList, Class<PROP> cls, String propertyPath ) {
|
||||
List<PROP> outputList = new ArrayList<>();
|
||||
|
||||
for (Object o : inputList) {
|
||||
outputList.add((PROP) BeanUtils.idx(o, propertyPath));
|
||||
}
|
||||
|
||||
return outputList;
|
||||
}
|
||||
|
||||
public static IntList toIntList( List<?> inputList, String propertyPath ) {
|
||||
|
||||
return IntList.toIntList(inputList, propertyPath);
|
||||
}
|
||||
|
||||
|
||||
public static FloatList toFloatList( List<?> inputList, String propertyPath ) {
|
||||
|
||||
return FloatList.toFloatList(inputList, propertyPath);
|
||||
}
|
||||
|
||||
|
||||
public static DoubleList toDoubleList( List<?> inputList, String propertyPath ) {
|
||||
|
||||
return DoubleList.toDoubleList(inputList, propertyPath);
|
||||
}
|
||||
|
||||
|
||||
public static LongList toLongList( List<?> inputList, String propertyPath ) {
|
||||
|
||||
return LongList.toLongList(inputList, propertyPath);
|
||||
}
|
||||
|
||||
public static List<?> toList( List<?> inputList, String propertyPath ) {
|
||||
List<Object> outputList = new ArrayList<>();
|
||||
|
||||
for (Object o : inputList) {
|
||||
outputList.add(BeanUtils.idx(o, propertyPath));
|
||||
}
|
||||
|
||||
return outputList;
|
||||
}
|
||||
|
||||
public static List<?> toList( Object item ) {
|
||||
if ( item!= null && item.getClass().isArray() ) {
|
||||
final int length = Array.getLength( item );
|
||||
List<Object> list = new ArrayList<>();
|
||||
for ( int index = 0; index < length; index++ ) {
|
||||
list.add( Array.get( item, index ) );
|
||||
}
|
||||
return list;
|
||||
} else if ( item instanceof Collection ) {
|
||||
return list( ( Collection ) item );
|
||||
} else if ( item instanceof Iterator ) {
|
||||
return list( ( Iterator ) item );
|
||||
} else if ( item instanceof Enumeration ) {
|
||||
return list( ( Enumeration ) item );
|
||||
} else if ( item instanceof Iterable ) {
|
||||
return list( ( Iterable ) item );
|
||||
} else {
|
||||
return MapObjectConversion.toList( item );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static <V, WRAP> List<WRAP> convert(Class<WRAP> wrapper, Iterable<V> collection ) {
|
||||
List<WRAP> list = new ArrayList<>( );
|
||||
|
||||
for (V v : collection) {
|
||||
|
||||
list.add ( Conversions.coerce(wrapper, v) );
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public static <V, WRAP> List<WRAP> convert(Class<WRAP> wrapper, Collection<V> collection ) {
|
||||
List<WRAP> list = new ArrayList<>( collection.size() );
|
||||
|
||||
for (V v : collection) {
|
||||
|
||||
list.add ( Conversions.coerce(wrapper, v) );
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
public static <V, WRAP> List<WRAP> convert(Class<WRAP> wrapper, V[] collection ) {
|
||||
List<WRAP> list = new ArrayList<>( collection.length );
|
||||
|
||||
for (V v : collection) {
|
||||
|
||||
list.add ( Conversions.coerce(wrapper, v) );
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
public static <V, WRAP> List<WRAP> wrap(Class<WRAP> wrapper, Iterable<V> collection ) {
|
||||
List<WRAP> list = new ArrayList<>( );
|
||||
|
||||
for (V v : collection) {
|
||||
WRAP wrap = Reflection.newInstance ( wrapper, v );
|
||||
list.add ( wrap );
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public static <V, WRAP> List<WRAP> wrap(Class<WRAP> wrapper, Collection<V> collection ) {
|
||||
|
||||
if (collection.size()==0) {
|
||||
return Collections.EMPTY_LIST;
|
||||
}
|
||||
|
||||
List<WRAP> list = new ArrayList<>( collection.size () );
|
||||
|
||||
|
||||
|
||||
ClassMeta <WRAP> cls = ClassMeta.classMeta(wrapper);
|
||||
ConstructorAccess<WRAP> declaredConstructor = cls.declaredConstructor(collection.iterator().next().getClass());
|
||||
|
||||
for (V v : collection) {
|
||||
WRAP wrap = declaredConstructor.create ( v );
|
||||
list.add ( wrap );
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
public static <V, WRAP> List<WRAP> wrap(Class<WRAP> wrapper, V[] collection ) {
|
||||
List<WRAP> list = new ArrayList<>( collection.length );
|
||||
|
||||
for (V v : collection) {
|
||||
WRAP wrap = Reflection.newInstance ( wrapper, v );
|
||||
list.add ( wrap );
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public static <V> List<V> list( Enumeration<V> enumeration ) {
|
||||
List<V> list = new ArrayList<>();
|
||||
while ( enumeration.hasMoreElements() ) {
|
||||
list.add( enumeration.nextElement() );
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
public static <V> Enumeration<V> enumeration( final List<V> list ) {
|
||||
final Iterator<V> iter = list.iterator();
|
||||
return new Enumeration<V>() {
|
||||
@Override
|
||||
public boolean hasMoreElements() {
|
||||
return iter.hasNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public V nextElement() {
|
||||
return iter.next();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static <V> List<V> list( Iterator<V> iterator ) {
|
||||
List<V> list = new ArrayList<>();
|
||||
while ( iterator.hasNext() ) {
|
||||
list.add( iterator.next() );
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@SafeVarargs
|
||||
public static <V> List<V> list( final V... array ) {
|
||||
if ( array == null ) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
List<V> list = new ArrayList<>( array.length );
|
||||
Collections.addAll( list, array );
|
||||
return list;
|
||||
}
|
||||
|
||||
public static <V> List<V> safeList(Class<V> cls) {
|
||||
return new CopyOnWriteArrayList<>( );
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
public static <V> List<V> safeList( final V... array ) {
|
||||
return new CopyOnWriteArrayList<>( array );
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
public static <V> List<V> linkedList( final V... array ) {
|
||||
if ( array == null ) {
|
||||
return new LinkedList<>();
|
||||
}
|
||||
List<V> list = new LinkedList<>();
|
||||
Collections.addAll( list, array );
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
public static <V> List<V> safeList( Collection<V> collection ) {
|
||||
return new CopyOnWriteArrayList<>( collection );
|
||||
}
|
||||
|
||||
public static <V> List<V> linkedList( Collection<V> collection ) {
|
||||
return new LinkedList<>( collection );
|
||||
}
|
||||
|
||||
/**
|
||||
* Universal methods
|
||||
*/
|
||||
@Universal
|
||||
public static int len( List<?> list ) {
|
||||
return list.size();
|
||||
}
|
||||
|
||||
|
||||
@Universal
|
||||
public static int lengthOf( List<?> list ) {
|
||||
return len (list);
|
||||
}
|
||||
|
||||
public static boolean isEmpty( List<?> list ) {
|
||||
return list == null || list.size() == 0;
|
||||
}
|
||||
|
||||
@Universal
|
||||
public static <V> boolean in( V value, List<?> list ) {
|
||||
return list.contains( value );
|
||||
}
|
||||
|
||||
@Universal
|
||||
public static <V> void add( List<V> list, V value ) {
|
||||
list.add( value );
|
||||
}
|
||||
|
||||
|
||||
@Universal
|
||||
public static <V> void add( List<V> list, V... values ) {
|
||||
for (V v : values) {
|
||||
list.add( v );
|
||||
}
|
||||
}
|
||||
|
||||
@Universal
|
||||
public static <T> T atIndex( List<T> list, final int index ) {
|
||||
|
||||
return idx(list, index);
|
||||
|
||||
}
|
||||
|
||||
@Universal
|
||||
public static <T> T idx( List<T> list, final int index ) {
|
||||
int i = calculateIndex( list, index );
|
||||
if ( i > list.size() - 1 ) {
|
||||
i = list.size() - 1;
|
||||
}
|
||||
return list.get( i );
|
||||
|
||||
}
|
||||
|
||||
public static <T> List idxList( List<T> list, final int index ) {
|
||||
return (List) idx(list, index);
|
||||
}
|
||||
|
||||
|
||||
public static <T> Map idxMap( List<T> list, final int index ) {
|
||||
return (Map) idx(list, index);
|
||||
}
|
||||
|
||||
|
||||
@Universal
|
||||
public static <V> void atIndex( List<V> list, int index, V v ) {
|
||||
idx (list, index, v);
|
||||
}
|
||||
|
||||
@Universal
|
||||
public static <V> void idx( List<V> list, int index, V v ) {
|
||||
int i = calculateIndex( list, index );
|
||||
list.set( i, v );
|
||||
}
|
||||
|
||||
|
||||
@Universal
|
||||
public static <V> List<V> sliceOf( List<V> list, int startIndex, int endIndex ) {
|
||||
return slc(list, startIndex, endIndex);
|
||||
}
|
||||
|
||||
@Universal
|
||||
public static <V> List<V> slc( List<V> list, int startIndex, int endIndex ) {
|
||||
int start = calculateIndex( list, startIndex );
|
||||
int end = calculateIndex( list, endIndex );
|
||||
return list.subList( start, end );
|
||||
}
|
||||
|
||||
|
||||
@Universal
|
||||
public static <V> List<V> sliceOf( List<V> list, int startIndex ) {
|
||||
return slc(list, startIndex);
|
||||
}
|
||||
|
||||
@Universal
|
||||
public static <V> List<V> slc( List<V> list, int startIndex ) {
|
||||
return slc( list, startIndex, list.size() );
|
||||
}
|
||||
|
||||
@Universal
|
||||
public static <V> List<V> endSliceOf( List<V> list, int endIndex ) {
|
||||
return slcEnd( list, endIndex );
|
||||
}
|
||||
|
||||
|
||||
@Universal
|
||||
public static <V> List<V> slcEnd( List<V> list, int endIndex ) {
|
||||
return slc( list, 0, endIndex );
|
||||
}
|
||||
|
||||
|
||||
@Universal
|
||||
public static <V> List<V> copy( List<V> list ) {
|
||||
if ( list instanceof LinkedList ) {
|
||||
return new LinkedList<>( list );
|
||||
} else if ( list instanceof CopyOnWriteArrayList ) {
|
||||
return new CopyOnWriteArrayList<>( list );
|
||||
} else {
|
||||
return new ArrayList<>( list );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Universal
|
||||
public static <V> List<V> copy( CopyOnWriteArrayList<V> list ) {
|
||||
return new CopyOnWriteArrayList<>( list );
|
||||
}
|
||||
|
||||
@Universal
|
||||
public static <V> List<V> copy( ArrayList<V> list ) {
|
||||
return new ArrayList<>( list );
|
||||
}
|
||||
|
||||
@Universal
|
||||
public static <V> List<V> copy( LinkedList<V> list ) {
|
||||
return new LinkedList<>( list );
|
||||
}
|
||||
|
||||
|
||||
@Universal
|
||||
public static <V> void insert( List<V> list, int index, V v ) {
|
||||
int i = calculateIndex( list, index );
|
||||
list.add( i, v );
|
||||
}
|
||||
|
||||
|
||||
/* End universal methods. */
|
||||
private static <T> int calculateIndex( List<T> list, int originalIndex ) {
|
||||
final int length = list.size();
|
||||
|
||||
int index = originalIndex;
|
||||
|
||||
/* Adjust for reading from the right as in
|
||||
-1 reads the 4th element if the length is 5
|
||||
*/
|
||||
if ( index < 0 ) {
|
||||
index = ( length + index );
|
||||
}
|
||||
|
||||
|
||||
/* Bounds check
|
||||
if it is still less than 0, then they
|
||||
have an negative index that is greater than length
|
||||
*/
|
||||
if ( index < 0 ) {
|
||||
index = 0;
|
||||
}
|
||||
if ( index > length ) {
|
||||
index = length;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
|
||||
public static <T> List<T> listFromProperty( Class<T> propertyType, String propertyPath, Collection<?> list ) {
|
||||
List<T> newList = new ArrayList<>( list.size() );
|
||||
|
||||
for ( Object item : list ) {
|
||||
T newItem = ( T ) BeanUtils.idx( item, propertyPath );
|
||||
newList.add( newItem );
|
||||
}
|
||||
|
||||
return newList;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static <T> List<T> listFromProperty( Class<T> propertyType, String propertyPath, Iterable<?> list ) {
|
||||
List<T> newList = new ArrayList<>( );
|
||||
|
||||
for ( Object item : list ) {
|
||||
T newItem = ( T ) BeanUtils.idx( item, propertyPath );
|
||||
newList.add( newItem );
|
||||
}
|
||||
|
||||
return newList;
|
||||
|
||||
}
|
||||
public static List<Map<String, Object>> toListOfMaps( List<?> list ) {
|
||||
return MapObjectConversion.toListOfMaps( list );
|
||||
}
|
||||
|
||||
public static void setListProperty(List<?> list, String propertyName, Object value) {
|
||||
for (Object object : list) {
|
||||
BeanUtils.idx(object, propertyName, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static List<?> mapBy( Object[] objects, Object instance, String methodName) {
|
||||
|
||||
List list = new ArrayList(objects.length);
|
||||
for (Object o : objects) {
|
||||
list.add( Invoker.invoke(instance, methodName, o ));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
public static List<?> mapBy(Object[] objects, Class<?> cls, String methodName) {
|
||||
|
||||
List list = new ArrayList(objects.length);
|
||||
for (Object o : objects) {
|
||||
list.add( Invoker.invoke(cls,methodName, o ));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static List<?> mapBy(Iterable<?> objects, Class<?> cls, String methodName) {
|
||||
|
||||
List list = new ArrayList();
|
||||
for (Object o : objects) {
|
||||
list.add( Invoker.invoke(cls, methodName, o ));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
public static List<?> mapBy(Iterable<?> objects, Object instance, String methodName) {
|
||||
|
||||
List list = new ArrayList();
|
||||
for (Object o : objects) {
|
||||
list.add( Invoker.invoke(instance, methodName, o ));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
public static List<?> mapBy(Collection<?> objects, Class<?> cls, String methodName) {
|
||||
|
||||
List list = new ArrayList(objects.size());
|
||||
|
||||
MethodAccess methodAccess = Invoker.invokeMethodAccess(cls, methodName);
|
||||
|
||||
for (Object o : objects) {
|
||||
list.add( methodAccess.invokeStatic(o));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public static List<?> mapBy(Collection<?> objects, Object function) {
|
||||
|
||||
|
||||
MethodAccess methodAccess = Invoker.invokeFunctionMethodAccess(function);
|
||||
|
||||
List list = new ArrayList();
|
||||
for (Object o : objects) {
|
||||
list.add( methodAccess.invoke(function, o));
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
public static <T> List<T> mapBy(Class<T> cls, Collection<?> objects, Object function) {
|
||||
return (List<T>) mapBy(objects, function);
|
||||
}
|
||||
|
||||
public static List<?> mapBy(Iterable<?> objects, Object function) {
|
||||
|
||||
|
||||
MethodAccess methodAccess = Invoker.invokeFunctionMethodAccess(function);
|
||||
|
||||
List list = new ArrayList();
|
||||
for (Object o : objects) {
|
||||
list.add( methodAccess.invoke(function, o));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
public static List<?> mapBy(Object[] objects, Object function) {
|
||||
|
||||
MethodAccess methodAccess = Invoker.invokeFunctionMethodAccess(function);
|
||||
|
||||
List list = new ArrayList(objects.length);
|
||||
for (Object o : objects) {
|
||||
list.add( methodAccess.invoke(function, o));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static List<?> mapBy(Collection<?> objects, Object object, String methodName) {
|
||||
|
||||
|
||||
MethodAccess methodAccess = Invoker.invokeMethodAccess(object.getClass(), methodName);
|
||||
|
||||
List list = new ArrayList(objects.size());
|
||||
for (Object o : objects) {
|
||||
list.add( methodAccess.invoke(object, o));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
public static <V, N> List<N> mapBy( final V[] array, Function<V, N> function ) {
|
||||
List<N> list = new ArrayList<>( array.length );
|
||||
|
||||
for ( V v : array ) {
|
||||
list.add( function.apply( v ) );
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public static <V, N> List<N> mapBy( final Collection<V> array, Function<V, N> function ) {
|
||||
List<N> list = new ArrayList<>( array.size() );
|
||||
|
||||
for ( V v : array ) {
|
||||
list.add( function.apply( v ) );
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public static <V, N> List<N> mapBy( final Iterable<V> array, Function<V, N> function ) {
|
||||
List<N> list = new ArrayList<>( );
|
||||
|
||||
for ( V v : array ) {
|
||||
list.add( function.apply( v ) );
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
public static <V, SUM> SUM reduceBy( final Iterable<V> array, Reducer<V, SUM> function ) {
|
||||
|
||||
SUM sum = null;
|
||||
for ( V v : array ) {
|
||||
sum = function.apply( sum, v ) ;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
|
||||
public static Object reduceBy( final Iterable<?> array, Object object ) {
|
||||
|
||||
Object sum = null;
|
||||
for ( Object v : array ) {
|
||||
sum = Invoker.invokeReducer(object, sum, v);
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static <T> List<T> filterBy( final Iterable<T> array, Predicate<T> predicate ) {
|
||||
List<T> list = new ArrayList<>( );
|
||||
|
||||
for ( T v : array ) {
|
||||
if ( predicate.test(v)) {
|
||||
list.add( v );
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
public static <T> List<T> filterBy( final Collection<T> array, Predicate<T> predicate ) {
|
||||
List<T> list = new ArrayList<>( array.size() );
|
||||
|
||||
for ( T v : array ) {
|
||||
if ( predicate.test(v)) {
|
||||
list.add( v );
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
public static <T> List<T> filterBy( Predicate<T> predicate, final T[] array ) {
|
||||
List<T> list = new ArrayList<>( array.length );
|
||||
|
||||
for ( T v : array ) {
|
||||
if ( predicate.test(v)) {
|
||||
list.add( v );
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static <T> List<T> filterBy( final Iterable<T> array, Object object ) {
|
||||
List<T> list = new ArrayList<>( );
|
||||
|
||||
for ( T v : array ) {
|
||||
if ( Invoker.invokeBooleanReturn(object, v) ) {
|
||||
list.add( v );
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
public static <T> List<T> filterBy( final Collection<T> array, Object object ) {
|
||||
List<T> list = new ArrayList<>( array.size() );
|
||||
|
||||
for ( T v : array ) {
|
||||
if ( Invoker.invokeBooleanReturn(object, v) ) {
|
||||
list.add( v );
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
public static <T> List<T> filterBy( final T[] array, Object object ) {
|
||||
List<T> list = new ArrayList<>( array.length );
|
||||
|
||||
for ( T v : array ) {
|
||||
if ( Invoker.invokeBooleanReturn(object, v) ) {
|
||||
list.add( v );
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static <T> List<T> filterBy( final Iterable<T> array, Object object, String methodName ) {
|
||||
List<T> list = new ArrayList<>( );
|
||||
|
||||
for ( T v : array ) {
|
||||
if ( (boolean) Invoker.invokeEither(object, methodName, v) ) {
|
||||
list.add( v );
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
public static <T> List<T> filterBy( final Collection<T> array, Object object, String methodName ) {
|
||||
List<T> list = new ArrayList<>( array.size() );
|
||||
|
||||
for ( T v : array ) {
|
||||
if ( (boolean) Invoker.invokeEither(object, methodName, v) ) {
|
||||
list.add( v );
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
public static <T> List<T> filterBy( final T[] array, Object object, String methodName ) {
|
||||
List<T> list = new ArrayList<>( array.length );
|
||||
|
||||
for ( T v : array ) {
|
||||
if ( (boolean) Invoker.invokeEither(object, methodName, v) ) {
|
||||
list.add( v );
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static String toPrettyJson(List list) {
|
||||
CharBuf buf = CharBuf.createCharBuf();
|
||||
return buf.prettyPrintCollection(list, false, 0).toString();
|
||||
}
|
||||
}
|
|
@ -1,226 +0,0 @@
|
|||
/*
|
||||
* Copyright 2013-2014 Richard M. Hightower
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* __________ _____ __ .__
|
||||
* \______ \ ____ ____ ____ /\ / \ _____ | | _|__| ____ ____
|
||||
* | | _// _ \ / _ \ / \ \/ / \ / \\__ \ | |/ / |/ \ / ___\
|
||||
* | | ( <_> | <_> ) | \ /\ / Y \/ __ \| <| | | \/ /_/ >
|
||||
* |______ /\____/ \____/|___| / \/ \____|__ (____ /__|_ \__|___| /\___ /
|
||||
* \/ \/ \/ \/ \/ \//_____/
|
||||
* ____. ___________ _____ ______________.___.
|
||||
* | |____ ___ _______ \_ _____/ / _ \ / _____/\__ | |
|
||||
* | \__ \\ \/ /\__ \ | __)_ / /_\ \ \_____ \ / | |
|
||||
* /\__| |/ __ \\ / / __ \_ | \/ | \/ \ \____ |
|
||||
* \________(____ /\_/ (____ / /_______ /\____|__ /_______ / / ______|
|
||||
* \/ \/ \/ \/ \/ \/
|
||||
*/
|
||||
|
||||
package org.boon;
|
||||
|
||||
|
||||
import org.boon.core.Handler;
|
||||
import org.boon.logging.*;
|
||||
|
||||
/**
|
||||
* <p>This class allows isolation of all logging dependencies in one place.
|
||||
*
|
||||
* There is 0 dependencies on third party logs</p>
|
||||
*
|
||||
* <p>By default logging uses uses JDK logging.
|
||||
* The logging configuration file (logging.properties).
|
||||
* You can use standard JDK logging config.</p>
|
||||
*
|
||||
* I wrote similar facilities in Crank and EasyJava,
|
||||
* but this style was heavily inspired by Vertx which was inspired by JBoss.
|
||||
*
|
||||
* @author Rick Hightower
|
||||
*/
|
||||
public class Logger {
|
||||
|
||||
|
||||
private transient volatile LoggerDelegate logger;
|
||||
final LoggerDelegate original;
|
||||
|
||||
|
||||
public Logger(final LoggerDelegate delegate) {
|
||||
logger = delegate;
|
||||
original = logger;
|
||||
}
|
||||
|
||||
public synchronized void tee(LoggerDelegate newLogger) {
|
||||
logger = new TeeLoggerWrapper(logger, newLogger);
|
||||
}
|
||||
|
||||
|
||||
public synchronized void handler(Handler<LogRecord> handler) {
|
||||
logger = new ConfigurableLogger(logger, handler);
|
||||
}
|
||||
|
||||
|
||||
public synchronized void teeAndHandler(LoggerDelegate newLogger, Handler<LogRecord> handler) {
|
||||
logger = new TeeLoggerWrapper(logger, newLogger);
|
||||
}
|
||||
|
||||
|
||||
public synchronized void unwrap() {
|
||||
logger = original;
|
||||
}
|
||||
|
||||
public boolean infoOn() {
|
||||
return logger.infoOn();
|
||||
}
|
||||
|
||||
public boolean debugOn() {
|
||||
return logger.debugOn();
|
||||
}
|
||||
|
||||
public boolean traceOn() {
|
||||
return logger.traceOn();
|
||||
}
|
||||
|
||||
public void fatal(final Object message) {
|
||||
logger.fatal(message);
|
||||
}
|
||||
|
||||
|
||||
public void fatal(final Exception message) {
|
||||
logger.fatal("", message);
|
||||
}
|
||||
|
||||
|
||||
public void error(final Exception message) {
|
||||
logger.error("", message);
|
||||
}
|
||||
|
||||
|
||||
public void warn(final Exception message) {
|
||||
logger.warn("", message);
|
||||
}
|
||||
|
||||
|
||||
public void fatal(final Object message, final Throwable t) {
|
||||
logger.fatal(message, t);
|
||||
}
|
||||
|
||||
public void error(final Object message) {
|
||||
logger.error(message);
|
||||
}
|
||||
|
||||
public void error(final Object message, final Throwable t) {
|
||||
logger.error(message, t);
|
||||
}
|
||||
|
||||
public void warn(final Object message) {
|
||||
logger.warn(message);
|
||||
}
|
||||
|
||||
public void warn(final Object message, final Throwable t) {
|
||||
logger.warn(message, t);
|
||||
}
|
||||
|
||||
public void info(final Object message) {
|
||||
logger.info(message);
|
||||
}
|
||||
|
||||
public void info(final Object message, final Throwable t) {
|
||||
logger.info(message, t);
|
||||
}
|
||||
|
||||
public void debug(final Object message) {
|
||||
logger.debug(message);
|
||||
}
|
||||
|
||||
public void debug(final Object message, final Throwable t) {
|
||||
logger.debug(message, t);
|
||||
}
|
||||
|
||||
public void trace(final Object message) {
|
||||
logger.trace(message);
|
||||
}
|
||||
|
||||
public void trace(final Object message, final Throwable t) {
|
||||
logger.trace(message, t);
|
||||
}
|
||||
|
||||
|
||||
public void level(LogLevel level) {
|
||||
logger.level(level);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void turnOff() {
|
||||
logger.turnOff();
|
||||
}
|
||||
|
||||
public void fatal(Object... messages) {
|
||||
logger.fatal(messages);
|
||||
}
|
||||
|
||||
public void fatal(Throwable t, Object... messages) {
|
||||
logger.fatal(t, messages);
|
||||
}
|
||||
|
||||
public void error(Object... messages) {
|
||||
logger.error(messages);
|
||||
}
|
||||
|
||||
public void error(Throwable t, Object... messages) {
|
||||
logger.error(t, messages);
|
||||
}
|
||||
|
||||
public void warn(Object... messages) {
|
||||
logger.warn(messages);
|
||||
}
|
||||
|
||||
public void warn(Throwable t, Object... messages) {
|
||||
|
||||
logger.warn(t, messages);
|
||||
}
|
||||
|
||||
public void info(Object... messages) {
|
||||
logger.info(messages);
|
||||
}
|
||||
|
||||
public void info(Throwable t, Object... messages) {
|
||||
logger.info(t, messages);
|
||||
}
|
||||
|
||||
public void config(Object... messages) {
|
||||
logger.config(messages);
|
||||
}
|
||||
|
||||
public void config(Throwable t, Object... messages) {
|
||||
logger.config(t, messages);
|
||||
}
|
||||
|
||||
public void debug(Object... messages) {
|
||||
logger.debug(messages);
|
||||
}
|
||||
|
||||
public void debug(Throwable t, Object... messages) {
|
||||
logger.debug(t, messages);
|
||||
}
|
||||
|
||||
public void trace(Object... messages) {
|
||||
logger.trace(messages);
|
||||
|
||||
}
|
||||
|
||||
public void trace(Throwable t, Object... messages) {
|
||||
logger.trace(t, messages);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,244 +0,0 @@
|
|||
/*
|
||||
* Copyright 2013-2014 Richard M. Hightower
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* __________ _____ __ .__
|
||||
* \______ \ ____ ____ ____ /\ / \ _____ | | _|__| ____ ____
|
||||
* | | _// _ \ / _ \ / \ \/ / \ / \\__ \ | |/ / |/ \ / ___\
|
||||
* | | ( <_> | <_> ) | \ /\ / Y \/ __ \| <| | | \/ /_/ >
|
||||
* |______ /\____/ \____/|___| / \/ \____|__ (____ /__|_ \__|___| /\___ /
|
||||
* \/ \/ \/ \/ \/ \//_____/
|
||||
* ____. ___________ _____ ______________.___.
|
||||
* | |____ ___ _______ \_ _____/ / _ \ / _____/\__ | |
|
||||
* | \__ \\ \/ /\__ \ | __)_ / /_\ \ \_____ \ / | |
|
||||
* /\__| |/ __ \\ / / __ \_ | \/ | \/ \ \____ |
|
||||
* \________(____ /\_/ (____ / /_______ /\____|__ /_______ / / ______|
|
||||
* \/ \/ \/ \/ \/ \/
|
||||
*/
|
||||
|
||||
package org.boon;
|
||||
|
||||
import javax.management.*;
|
||||
import javax.management.openmbean.CompositeData;
|
||||
import javax.management.openmbean.TabularData;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.*;
|
||||
|
||||
import static org.boon.Boon.toJson;
|
||||
import static org.boon.Exceptions.requireNonNull;
|
||||
|
||||
|
||||
/**
|
||||
* Utility methods to convert MBeans to a Map.
|
||||
*/
|
||||
public class MBeans {
|
||||
|
||||
public static String toJson () {
|
||||
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
|
||||
return toJson(server);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static String toJson (final MBeanServer server) {
|
||||
Set<ObjectName> objectNames = server.queryNames( null, null );
|
||||
|
||||
Map<String, Map<String, Object>> map = new LinkedHashMap<>();
|
||||
|
||||
for ( ObjectName name : objectNames ) {
|
||||
|
||||
map.put(name.toString(), MBeans.map(server, name));
|
||||
|
||||
}
|
||||
|
||||
return Boon.toJson(map);
|
||||
}
|
||||
|
||||
public static Map<String, Object> map( final ObjectName name ) {
|
||||
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
|
||||
return map(server, name);
|
||||
}
|
||||
|
||||
|
||||
public static Map<String, Object> map( final MBeanServer server,
|
||||
final ObjectName name ) {
|
||||
|
||||
|
||||
requireNonNull( server, "server cannot be null" );
|
||||
requireNonNull( name, "name cannot be null" );
|
||||
|
||||
|
||||
/* Return the bean attributes converted to a map. */
|
||||
Map<String, Object> result;
|
||||
MBeanInfo info = null;
|
||||
|
||||
try {
|
||||
|
||||
|
||||
info = server.getMBeanInfo( name );
|
||||
|
||||
final String[] attributeNames = getAttributeNames( info );
|
||||
result = new HashMap<>( attributeNames.length );
|
||||
|
||||
|
||||
final AttributeList attributeList = server.getAttributes( name, attributeNames );
|
||||
|
||||
|
||||
for ( Object obj : attributeList ) {
|
||||
final Attribute attribute = ( Attribute ) obj;
|
||||
result.put( attribute.getName(), convertValue( attribute.getValue() ) );
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
} catch ( Exception ex ) {
|
||||
|
||||
return Exceptions.handle( Map.class, String.format(
|
||||
"Unable to turn mbean into map %s ", name.getCanonicalName()
|
||||
), ex );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static String[] getAttributeNames( MBeanInfo info ) {
|
||||
final MBeanAttributeInfo[] attributes = info.getAttributes();
|
||||
final String[] attributeNames = new String[ attributes.length ];
|
||||
|
||||
for ( int index = 0; index < attributes.length; index++ ) {
|
||||
|
||||
attributeNames[ index ] = attributes[ index ].getName();
|
||||
}
|
||||
return attributeNames;
|
||||
}
|
||||
|
||||
private static Object convertValue( Object value ) {
|
||||
|
||||
|
||||
/* convert nulls */
|
||||
if ( value == null ) {
|
||||
value = "null";
|
||||
}
|
||||
|
||||
/* convert an array to a List and convert the component objects of the array.
|
||||
*/
|
||||
if ( value.getClass().isArray() ) {
|
||||
|
||||
value = convertFromArrayToList( value );
|
||||
|
||||
} else if ( value instanceof CompositeData ) {
|
||||
|
||||
value = convertFromCompositeDataToToMap( value );
|
||||
|
||||
} else if ( value instanceof TabularData ) {
|
||||
value = convertFromTabularDataToMap( value );
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
private static Object convertFromTabularDataToMap( Object value ) {
|
||||
final TabularData data = ( TabularData ) value;
|
||||
|
||||
final Set<List<?>> keys = ( Set<List<?>> ) data.keySet();
|
||||
|
||||
final Map<String, Object> map = new HashMap<>();
|
||||
for ( final List<?> key : keys ) {
|
||||
final Object subValue = convertValue( data.get( key.toArray() ) );
|
||||
|
||||
if ( key.size() == 1 ) {
|
||||
map.put( convertValue( key.get( 0 ) ).toString(), subValue );
|
||||
} else {
|
||||
map.put( convertValue( key ).toString(), subValue );
|
||||
}
|
||||
}
|
||||
|
||||
value = map;
|
||||
return value;
|
||||
}
|
||||
|
||||
private static Object convertFromCompositeDataToToMap( Object value ) {
|
||||
final CompositeData data = ( CompositeData ) value;
|
||||
final Map<String, Object> map = new HashMap<String, Object>();
|
||||
final Set<String> keySet = data.getCompositeType().keySet();
|
||||
|
||||
for ( final String key : keySet ) {
|
||||
map.put( key, convertValue( data.get( key ) ) );
|
||||
}
|
||||
|
||||
value = map;
|
||||
return value;
|
||||
}
|
||||
|
||||
private static Object convertFromArrayToList( Object value ) {
|
||||
final List<Object> list = new ArrayList<Object>();
|
||||
|
||||
final int length = Array.getLength( value );
|
||||
|
||||
for ( int index = 0; index < length; index++ ) {
|
||||
list.add( convertValue( Array.get( value, index ) ) );
|
||||
}
|
||||
|
||||
value = list;
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
public static DynamicMBean createMBean( final Object instance, final Class<?> managedInterface ) {
|
||||
|
||||
requireNonNull( instance, "instance cannot be null" );
|
||||
requireNonNull( managedInterface, "managedInterface cannot be null" );
|
||||
|
||||
|
||||
try {
|
||||
|
||||
/* Create the bean. */
|
||||
return new StandardMBean( instance, ( Class ) managedInterface );
|
||||
|
||||
} catch ( final NotCompliantMBeanException ex ) {
|
||||
return Exceptions.handle( DynamicMBean.class, String.format(
|
||||
"createMBean unable to register %s under interface %s",
|
||||
instance.getClass().getName(), managedInterface.getClass().getName()
|
||||
), ex );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static void registerMBean( final String prefix, final String name, final Object mbean ) {
|
||||
|
||||
Exceptions.requireNonNull( prefix, "prefix can't be null" );
|
||||
Exceptions.requireNonNull( name, "name can't be null" );
|
||||
Exceptions.requireNonNull( mbean, "mbean can't be null" );
|
||||
|
||||
String nameOfBean = nameOfBean = String.format( "%s.%s:type=%s",
|
||||
prefix, mbean.getClass().getSimpleName(),
|
||||
name );
|
||||
|
||||
try {
|
||||
|
||||
|
||||
final ObjectName objectName = new ObjectName( nameOfBean );
|
||||
|
||||
final MBeanServer beanServer = ManagementFactory.getPlatformMBeanServer();
|
||||
|
||||
beanServer.registerMBean( mbean, objectName );
|
||||
|
||||
} catch ( final Exception ex ) {
|
||||
Exceptions.handle( String.format(
|
||||
"registerMBean %s %s %s %s", prefix, name, mbean, nameOfBean
|
||||
), ex );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -1,149 +0,0 @@
|
|||
/*
|
||||
* Copyright 2013-2014 Richard M. Hightower
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* __________ _____ __ .__
|
||||
* \______ \ ____ ____ ____ /\ / \ _____ | | _|__| ____ ____
|
||||
* | | _// _ \ / _ \ / \ \/ / \ / \\__ \ | |/ / |/ \ / ___\
|
||||
* | | ( <_> | <_> ) | \ /\ / Y \/ __ \| <| | | \/ /_/ >
|
||||
* |______ /\____/ \____/|___| / \/ \____|__ (____ /__|_ \__|___| /\___ /
|
||||
* \/ \/ \/ \/ \/ \//_____/
|
||||
* ____. ___________ _____ ______________.___.
|
||||
* | |____ ___ _______ \_ _____/ / _ \ / _____/\__ | |
|
||||
* | \__ \\ \/ /\__ \ | __)_ / /_\ \ \_____ \ / | |
|
||||
* /\__| |/ __ \\ / / __ \_ | \/ | \/ \ \____ |
|
||||
* \________(____ /\_/ (____ / /_______ /\____|__ /_______ / / ______|
|
||||
* \/ \/ \/ \/ \/ \/
|
||||
*/
|
||||
|
||||
package org.boon;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.boon.Exceptions.die;
|
||||
|
||||
/**
|
||||
* Created by Richard on 3/7/14.
|
||||
*/
|
||||
public class Ok {
|
||||
|
||||
public static boolean ok(Object object) {
|
||||
return object!=null;
|
||||
}
|
||||
|
||||
|
||||
public static boolean ok(boolean value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
public static boolean ok(Number i) {
|
||||
return i!=null && i.intValue()!=0;
|
||||
}
|
||||
|
||||
public static boolean ok(int i) {
|
||||
return i!=0;
|
||||
}
|
||||
|
||||
public static boolean ok(long i) {
|
||||
return i!=0;
|
||||
}
|
||||
|
||||
public static boolean ok(Map map) {
|
||||
return map!=null && map.size() >0;
|
||||
}
|
||||
|
||||
public static boolean ok(Collection c) {
|
||||
return c!=null && c.size() >0;
|
||||
}
|
||||
|
||||
|
||||
public static boolean ok(CharSequence cs) {
|
||||
return cs!=null && cs.length() >0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static boolean okOrDie(Object object) {
|
||||
return object!=null || die();
|
||||
}
|
||||
|
||||
|
||||
public static boolean okOrDie(boolean value) {
|
||||
return value || die();
|
||||
}
|
||||
|
||||
public static boolean okOrDie(Number i) {
|
||||
return (i!=null && i.intValue() !=0) || die();
|
||||
}
|
||||
|
||||
|
||||
public static boolean okOrDie(int i) {
|
||||
return i!=0 || die();
|
||||
}
|
||||
|
||||
public static boolean okOrDie(long i) {
|
||||
return i!=0 || die();
|
||||
}
|
||||
|
||||
public static boolean okOrDie(Map map) {
|
||||
return (map!=null && map.size() >0) || die();
|
||||
}
|
||||
|
||||
public static boolean okOrDie(Collection c) {
|
||||
return (c!=null && c.size() >0) || die();
|
||||
}
|
||||
|
||||
|
||||
public static boolean okOrDie(CharSequence cs) {
|
||||
return (cs!=null && cs.length() >0) || die();
|
||||
}
|
||||
|
||||
|
||||
public static boolean okOrDie(String message, Object object) {
|
||||
return object!=null || die(message);
|
||||
}
|
||||
|
||||
public static boolean okOrDie(String message, int i) {
|
||||
return i!=0 || die(message);
|
||||
}
|
||||
|
||||
public static boolean okOrDie(String message, long i) {
|
||||
return i!=0 || die(message);
|
||||
}
|
||||
|
||||
public static boolean okOrDie(String message, Map map) {
|
||||
return (map!=null && map.size() >0) || die(message);
|
||||
}
|
||||
|
||||
public static boolean okOrDie(String message, Collection c) {
|
||||
return (c!=null && c.size() >0) || die(message);
|
||||
}
|
||||
|
||||
|
||||
public static boolean okOrDie(String message, CharSequence cs) {
|
||||
return (cs!=null && cs.length() >0) || die(message);
|
||||
}
|
||||
|
||||
|
||||
public static boolean okOrDie(String message, boolean value) {
|
||||
return value || die(message);
|
||||
}
|
||||
|
||||
public static boolean okOrDie(String message, Number i) {
|
||||
return (i!=null && i.intValue() !=0) || die(message);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,136 +0,0 @@
|
|||
package org.boon;
|
||||
|
||||
|
||||
import static org.boon.Exceptions.requireNonNull;
|
||||
|
||||
/**
|
||||
* Created by Richard on 9/9/14.
|
||||
*/
|
||||
public class Pair<K, V> implements Entry<K, V> {
|
||||
|
||||
|
||||
public static <K, V> Entry<K, V> entry( final K k, final V v ) {
|
||||
return new Pair<>( k, v );
|
||||
}
|
||||
|
||||
|
||||
public static <K, V> Pair<K, V> pair( final K k, final V v ) {
|
||||
return new Pair<>( k, v );
|
||||
}
|
||||
|
||||
public static <K, V> Entry<K, V> entry( Entry<K, V> entry ) {
|
||||
return new Pair<>( entry );
|
||||
}
|
||||
|
||||
private K k;
|
||||
private V v;
|
||||
|
||||
public Pair() {
|
||||
|
||||
}
|
||||
|
||||
public Pair(Pair<K, V> impl) {
|
||||
requireNonNull( impl );
|
||||
requireNonNull( impl.k );
|
||||
|
||||
this.k = impl.k;
|
||||
this.v = impl.v;
|
||||
}
|
||||
|
||||
public Pair(Entry<K, V> entry) {
|
||||
requireNonNull( entry );
|
||||
requireNonNull( entry.key() );
|
||||
|
||||
this.k = entry.key();
|
||||
this.v = entry.value();
|
||||
}
|
||||
|
||||
public Pair(K k, V v) {
|
||||
Exceptions.requireNonNull( k );
|
||||
|
||||
this.k = k;
|
||||
this.v = v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public K key() {
|
||||
return k;
|
||||
}
|
||||
|
||||
|
||||
public K getFirst() {
|
||||
return k;
|
||||
}
|
||||
public V getSecond() {
|
||||
return v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public V value() {
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public K getKey() {
|
||||
return k;
|
||||
}
|
||||
|
||||
@Override
|
||||
public V getValue() {
|
||||
return v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public V setValue(V value) {
|
||||
V old = this.v;
|
||||
this.v = value;
|
||||
return old;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals( Object o ) {
|
||||
if ( this == o ) return true;
|
||||
if ( o == null || getClass() != o.getClass() ) return false;
|
||||
|
||||
Pair entry = (Pair) o;
|
||||
return this.equals( entry );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals( Entry entry ) {
|
||||
|
||||
if ( k != null ? !k.equals( entry.key() ) : entry.key() != null ) return false;
|
||||
return !( v != null ? !v.equals( entry.value() ) : entry.value() != null );
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = k != null ? k.hashCode() : 0;
|
||||
result = 31 * result + ( v != null ? v.hashCode() : 0 );
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo( Entry entry ) {
|
||||
requireNonNull( entry );
|
||||
return this.key().toString().compareTo( entry.key().toString() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "{" +
|
||||
"\"k\":" + k +
|
||||
", \"v\":" + v +
|
||||
'}';
|
||||
}
|
||||
|
||||
public void setFirst(K first) {
|
||||
this.k = first;
|
||||
}
|
||||
|
||||
public void setSecond(V v) {
|
||||
this.v = v;
|
||||
}
|
||||
}
|
|
@ -1,600 +0,0 @@
|
|||
/*
|
||||
* Copyright 2013-2014 Richard M. Hightower
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* __________ _____ __ .__
|
||||
* \______ \ ____ ____ ____ /\ / \ _____ | | _|__| ____ ____
|
||||
* | | _// _ \ / _ \ / \ \/ / \ / \\__ \ | |/ / |/ \ / ___\
|
||||
* | | ( <_> | <_> ) | \ /\ / Y \/ __ \| <| | | \/ /_/ >
|
||||
* |______ /\____/ \____/|___| / \/ \____|__ (____ /__|_ \__|___| /\___ /
|
||||
* \/ \/ \/ \/ \/ \//_____/
|
||||
* ____. ___________ _____ ______________.___.
|
||||
* | |____ ___ _______ \_ _____/ / _ \ / _____/\__ | |
|
||||
* | \__ \\ \/ /\__ \ | __)_ / /_\ \ \_____ \ / | |
|
||||
* /\__| |/ __ \\ / / __ \_ | \/ | \/ \ \____ |
|
||||
* \________(____ /\_/ (____ / /_______ /\____|__ /_______ / / ______|
|
||||
* \/ \/ \/ \/ \/ \/
|
||||
*/
|
||||
|
||||
package org.boon;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.PrintWriter;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Scanner;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import static org.boon.Boon.puts;
|
||||
import static org.boon.Boon.sputs;
|
||||
|
||||
/**
|
||||
* Ported this form EasyJava/Facile. Got rid of the FileObject stuff.
|
||||
*
|
||||
* @author Rick Hightower
|
||||
*/
|
||||
public class Runner {
|
||||
|
||||
|
||||
private final static String shell;
|
||||
private final static String shellArgument;
|
||||
|
||||
static {
|
||||
// Windows
|
||||
if ( System.getProperty( "os.name" ).toLowerCase().indexOf( "win" ) >= 0 ) {
|
||||
shell = "cmd.exe";
|
||||
shellArgument = "/C";
|
||||
}
|
||||
|
||||
// Everyone else
|
||||
else {
|
||||
shell = "/bin/sh";
|
||||
shellArgument = "-c";
|
||||
}
|
||||
}
|
||||
|
||||
public static List<Path> path() {
|
||||
|
||||
final String[] paths = StringScanner.splitByDelimiters( System.getenv().get( "PATH" ), ":;" );
|
||||
return Lists.mapBy( paths, IO.convertToPathFunction );
|
||||
|
||||
}
|
||||
|
||||
public static int exec( String... args ) {
|
||||
ProcessRunner runner = new ProcessRunner( null, null, 0, null, false, args );
|
||||
return runner.exec();
|
||||
}
|
||||
|
||||
public static int exec( int timeout, String... args ) {
|
||||
ProcessRunner runner = new ProcessRunner( null, null, timeout, null, false, args );
|
||||
return runner.exec();
|
||||
}
|
||||
|
||||
|
||||
public static String run( int timeout, String... args ) {
|
||||
|
||||
return run( timeout, null, args );
|
||||
}
|
||||
|
||||
|
||||
public static String runAt( String cwd, int timeout, String... args ) {
|
||||
|
||||
return runAt( cwd, timeout, null, args );
|
||||
}
|
||||
|
||||
|
||||
public static String run( int timeout, List<Path> path, String... args ) {
|
||||
return doRun( timeout, path, false, args );
|
||||
}
|
||||
|
||||
|
||||
public static String runAt( String cwd, int timeout, List<Path> path, String... args ) {
|
||||
return doRunAt( cwd, timeout, path, false, args );
|
||||
}
|
||||
|
||||
public static ProcessOut runProcess( int timeout, List<Path> path, boolean verbose, String... args ) {
|
||||
return runProcessAt( null, timeout, path, verbose, args );
|
||||
}
|
||||
|
||||
public static ProcessOut runProcessAt( String cwd, int timeout, List<Path> path, boolean verbose, String... args ) {
|
||||
|
||||
|
||||
ProcessOut out = new ProcessOut();
|
||||
ProcessRunner runner = new ProcessRunner( null, null, timeout, path, verbose, args );
|
||||
runner.cwd = cwd;
|
||||
out.exit = runner.exec();
|
||||
out.stdout = runner.stdOut();
|
||||
out.stderr = runner.stdErr();
|
||||
out.commandLine = Str.joinCollection( ' ', runner.commandLine );
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
private static String doRun( int timeout, List<Path> path, boolean verbose, String... args ) {
|
||||
|
||||
|
||||
ProcessOut out = runProcess( timeout, path, verbose, args );
|
||||
if ( out.getExit() != 0 ) {
|
||||
throw new ProcessException( sputs( "EXIT CODE", out.getExit(), out.getStderr() ) );
|
||||
} else {
|
||||
return out.getStdout();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
private static String doRunAt( String cwd, int timeout, List<Path> path, boolean verbose, String... args ) {
|
||||
|
||||
|
||||
ProcessOut out = runProcessAt( cwd, timeout, path, verbose, args );
|
||||
if ( out.getExit() != 0 ) {
|
||||
throw new ProcessException( sputs( "EXIT CODE", out.getExit(), out.getStderr() ) );
|
||||
} else {
|
||||
return out.getStdout();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static ProcessInOut launchProcess( int timeout, List<Path> path, boolean verbose, String... args ) {
|
||||
|
||||
ProcessInOut process = new ProcessInOut();
|
||||
process.run( timeout, path, verbose, args );
|
||||
|
||||
return process;
|
||||
|
||||
}
|
||||
|
||||
public static String run( String... args ) {
|
||||
return run( 0, args );
|
||||
}
|
||||
|
||||
|
||||
public static String runAt( String cwd, String... args ) {
|
||||
return runAt( cwd, 0, args );
|
||||
}
|
||||
|
||||
|
||||
public static String runShell( String... args ) {
|
||||
|
||||
List<String> list = new ArrayList<>( args.length + 2 );
|
||||
list.add( shell );
|
||||
list.add( shellArgument );
|
||||
for ( String arg : args ) {
|
||||
list.add( arg );
|
||||
|
||||
}
|
||||
return run( 0, list.toArray( new String[ list.size() ] ) );
|
||||
}
|
||||
|
||||
public static String runShell( int timeout, String... args ) {
|
||||
|
||||
List<String> list = new ArrayList<>( args.length + 2 );
|
||||
list.add( shell );
|
||||
list.add( shellArgument );
|
||||
for ( String arg : args ) {
|
||||
list.add( arg );
|
||||
|
||||
}
|
||||
return run( timeout, list.toArray( new String[ list.size() ] ) );
|
||||
}
|
||||
|
||||
|
||||
public static int execShell( String... args ) {
|
||||
|
||||
List<String> list = new ArrayList<>( args.length + 2 );
|
||||
list.add( shell );
|
||||
list.add( shellArgument );
|
||||
for ( String arg : args ) {
|
||||
list.add( arg );
|
||||
|
||||
}
|
||||
return exec( 0, list.toArray( new String[ list.size() ] ) );
|
||||
}
|
||||
|
||||
|
||||
public static int execShell( int timeout, String... args ) {
|
||||
|
||||
List<String> list = new ArrayList<>( args.length + 2 );
|
||||
list.add( shell );
|
||||
list.add( shellArgument );
|
||||
for ( String arg : args ) {
|
||||
list.add( arg );
|
||||
|
||||
}
|
||||
return exec( timeout, list.toArray( new String[ list.size() ] ) );
|
||||
}
|
||||
|
||||
|
||||
public static class ProcessInOut {
|
||||
|
||||
private ProcessRunner runner;
|
||||
private ProcessOut out;
|
||||
|
||||
private AtomicBoolean done = new AtomicBoolean( false );
|
||||
|
||||
private BlockingQueue<String> queueOut;
|
||||
private BlockingQueue<String> queueErr;
|
||||
|
||||
|
||||
private ExecutorService executorService;
|
||||
|
||||
|
||||
public ProcessInOut() {
|
||||
this.queueOut = new ArrayBlockingQueue<>( 100 );
|
||||
this.queueErr = new ArrayBlockingQueue<>( 100 );
|
||||
}
|
||||
|
||||
public void run( final int timeout, final List<Path> path, final boolean verbose, final String... args ) {
|
||||
done.set( false );
|
||||
out = new ProcessOut();
|
||||
runner = new ProcessRunner( ProcessInOut.this, null, timeout, path, verbose, args );
|
||||
|
||||
executorService = Executors.newSingleThreadExecutor();
|
||||
|
||||
Runnable task = new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
out.exit = runner.exec();
|
||||
out.stdout = runner.stdOut();
|
||||
out.stderr = runner.stdErr();
|
||||
out.commandLine = Str.joinCollection( ' ', runner.commandLine );
|
||||
done.set( true );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
executorService.submit( task );
|
||||
|
||||
}
|
||||
|
||||
public boolean isDone() {
|
||||
return done.get();
|
||||
}
|
||||
|
||||
public ProcessOut processOut() {
|
||||
return out;
|
||||
}
|
||||
|
||||
public BlockingQueue<String> getStdOut() {
|
||||
return queueOut;
|
||||
}
|
||||
|
||||
public BlockingQueue<String> getStdErr() {
|
||||
return queueErr;
|
||||
}
|
||||
|
||||
|
||||
public void kill() {
|
||||
runner.process.destroy();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static class ProcessOut {
|
||||
private int exit;
|
||||
private String stdout;
|
||||
private String stderr;
|
||||
private String commandLine;
|
||||
|
||||
public int getExit() {
|
||||
return exit;
|
||||
}
|
||||
|
||||
|
||||
public String getStdout() {
|
||||
return stdout;
|
||||
}
|
||||
|
||||
|
||||
public String getStderr() {
|
||||
return stderr;
|
||||
}
|
||||
|
||||
public String getCommandLine() {
|
||||
return commandLine;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ProcessOut [\nexit=" + exit + ", \nstdout=" + stdout
|
||||
+ ", \nstderr=" + stderr + ", \ncommandLine=" + commandLine
|
||||
+ "\n]";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void handle( Exception ex ) {
|
||||
throw new ProcessException( ex );
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings ( "serial" )
|
||||
public static class ProcessException extends RuntimeException {
|
||||
|
||||
public ProcessException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public ProcessException( String m, Throwable t ) {
|
||||
super( m, t );
|
||||
}
|
||||
|
||||
public ProcessException( String m ) {
|
||||
super( m );
|
||||
}
|
||||
|
||||
public ProcessException( Throwable t ) {
|
||||
super( t );
|
||||
}
|
||||
}
|
||||
|
||||
public static class ProcessRunner {
|
||||
private List<String> commandLine;
|
||||
private String password;
|
||||
private List<Path> path;
|
||||
|
||||
private ProcessIODrainer fromProcessOutput;
|
||||
private ProcessIODrainer fromProcessError;
|
||||
private int timeoutInSeconds = 0;
|
||||
private boolean verbose;
|
||||
|
||||
private PrintWriter toProcess;
|
||||
|
||||
|
||||
private ProcessInOut inout;
|
||||
private Process process;
|
||||
|
||||
|
||||
private ExecutorService executorService;
|
||||
|
||||
private ScheduledExecutorService scheduledExecutorService;
|
||||
|
||||
private String cwd;
|
||||
|
||||
public ProcessRunner( ProcessInOut inout, String password, int timeoutInSeconds,
|
||||
List<Path> path, boolean verbose, String... cmdLine ) {
|
||||
|
||||
|
||||
if ( timeoutInSeconds == 0 ) {
|
||||
timeoutInSeconds = 5;
|
||||
}
|
||||
if ( cmdLine.length == 1 ) {
|
||||
cmdLine = Str.split( cmdLine[ 0 ] );
|
||||
}
|
||||
|
||||
|
||||
this.inout = inout;
|
||||
this.commandLine = Lists.list( cmdLine );
|
||||
this.password = password;
|
||||
this.timeoutInSeconds = timeoutInSeconds;
|
||||
this.path = path;
|
||||
this.verbose = verbose;
|
||||
|
||||
|
||||
if ( this.path == null ) {
|
||||
this.path = Runner.path();
|
||||
}
|
||||
|
||||
executorService = Executors.newFixedThreadPool( 2 );
|
||||
|
||||
}
|
||||
|
||||
public int exec() throws ProcessException {
|
||||
int exit = -666;
|
||||
|
||||
initializePath();
|
||||
|
||||
|
||||
ProcessBuilder processBuilder = new ProcessBuilder( commandLine );
|
||||
|
||||
if ( cwd != null ) {
|
||||
processBuilder.directory( new File( cwd ) );
|
||||
}
|
||||
|
||||
String envPath = Str.joinCollection( File.pathSeparatorChar, path );
|
||||
processBuilder.environment().put( "PATH", envPath );
|
||||
|
||||
|
||||
try {
|
||||
initializeDrainersScannersAndWriters( processBuilder );
|
||||
|
||||
|
||||
final Future<?> fromProcessErrorFuture = executorService.submit( fromProcessError );
|
||||
final Future<?> fromProcessOutputFuture = executorService.submit( fromProcessOutput );
|
||||
|
||||
|
||||
if ( timeoutInSeconds == -1 ) {
|
||||
exit = process.waitFor();
|
||||
|
||||
} else {
|
||||
|
||||
exit = runWithTimeoutTimer( fromProcessErrorFuture, fromProcessOutputFuture );
|
||||
|
||||
}
|
||||
|
||||
|
||||
fromProcessErrorFuture.get();
|
||||
fromProcessOutputFuture.get();
|
||||
|
||||
|
||||
} catch ( Exception e ) {
|
||||
Thread.interrupted();
|
||||
handle( e );
|
||||
}
|
||||
return exit;
|
||||
}
|
||||
|
||||
private void initializePath() {
|
||||
String cmd = commandLine.get( 0 );
|
||||
Path pathCommand = IO.path( cmd );
|
||||
if ( !Files.exists( pathCommand ) ) {
|
||||
for ( Path dir : path ) {
|
||||
pathCommand = IO.path( dir, cmd );
|
||||
if ( Files.exists( pathCommand ) ) {
|
||||
cmd = pathCommand.toAbsolutePath().toString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
commandLine.set( 0, cmd );
|
||||
|
||||
}
|
||||
|
||||
private void initializeDrainersScannersAndWriters( ProcessBuilder processBuilder ) throws IOException {
|
||||
process = processBuilder.start();
|
||||
|
||||
toProcess = new PrintWriter( new OutputStreamWriter( process.getOutputStream() ) );
|
||||
|
||||
Scanner stdOut = new Scanner( process.getInputStream() );
|
||||
Scanner stdErr = new Scanner( process.getErrorStream() );
|
||||
|
||||
if ( inout == null ) {
|
||||
fromProcessError = new ProcessIODrainer( stdErr, verbose );
|
||||
fromProcessOutput = new ProcessIODrainer( stdOut, toProcess,
|
||||
password, false, verbose );
|
||||
} else {
|
||||
fromProcessError = new ProcessIODrainer( inout.queueErr, stdErr, verbose );
|
||||
fromProcessOutput = new ProcessIODrainer( inout.queueOut, stdOut, toProcess,
|
||||
password, false, verbose );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private int runWithTimeoutTimer( final Future<?> fromProcessErrorFuture, final Future<?> fromProcessOutputFuture ) throws InterruptedException {
|
||||
Runnable command = new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
process.destroy();
|
||||
fromProcessErrorFuture.cancel( true );
|
||||
fromProcessOutputFuture.cancel( true );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
|
||||
final ScheduledFuture<?> scheduledFuture = scheduledExecutorService.scheduleWithFixedDelay( command, timeoutInSeconds, timeoutInSeconds, TimeUnit.SECONDS );
|
||||
int exit = process.waitFor();
|
||||
scheduledFuture.cancel( true );
|
||||
return exit;
|
||||
}
|
||||
|
||||
public String stdOut() {
|
||||
return fromProcessOutput.getOutput();
|
||||
}
|
||||
|
||||
public String stdErr() {
|
||||
return fromProcessError.getOutput();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class ProcessIODrainer implements Runnable {
|
||||
private Scanner fromProcess;
|
||||
private String password;
|
||||
private PrintWriter toProcess;
|
||||
private StringBuilder outputBuffer = new StringBuilder( 1024 );
|
||||
private boolean sudo;
|
||||
private boolean verbose;
|
||||
private BlockingQueue<String> queue;
|
||||
|
||||
ProcessIODrainer( Scanner fromProcess, boolean verbose ) {
|
||||
this.fromProcess = fromProcess;
|
||||
this.verbose = verbose;
|
||||
}
|
||||
|
||||
ProcessIODrainer( BlockingQueue<String> queueOut, Scanner fromProcess, boolean verbose ) {
|
||||
this.queue = queueOut;
|
||||
this.fromProcess = fromProcess;
|
||||
this.verbose = verbose;
|
||||
}
|
||||
|
||||
ProcessIODrainer( Scanner fromProcess,
|
||||
PrintWriter toProcess, String password, boolean sudo, boolean verbose ) {
|
||||
this.sudo = sudo;
|
||||
this.fromProcess = fromProcess;
|
||||
this.toProcess = toProcess;
|
||||
this.verbose = verbose;
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public ProcessIODrainer( BlockingQueue<String> queueOut, Scanner fromProcess,
|
||||
PrintWriter toProcess, String password, boolean sudo, boolean verbose ) {
|
||||
this.queue = queueOut;
|
||||
this.sudo = sudo;
|
||||
this.fromProcess = fromProcess;
|
||||
this.toProcess = toProcess;
|
||||
this.verbose = verbose;
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
if ( sudo ) {
|
||||
try {
|
||||
Thread.sleep( 100 );
|
||||
} catch ( InterruptedException e ) {
|
||||
Thread.interrupted();
|
||||
}
|
||||
toProcess.println( password );
|
||||
toProcess.flush();
|
||||
}
|
||||
|
||||
try {
|
||||
while ( fromProcess.hasNextLine() ) {
|
||||
String line = fromProcess.nextLine();
|
||||
|
||||
if ( queue != null ) {
|
||||
while ( true ) {
|
||||
try {
|
||||
queue.put( line );
|
||||
break;
|
||||
} catch ( InterruptedException e ) {
|
||||
if ( Thread.currentThread().isInterrupted() ) {
|
||||
break;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( verbose ) {
|
||||
puts( line );
|
||||
}
|
||||
outputBuffer.append( line ).append( '\n' );
|
||||
}
|
||||
|
||||
} finally {
|
||||
fromProcess.close();
|
||||
}
|
||||
}
|
||||
|
||||
public String getOutput() {
|
||||
return outputBuffer.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -1,451 +0,0 @@
|
|||
/*
|
||||
* Copyright 2013-2014 Richard M. Hightower
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* __________ _____ __ .__
|
||||
* \______ \ ____ ____ ____ /\ / \ _____ | | _|__| ____ ____
|
||||
* | | _// _ \ / _ \ / \ \/ / \ / \\__ \ | |/ / |/ \ / ___\
|
||||
* | | ( <_> | <_> ) | \ /\ / Y \/ __ \| <| | | \/ /_/ >
|
||||
* |______ /\____/ \____/|___| / \/ \____|__ (____ /__|_ \__|___| /\___ /
|
||||
* \/ \/ \/ \/ \/ \//_____/
|
||||
* ____. ___________ _____ ______________.___.
|
||||
* | |____ ___ _______ \_ _____/ / _ \ / _____/\__ | |
|
||||
* | \__ \\ \/ /\__ \ | __)_ / /_\ \ \_____ \ / | |
|
||||
* /\__| |/ __ \\ / / __ \_ | \/ | \/ \ \____ |
|
||||
* \________(____ /\_/ (____ / /_______ /\____|__ /_______ / / ______|
|
||||
* \/ \/ \/ \/ \/ \/
|
||||
*/
|
||||
|
||||
package org.boon;
|
||||
|
||||
|
||||
import org.boon.core.reflection.BeanUtils;
|
||||
import org.boon.core.reflection.MapObjectConversion;
|
||||
import org.boon.primitive.CharBuf;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentSkipListSet;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
|
||||
public class Sets {
|
||||
|
||||
/* Creation */
|
||||
public static <V> Set<V> set( Collection<V> collection ) {
|
||||
if (collection instanceof Set) {
|
||||
return (Set <V>) collection;
|
||||
}
|
||||
if (collection==null) {
|
||||
return Collections.EMPTY_SET;
|
||||
}
|
||||
return new LinkedHashSet<>( collection );
|
||||
}
|
||||
|
||||
|
||||
public static <V> Enumeration<V> enumeration( final Set<V> set ) {
|
||||
final Iterator<V> iter = set.iterator();
|
||||
return new Enumeration<V>() {
|
||||
@Override
|
||||
public boolean hasMoreElements() {
|
||||
return iter.hasNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public V nextElement() {
|
||||
return iter.next();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static <V> Set<V> set( Class<V> clazz ) {
|
||||
return new LinkedHashSet<>();
|
||||
}
|
||||
|
||||
public static <V> Set<V> set( Iterable<V> iterable ) {
|
||||
Set<V> set = new LinkedHashSet<>();
|
||||
for ( V o : iterable ) {
|
||||
set.add( o );
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
public static <V> Set<V> set( Enumeration<V> enumeration ) {
|
||||
Set<V> set = new LinkedHashSet<>();
|
||||
while ( enumeration.hasMoreElements() ) {
|
||||
set.add( enumeration.nextElement() );
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
|
||||
public static <V> Set<V> set( Iterator<V> iterator ) {
|
||||
Set<V> set = new LinkedHashSet<>();
|
||||
while ( iterator.hasNext() ) {
|
||||
set.add( iterator.next() );
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
|
||||
@SafeVarargs
|
||||
public static <V> Set<V> set( final V... array ) {
|
||||
|
||||
|
||||
Set<V> set = new LinkedHashSet<>();
|
||||
|
||||
for ( V v : array ) {
|
||||
set.add( v );
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
public static <V> Set<V> set( int size, final V... array ) {
|
||||
|
||||
int index=0;
|
||||
Set<V> set = new LinkedHashSet<>();
|
||||
|
||||
for ( V v : array ) {
|
||||
set.add( v );
|
||||
index++;
|
||||
if (index == size) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
|
||||
public static <V> NavigableSet<V> sortedSet( Iterator<V> iterator ) {
|
||||
NavigableSet<V> set = new TreeSet<>();
|
||||
while ( iterator.hasNext() ) {
|
||||
set.add( iterator.next() );
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
public static <V> NavigableSet<V> sortedSet( Class<V> clazz ) {
|
||||
return new TreeSet<>();
|
||||
}
|
||||
|
||||
public static <V> NavigableSet<V> sortedSet( Iterable<V> iterable ) {
|
||||
NavigableSet<V> set = new TreeSet<>();
|
||||
for ( V o : iterable ) {
|
||||
set.add( o );
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
public static <V> NavigableSet<V> sortedSet( Enumeration<V> enumeration ) {
|
||||
NavigableSet<V> set = new TreeSet<>();
|
||||
while ( enumeration.hasMoreElements() ) {
|
||||
set.add( enumeration.nextElement() );
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
public static <V> NavigableSet<V> sortedSet( final V... array ) {
|
||||
NavigableSet<V> set = new TreeSet<>();
|
||||
|
||||
for ( V v : array ) {
|
||||
set.add( v );
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
public static <V> NavigableSet<V> sortedSet( Collection<V> collection ) {
|
||||
return new TreeSet<>( collection );
|
||||
}
|
||||
|
||||
|
||||
public static <V> NavigableSet<V> safeSortedSet( Iterator<V> iterator ) {
|
||||
NavigableSet<V> set = new ConcurrentSkipListSet<>();
|
||||
while ( iterator.hasNext() ) {
|
||||
set.add( iterator.next() );
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
public static <V> NavigableSet<V> safeSortedSet( Class<V> clazz ) {
|
||||
return new ConcurrentSkipListSet<>();
|
||||
}
|
||||
|
||||
public static <V> NavigableSet<V> safeSortedSet( Iterable<V> iterable ) {
|
||||
NavigableSet<V> set = new ConcurrentSkipListSet<>();
|
||||
for ( V o : iterable ) {
|
||||
set.add( o );
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
public static <V> NavigableSet<V> safeSortedSet( Enumeration<V> enumeration ) {
|
||||
NavigableSet<V> set = new ConcurrentSkipListSet<>();
|
||||
while ( enumeration.hasMoreElements() ) {
|
||||
set.add( enumeration.nextElement() );
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
public static <V> NavigableSet<V> safeSortedSet( final V... array ) {
|
||||
|
||||
NavigableSet<V> set = new ConcurrentSkipListSet<>();
|
||||
|
||||
for ( V v : array ) {
|
||||
set.add( v );
|
||||
}
|
||||
return set;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static <V> NavigableSet<V> safeSortedSet( Collection<V> collection ) {
|
||||
return new ConcurrentSkipListSet<>( collection );
|
||||
}
|
||||
|
||||
public static <V> Set<V> safeSet( Class<V> clazz ) {
|
||||
return new CopyOnWriteArraySet<>();
|
||||
}
|
||||
|
||||
public static <V> Set<V> safeSet( Iterable<V> iterable ) {
|
||||
Set<V> set = new CopyOnWriteArraySet<>();
|
||||
for ( V o : iterable ) {
|
||||
set.add( o );
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
public static <V> Set<V> safeSet( Enumeration<V> enumeration ) {
|
||||
Set<V> set = new CopyOnWriteArraySet<>();
|
||||
while ( enumeration.hasMoreElements() ) {
|
||||
set.add( enumeration.nextElement() );
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
|
||||
public static <V> Set<V> safeSet( Iterator<V> iterator ) {
|
||||
Set<V> set = new CopyOnWriteArraySet<>();
|
||||
while ( iterator.hasNext() ) {
|
||||
set.add( iterator.next() );
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
|
||||
@SafeVarargs
|
||||
public static <V> Set<V> safeSet( final V... array ) {
|
||||
|
||||
List<V> list = Lists.list( array );
|
||||
Set<V> set = new CopyOnWriteArraySet<>( list );
|
||||
|
||||
return set;
|
||||
}
|
||||
|
||||
public static <V> Set<V> safeSet( Collection<V> collection ) {
|
||||
return new CopyOnWriteArraySet<>( collection );
|
||||
}
|
||||
|
||||
|
||||
@Universal
|
||||
public static int len( Set<?> set ) {
|
||||
return set.size();
|
||||
}
|
||||
|
||||
@Universal
|
||||
public static <V> boolean in( V value, Set<?> set ) {
|
||||
return set.contains( value );
|
||||
}
|
||||
|
||||
@Universal
|
||||
public static <V> void add( Set<V> set, V value ) {
|
||||
set.add( value );
|
||||
}
|
||||
|
||||
@Universal
|
||||
public static <T> T idx( NavigableSet<T> set, final T index ) {
|
||||
|
||||
return set.higher( index );
|
||||
}
|
||||
|
||||
@Universal
|
||||
public static <T> T idx( Set<T> set, final T index ) {
|
||||
|
||||
if ( set instanceof NavigableSet ) {
|
||||
return idx( ( NavigableSet<T> ) set, index );
|
||||
} else {
|
||||
throw new IllegalArgumentException( "Set must be a NavigableSet for idx operation to work" );
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> T after( NavigableSet<T> set, final T index ) {
|
||||
|
||||
return set.higher( index );
|
||||
}
|
||||
|
||||
public static <T> T before( NavigableSet<T> set, final T index ) {
|
||||
|
||||
return set.lower( index );
|
||||
}
|
||||
|
||||
@Universal
|
||||
public static <V> SortedSet<V> slc( NavigableSet<V> set, V startIndex, V endIndex ) {
|
||||
return set.subSet( startIndex, endIndex );
|
||||
}
|
||||
|
||||
|
||||
@Universal
|
||||
public static <V> SortedSet<V> slcEnd( NavigableSet<V> set, V fromIndex ) {
|
||||
return set.tailSet( fromIndex );
|
||||
}
|
||||
|
||||
|
||||
@Universal
|
||||
public static <V> SortedSet<V> slc( NavigableSet<V> set, V toIndex ) {
|
||||
return set.headSet( toIndex );
|
||||
}
|
||||
|
||||
@Universal
|
||||
public static <V> Set<V> copy( HashSet<V> collection ) {
|
||||
return new LinkedHashSet<>( collection );
|
||||
}
|
||||
|
||||
@Universal
|
||||
public static <V> NavigableSet<V> copy( TreeSet<V> collection ) {
|
||||
return new TreeSet<>( collection );
|
||||
}
|
||||
|
||||
@Universal
|
||||
public static <V> Set<V> copy( CopyOnWriteArraySet<V> collection ) {
|
||||
return new CopyOnWriteArraySet<>( collection );
|
||||
}
|
||||
|
||||
@Universal
|
||||
public static <V> NavigableSet<V> copy( ConcurrentSkipListSet<V> collection ) {
|
||||
return new ConcurrentSkipListSet<>( collection );
|
||||
}
|
||||
|
||||
|
||||
@Universal
|
||||
public static <V> NavigableSet<V> copy( NavigableSet<V> collection ) {
|
||||
if ( collection instanceof ConcurrentSkipListSet ) {
|
||||
return copy( ( ConcurrentSkipListSet<V> ) collection );
|
||||
} else {
|
||||
return copy( ( TreeSet<V> ) collection );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Universal
|
||||
public static <V> Set<V> copy( Set<V> collection ) {
|
||||
if ( collection instanceof NavigableSet ) {
|
||||
|
||||
return copy( ( NavigableSet<V> ) collection );
|
||||
|
||||
|
||||
} else if ( collection instanceof CopyOnWriteArraySet ) {
|
||||
|
||||
return copy( ( CopyOnWriteArraySet<V> ) collection );
|
||||
|
||||
} else {
|
||||
|
||||
return copy( ( LinkedHashSet<V> ) collection );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static <V> Set<V> deepCopy( Collection<V> collection ) {
|
||||
Set<V> newSet = new LinkedHashSet<>(collection.size());
|
||||
|
||||
for (V v : collection) {
|
||||
newSet.add(BeanUtils.copy(v));
|
||||
}
|
||||
return newSet;
|
||||
}
|
||||
|
||||
public static <V> Set<V> deepCopyToSet( Collection<V> src, Set<V> dst) {
|
||||
|
||||
for (V v : src) {
|
||||
dst.add( BeanUtils.copy( v ));
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
|
||||
public static <V,T> List<T> deepCopy( Collection<V> src, Class<T> dest ) {
|
||||
List<T> list = new ArrayList<>(src.size());
|
||||
|
||||
for (V v : src) {
|
||||
list.add( BeanUtils.createFromSrc( v, dest ));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Universal
|
||||
public static <V> Set<V> deepCopy( Set<V> set ) {
|
||||
if ( set instanceof LinkedHashSet ) {
|
||||
return deepCopyToSet(set, new LinkedHashSet<V>());
|
||||
} else if ( set instanceof CopyOnWriteArraySet ) {
|
||||
return deepCopyToSet(set, new CopyOnWriteArraySet<V>());
|
||||
} else if ( set instanceof HashSet ) {
|
||||
return deepCopyToSet(set, new HashSet<V>());
|
||||
} else {
|
||||
return deepCopy( (Collection)set);
|
||||
}
|
||||
}
|
||||
|
||||
//end universal
|
||||
|
||||
public static List<Map<String, Object>> toListOfMaps( Set<?> set ) {
|
||||
return MapObjectConversion.toListOfMaps( set );
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static <T> Set<T> setFromProperty( Class<T> propertyType, String propertyPath, Collection<?> list ) {
|
||||
Set<T> newSet = new LinkedHashSet<>( list.size() );
|
||||
|
||||
for ( Object item : list ) {
|
||||
T newItem = ( T ) BeanUtils.idx( item, propertyPath );
|
||||
newSet.add(newItem);
|
||||
}
|
||||
|
||||
return newSet;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static <T> Set<T> setFromProperty( Class<T> propertyType, String propertyPath, Iterable<?> list ) {
|
||||
Set<T> newSet = new LinkedHashSet<>( );
|
||||
|
||||
for ( Object item : list ) {
|
||||
T newItem = ( T ) BeanUtils.idx( item, propertyPath );
|
||||
newSet.add(newItem);
|
||||
}
|
||||
|
||||
return newSet;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static String toPrettyJson(Set set) {
|
||||
CharBuf buf = CharBuf.createCharBuf();
|
||||
return buf.prettyPrintCollection(set, false, 0).toString();
|
||||
}
|
||||
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -1,316 +0,0 @@
|
|||
/*
|
||||
* Copyright 2013-2014 Richard M. Hightower
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* __________ _____ __ .__
|
||||
* \______ \ ____ ____ ____ /\ / \ _____ | | _|__| ____ ____
|
||||
* | | _// _ \ / _ \ / \ \/ / \ / \\__ \ | |/ / |/ \ / ___\
|
||||
* | | ( <_> | <_> ) | \ /\ / Y \/ __ \| <| | | \/ /_/ >
|
||||
* |______ /\____/ \____/|___| / \/ \____|__ (____ /__|_ \__|___| /\___ /
|
||||
* \/ \/ \/ \/ \/ \//_____/
|
||||
* ____. ___________ _____ ______________.___.
|
||||
* | |____ ___ _______ \_ _____/ / _ \ / _____/\__ | |
|
||||
* | \__ \\ \/ /\__ \ | __)_ / /_\ \ \_____ \ / | |
|
||||
* /\__| |/ __ \\ / / __ \_ | \/ | \/ \ \____ |
|
||||
* \________(____ /\_/ (____ / /_______ /\____|__ /_______ / / ______|
|
||||
* \/ \/ \/ \/ \/ \/
|
||||
*/
|
||||
|
||||
package org.boon;
|
||||
|
||||
import org.boon.core.reflection.FastStringUtils;
|
||||
import org.boon.primitive.CharScanner;
|
||||
import org.boon.primitive.Chr;
|
||||
|
||||
|
||||
public class StringScanner {
|
||||
|
||||
|
||||
private static final char[] WHITE_SPACE = new char[] {'\n', '\t', ' ', '\r'};
|
||||
|
||||
/**
|
||||
* Checks the input string to see if it is only digits
|
||||
* @param input digits
|
||||
* @return true or false
|
||||
*/
|
||||
public static boolean isDigits( String input ) {
|
||||
return CharScanner.isDigits( FastStringUtils.toCharArray( input ) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Splits a string into many parts
|
||||
* @param string input string
|
||||
* @param split char to split by
|
||||
* @param limit the limit of the times you want it split up
|
||||
* @return the split string
|
||||
*/
|
||||
public static String[] split( final String string,
|
||||
final char split, final int limit ) {
|
||||
|
||||
|
||||
char[][] comps = CharScanner.split( FastStringUtils.toCharArray( string ), split, limit );
|
||||
|
||||
return Str.fromCharArrayOfArrayToStringArray( comps );
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Splits a string
|
||||
* @param string string to split
|
||||
* @param split what you want to split it by
|
||||
* @return the split up string
|
||||
*/
|
||||
public static String[] split( final String string,
|
||||
final char split ) {
|
||||
|
||||
char[][] comps = CharScanner.split( FastStringUtils.toCharArray( string ), split );
|
||||
|
||||
return Str.fromCharArrayOfArrayToStringArray( comps );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Split string by a list of delimiters
|
||||
* @param string string to split
|
||||
* @param delimiters delimeters to split it by
|
||||
* @return the split up string
|
||||
*/
|
||||
public static String[] splitByChars( final String string,
|
||||
final char... delimiters ) {
|
||||
|
||||
char[][] comps = CharScanner.splitByChars( FastStringUtils.toCharArray( string ), delimiters );
|
||||
|
||||
return Str.fromCharArrayOfArrayToStringArray( comps );
|
||||
|
||||
}
|
||||
|
||||
public static String[] splitByCharsFromToDelims( final String string, int from, int to,
|
||||
final char... delimiters ) {
|
||||
|
||||
char[][] comps = CharScanner.splitByCharsFromToDelims( FastStringUtils.toCharArray( string ), from, to, delimiters );
|
||||
|
||||
return Str.fromCharArrayOfArrayToStringArray( comps );
|
||||
|
||||
}
|
||||
|
||||
public static String[] splitByCharsFrom( final String string, int from,
|
||||
final char... delimiters ) {
|
||||
|
||||
char[][] comps = CharScanner.splitByCharsFromToDelims( FastStringUtils.toCharArray( string ), from, string.length(), delimiters );
|
||||
|
||||
return Str.fromCharArrayOfArrayToStringArray( comps );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Split string by white space
|
||||
* @param string string to split
|
||||
* @return the split up string
|
||||
*/
|
||||
public static String[] splitByWhiteSpace( final String string
|
||||
) {
|
||||
|
||||
char[][] comps = CharScanner.splitByChars( FastStringUtils.toCharArray( string ), WHITE_SPACE );
|
||||
|
||||
return Str.fromCharArrayOfArrayToStringArray( comps );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Split string by a list of delimiters
|
||||
* @param string string to split
|
||||
* @param delimiters delimeters to split it by
|
||||
* @return the split up string
|
||||
*/
|
||||
public static String[] splitByDelimiters( final String string,
|
||||
final String delimiters ) {
|
||||
|
||||
char[][] comps = CharScanner.splitByChars( FastStringUtils.toCharArray( string ), delimiters.toCharArray() );
|
||||
|
||||
return Str.fromCharArrayOfArrayToStringArray( comps );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Split string by a list of delimiters but none are empty
|
||||
* @param string string to split
|
||||
* @param delimiters delimeters to split it by
|
||||
* @return the split up string
|
||||
*/
|
||||
public static String[] splitByCharsNoneEmpty( final String string, final char... delimiters ) {
|
||||
|
||||
char[][] comps = CharScanner.splitByCharsNoneEmpty( FastStringUtils.toCharArray( string ), delimiters );
|
||||
return Str.fromCharArrayOfArrayToStringArray( comps );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* remove chars from a string
|
||||
* @param string string to split
|
||||
* @param delimiters delimeters to remove
|
||||
* @return the split up string
|
||||
*/
|
||||
public static String removeChars( final String string, final char... delimiters ) {
|
||||
char[][] comps = CharScanner.splitByCharsNoneEmpty( FastStringUtils.toCharArray( string ), delimiters );
|
||||
return new String(Chr.add ( comps ));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Split string by a list of delimiters but none are empty within a range
|
||||
* @param string string to split
|
||||
* @param delimiters delimeters to split it by
|
||||
* @return the split up string
|
||||
*/
|
||||
public static String[] splitByCharsNoneEmpty( final String string, int start, int end, final char... delimiters ) {
|
||||
Exceptions.requireNonNull( string );
|
||||
|
||||
char[][] comps = CharScanner.splitByCharsNoneEmpty( FastStringUtils.toCharArray( string ), start, end, delimiters );
|
||||
return Str.fromCharArrayOfArrayToStringArray( comps );
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse float
|
||||
* @param buffer input buffer
|
||||
* @param from from
|
||||
* @param to to
|
||||
* @return value
|
||||
*/
|
||||
public static float parseFloat( String buffer, int from, int to ) {
|
||||
return CharScanner.parseFloat( FastStringUtils.toCharArray(buffer), from , to );
|
||||
}
|
||||
|
||||
/**
|
||||
* parse a float
|
||||
* @param buffer input string
|
||||
* @return value
|
||||
*/
|
||||
public static float parseFloat( String buffer ) {
|
||||
return CharScanner.parseFloat( FastStringUtils.toCharArray(buffer) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* parse a double
|
||||
* @param buffer input string
|
||||
* @return value
|
||||
*/
|
||||
public static double parseDouble( String buffer, int from, int to ) {
|
||||
return CharScanner.parseDouble( FastStringUtils.toCharArray(buffer), from , to );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* parse a double
|
||||
* @param buffer input string
|
||||
* @return value
|
||||
*/
|
||||
public static double parseDouble( String buffer ) {
|
||||
return CharScanner.parseDouble( FastStringUtils.toCharArray(buffer) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* parse an int within a range
|
||||
* @param buffer input string
|
||||
* @return value
|
||||
*/
|
||||
public static int parseInt( String buffer, int from, int to ) {
|
||||
return CharScanner.parseInt( FastStringUtils.toCharArray(buffer), from , to );
|
||||
}
|
||||
|
||||
/**
|
||||
* parse an int within a range
|
||||
* @param buffer input string
|
||||
* @return value
|
||||
*/
|
||||
public static int parseInt( String buffer ) {
|
||||
return CharScanner.parseInt( FastStringUtils.toCharArray(buffer) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* parse an long within a range
|
||||
* @param buffer input string
|
||||
* @return value
|
||||
*/
|
||||
public static long parseLong( String buffer, int from, int to ) {
|
||||
return CharScanner.parseLong( FastStringUtils.toCharArray(buffer), from , to );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* parse an long within a range
|
||||
* @param buffer input string
|
||||
* @return value
|
||||
*/
|
||||
public static long parseLong( String buffer ) {
|
||||
return CharScanner.parseLong( FastStringUtils.toCharArray(buffer) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static short parseShort( String buffer, int from, int to ) {
|
||||
return (short) CharScanner.parseInt( FastStringUtils.toCharArray(buffer), from , to );
|
||||
}
|
||||
|
||||
public static short parseShort( String buffer ) {
|
||||
return (short) CharScanner.parseInt( FastStringUtils.toCharArray(buffer) );
|
||||
}
|
||||
|
||||
|
||||
public static short parseByte( String buffer, int from, int to ) {
|
||||
return (byte) CharScanner.parseInt( FastStringUtils.toCharArray(buffer), from , to );
|
||||
}
|
||||
|
||||
public static short parseByte( String buffer ) {
|
||||
return (byte) CharScanner.parseInt( FastStringUtils.toCharArray(buffer) );
|
||||
}
|
||||
|
||||
|
||||
public static int findWhiteSpace(String buffer) {
|
||||
return CharScanner.findWhiteSpace(FastStringUtils.toCharArray(buffer));
|
||||
}
|
||||
|
||||
public static String substringAfter(String string, String after) {
|
||||
|
||||
int index = StringScanner.findString(string, after);
|
||||
if (index==-1) {
|
||||
return "";
|
||||
} else {
|
||||
return Str.slc(string, index+after.length());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static int findString(String string, String after) {
|
||||
return CharScanner.findChars(FastStringUtils.toCharArray(after),
|
||||
FastStringUtils.toCharArray(string));
|
||||
}
|
||||
|
||||
public static String substringBefore(String string, String before) {
|
||||
|
||||
int index = StringScanner.findString(string, before);
|
||||
if (index==-1) {
|
||||
return "";
|
||||
} else {
|
||||
return Str.slcEnd(string, index);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,54 +0,0 @@
|
|||
package org.boon;
|
||||
|
||||
/**
|
||||
* Created by gcc on 1/15/15.
|
||||
*/
|
||||
public class Terminal {
|
||||
|
||||
public enum Escape {
|
||||
|
||||
RESET("\u001B[0m"),
|
||||
BOLD_ON("\u001B[1m"),
|
||||
ITALICS_ON("\u001B[3m"),
|
||||
UNDERLINE_ON("\u001B[4m"),
|
||||
INVERSE_ON("\u001B[7m"),
|
||||
STRIKETHROUGH_ON("\u001B[9m"),
|
||||
|
||||
BOLD_OFF("\u001B[22m"),
|
||||
ITALICS_OFF("\u001B[23m"),
|
||||
UNDERLINE_OFF("\u001B[24m"),
|
||||
INVERSE_OFF("\u001B[27m"),
|
||||
STRIKETHROUGH_OFF("\u001B[29m"),
|
||||
|
||||
FG_BLACK("\u001B[30m"),
|
||||
FG_RED("\u001B[31m"),
|
||||
FG_GREEN("\u001B[32m"),
|
||||
FG_YELLOW("\u001B[33m"),
|
||||
FG_BLUE("\u001B[34m"),
|
||||
FG_MAGENTA("\u001B[35m"),
|
||||
FG_CYAN("\u001B[36m"),
|
||||
FG_WHITE("\u001B[37m"),
|
||||
FG_DEFAULT("\u001B[39m"),
|
||||
|
||||
BG_BLACK("\u001B[40m"),
|
||||
BG_RED("\u001B[41m"),
|
||||
BG_GREEN("\u001B[42m"),
|
||||
BG_YELLOW("\u001B[43m"),
|
||||
BG_BLUE("\u001B[44m"),
|
||||
BG_MAGENTA("\u001B[45m"),
|
||||
BG_CYAN("\u001B[46m"),
|
||||
BG_WHITE("\u001B[47m"),
|
||||
BG_DEFAULT("\u001B[49m");
|
||||
|
||||
private final String value;
|
||||
|
||||
Escape(String s) {
|
||||
this.value = s;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
/*
|
||||
* Copyright 2013-2014 Richard M. Hightower
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* __________ _____ __ .__
|
||||
* \______ \ ____ ____ ____ /\ / \ _____ | | _|__| ____ ____
|
||||
* | | _// _ \ / _ \ / \ \/ / \ / \\__ \ | |/ / |/ \ / ___\
|
||||
* | | ( <_> | <_> ) | \ /\ / Y \/ __ \| <| | | \/ /_/ >
|
||||
* |______ /\____/ \____/|___| / \/ \____|__ (____ /__|_ \__|___| /\___ /
|
||||
* \/ \/ \/ \/ \/ \//_____/
|
||||
* ____. ___________ _____ ______________.___.
|
||||
* | |____ ___ _______ \_ _____/ / _ \ / _____/\__ | |
|
||||
* | \__ \\ \/ /\__ \ | __)_ / /_\ \ \_____ \ / | |
|
||||
* /\__| |/ __ \\ / / __ \_ | \/ | \/ \ \____ |
|
||||
* \________(____ /\_/ (____ / /_______ /\____|__ /_______ / / ______|
|
||||
* \/ \/ \/ \/ \/ \/
|
||||
*/
|
||||
|
||||
package org.boon;
|
||||
|
||||
/**
|
||||
* This is for documentation purposes.
|
||||
* It means a method is universal.
|
||||
*
|
||||
* @see UniversalOperations
|
||||
*/
|
||||
public @interface Universal {
|
||||
}
|
|
@ -1,567 +0,0 @@
|
|||
/*
|
||||
* Copyright 2013-2014 Richard M. Hightower
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* __________ _____ __ .__
|
||||
* \______ \ ____ ____ ____ /\ / \ _____ | | _|__| ____ ____
|
||||
* | | _// _ \ / _ \ / \ \/ / \ / \\__ \ | |/ / |/ \ / ___\
|
||||
* | | ( <_> | <_> ) | \ /\ / Y \/ __ \| <| | | \/ /_/ >
|
||||
* |______ /\____/ \____/|___| / \/ \____|__ (____ /__|_ \__|___| /\___ /
|
||||
* \/ \/ \/ \/ \/ \//_____/
|
||||
* ____. ___________ _____ ______________.___.
|
||||
* | |____ ___ _______ \_ _____/ / _ \ / _____/\__ | |
|
||||
* | \__ \\ \/ /\__ \ | __)_ / /_\ \ \_____ \ / | |
|
||||
* /\__| |/ __ \\ / / __ \_ | \/ | \/ \ \____ |
|
||||
* \________(____ /\_/ (____ / /_______ /\____|__ /_______ / / ______|
|
||||
* \/ \/ \/ \/ \/ \/
|
||||
*/
|
||||
|
||||
package org.boon;
|
||||
|
||||
|
||||
/**
|
||||
* This is more for documentation then actually using.
|
||||
* Nothing will likely implement this.
|
||||
* It is more conceptional.
|
||||
* <p/>
|
||||
* There are examples in the documentation.
|
||||
* <p/>
|
||||
* The following is a basis for many of the examples.
|
||||
* <p/>
|
||||
* <blockquote>
|
||||
* <pre>
|
||||
*
|
||||
*
|
||||
* //Works with lists, arrays, sets, maps, sorted maps, etc.
|
||||
* List<String> fruitList;
|
||||
* String [] fruitArray;
|
||||
* Set<String> veggiesSet;
|
||||
* char [] letters;
|
||||
* byte [] bytes;
|
||||
* NavigableMap <Integer, String> favoritesMap;
|
||||
* Map<String, Integer> map;
|
||||
*
|
||||
* // These helper methods are used to create common Java types.
|
||||
* // Sets and lists have concurrent and non concurrent variants
|
||||
* // Set also has sorted and non sorted variants
|
||||
* // This makes safeList, listStream, set, sortedSet, safeSet, safeSortedSet
|
||||
* veggiesSet = set( "salad", "broccoli", "spinach");
|
||||
* fruitList = listStream( "apple", "oranges", "pineapple");
|
||||
* fruitArray = array( "apple", "oranges", "pineapple");
|
||||
* letters = array( 'a', 'b', 'c');
|
||||
* bytes = array( new byte[]{0x1, 0x2, 0x3, 0x4});
|
||||
*
|
||||
* //You addObject up name / value pairs as a pseudo literal for map
|
||||
* favoritesMap = sortedMap(
|
||||
* 2, "pineapple",
|
||||
* 1, "oranges",
|
||||
* 3, "apple"
|
||||
* );
|
||||
*
|
||||
*
|
||||
* // You addObject up name / value pairs as a pseudo literal for map
|
||||
* // map, sortedMap, safeMap (thread safe concurrent), and sortedSafeMap are
|
||||
* // supported.
|
||||
* map = map (
|
||||
* "pineapple", 2,
|
||||
* "oranges", 1,
|
||||
* "apple", 3
|
||||
* );
|
||||
*
|
||||
*
|
||||
* </pre>
|
||||
* </blockquote>
|
||||
*/
|
||||
public interface UniversalOperations<ITEM, INDEX> {
|
||||
|
||||
public enum Returns {
|
||||
VARIES
|
||||
}
|
||||
|
||||
;
|
||||
|
||||
/**
|
||||
* Get the item at the index.
|
||||
* This works with Maps, TreeSets, Strings, Object arrays, primitive arrays,
|
||||
* etc.
|
||||
* <p/>
|
||||
* Implemented by:
|
||||
* <pre>
|
||||
* org.boon.primitive.Byt
|
||||
* org.boon.primitive.Chr
|
||||
* org.boon.primitive.Int (in progress)
|
||||
* org.boon.primitive.Lng (in progress)
|
||||
* org.boon.primitive.Arry
|
||||
* org.boon.core.Strings (planned)
|
||||
* org.boon.core.StrBuf (planned)
|
||||
* org.boon.Lists
|
||||
* org.boon.Maps
|
||||
* org.boon.Sets
|
||||
* </pre>
|
||||
* <p/>
|
||||
* Works with maps and sets
|
||||
* <p/>
|
||||
* <pre>
|
||||
* Map<String,Dog> dogMap; //map of dogs
|
||||
*
|
||||
* Dog dog = new Dog("dog");
|
||||
*
|
||||
* NavigableSet<String> set; //set of strings
|
||||
*
|
||||
* List<String> listStream;
|
||||
*
|
||||
* char[] letters;
|
||||
*
|
||||
*
|
||||
*
|
||||
* </pre>
|
||||
* Initialize our examples
|
||||
* <pre>
|
||||
* dogMap = map("dog", dog);
|
||||
* set = sortedSet("apple", "kiwi", "oranges", "pears", "pineapple");
|
||||
* listStream = listStream("apple", "oranges", "pears");
|
||||
* letters = array('a', 'b', 'c', 'd');
|
||||
*
|
||||
* </pre>
|
||||
* The methods map, listStream, sortedSet, arrays
|
||||
* are utility methods for creating Maps, lists sets, etc.
|
||||
* <br />
|
||||
* <p/>
|
||||
* Using
|
||||
* <pre>
|
||||
*
|
||||
* //Get the dog at the index "dog" in the map
|
||||
* assertEquals(
|
||||
*
|
||||
* dog, idx(dogMap, "dog")
|
||||
*
|
||||
* );
|
||||
*
|
||||
* //Get the string "oranges" at index "ora"
|
||||
* assertEquals(
|
||||
*
|
||||
* "oranges",
|
||||
* idx(set, "ora")
|
||||
*
|
||||
* );
|
||||
*
|
||||
* //Get the string "oranges" at index "o"
|
||||
* assertEquals(
|
||||
*
|
||||
* "oranges",
|
||||
* idx(set, "o")
|
||||
*
|
||||
* );
|
||||
*
|
||||
* //Get the string "oranges" at index 1 of the listStream.
|
||||
* assertEquals(
|
||||
* "oranges",
|
||||
* idx(listStream, 1)
|
||||
* );
|
||||
*
|
||||
* // Get the string "pears" at index -1 (using Python style slice notation)
|
||||
* // of the listStream.
|
||||
* assertEquals(
|
||||
* "pears",
|
||||
* idx(listStream, -1)
|
||||
* );
|
||||
*
|
||||
* //oranges are two from the back
|
||||
* assertEquals(
|
||||
* "oranges",
|
||||
* idx(listStream, -2));
|
||||
*
|
||||
*
|
||||
* //apple are two from the back
|
||||
* assertEquals(
|
||||
* "apple",
|
||||
* idx(listStream, -3));
|
||||
*
|
||||
*
|
||||
*
|
||||
* </pre>
|
||||
* <p/>
|
||||
* Based on the example at top {@link UniversalOperations}:
|
||||
* <blockquote>
|
||||
* <pre>
|
||||
*
|
||||
* //Using idx to access a value.
|
||||
*
|
||||
* assert idx( veggiesSet, "b").equals("broccoli");
|
||||
*
|
||||
* assert idx( fruitList, 1 ).equals("oranges");
|
||||
*
|
||||
* assert idx( fruitArray, 1 ).equals("oranges");
|
||||
*
|
||||
* assert idx( letters, 1 ) == 'b';
|
||||
*
|
||||
* assert idx( bytes, 1 ) == 0x2;
|
||||
*
|
||||
* assert idx( favoritesMap, 2 ).equals("pineapple");
|
||||
*
|
||||
* assert idx( map, "pineapple" ) == 2;
|
||||
*
|
||||
* </pre>
|
||||
* </blockquote>
|
||||
* <p/>
|
||||
* Negative index works with listStream like, array like things.
|
||||
* <p/>
|
||||
* <blockquote>
|
||||
* <pre>
|
||||
*
|
||||
* //Negative indexes
|
||||
*
|
||||
* assert idx( fruitList, -2 ).equals("oranges");
|
||||
*
|
||||
* assert idx( fruitArray, -2 ).equals("oranges");
|
||||
*
|
||||
* assert idx( letters, -2 ) == 'b';
|
||||
*
|
||||
* assert idx( bytes, -3 ) == 0x2;
|
||||
* </pre>
|
||||
* </blockquote>
|
||||
*
|
||||
* @param index the index of the item
|
||||
* @return the item at the index
|
||||
* @see org.boon.primitive.Byt
|
||||
* @see org.boon.primitive.Chr
|
||||
* @see org.boon.primitive.Int
|
||||
* @see org.boon.primitive.Arry
|
||||
* @see Lists
|
||||
* @see Maps
|
||||
* @see Sets#idx(java.util.NavigableSet, Object)
|
||||
* @see org.boon.primitive.Byt#idx(byte[], int)
|
||||
* @see org.boon.primitive.Chr#idx(char[], int)
|
||||
* @see org.boon.primitive.Int
|
||||
* @see org.boon.primitive.Arry#idx(Object[], int)
|
||||
* @see Lists
|
||||
* @see Maps
|
||||
* @see Sets
|
||||
*/
|
||||
ITEM idx( INDEX index );
|
||||
|
||||
/**
|
||||
* Sets the value at an index.
|
||||
*
|
||||
* @param index index
|
||||
* @param item item you are setting
|
||||
*/
|
||||
void idx( INDEX index, ITEM item );
|
||||
|
||||
/**
|
||||
* Gets the length
|
||||
* This works with Maps, TreeSets, Strings, Object arrays, primitive arrays,
|
||||
* etc.
|
||||
* <p/>
|
||||
* <p/>
|
||||
* <br />
|
||||
* Building from the example at top ({@link UniversalOperations}).
|
||||
* <blockquote>
|
||||
* <pre>
|
||||
*
|
||||
* // Getting the length
|
||||
* assert len( veggiesSet ) == 3;
|
||||
* assert len( fruitList ) == 3;
|
||||
* assert len( fruitArray ) == 3;
|
||||
* assert len( letters ) == 3;
|
||||
* assert len( bytes ) == 4;
|
||||
* assert len( favoritesMap ) == 3;
|
||||
* assert len( map ) == 3;
|
||||
*
|
||||
*
|
||||
*
|
||||
* </pre>
|
||||
* </blockquote>
|
||||
* <p/>
|
||||
* Implemented by:
|
||||
* <pre>
|
||||
* org.boon.primitive.Byt
|
||||
* org.boon.primitive.Chr
|
||||
* org.boon.primitive.Int (in progress)
|
||||
* org.boon.primitive.Lng (in progress)
|
||||
* org.boon.primitive.Arry
|
||||
* org.boon.core.Strings (planned)
|
||||
* org.boon.core.StrBuf (planned)
|
||||
* org.boon.Lists
|
||||
* org.boon.Maps
|
||||
* org.boon.Sets
|
||||
* </pre>
|
||||
*
|
||||
* @return the length
|
||||
* @see org.boon.primitive.Byt
|
||||
* @see org.boon.primitive.Chr
|
||||
* @see org.boon.primitive.Int
|
||||
* @see org.boon.primitive.Arry
|
||||
* @see Lists
|
||||
* @see Maps
|
||||
* @see Sets
|
||||
*/
|
||||
int len();
|
||||
|
||||
|
||||
/**
|
||||
* Adds something to a collection, map or array
|
||||
* <p/>
|
||||
* For maps you addObject an entry
|
||||
* <p/>
|
||||
* <p/>
|
||||
* Implemented by:
|
||||
* <pre>
|
||||
* org.boon.primitive.Byt
|
||||
* org.boon.primitive.Chr
|
||||
* org.boon.primitive.Int (in progress)
|
||||
* org.boon.primitive.Lng (in progress)
|
||||
* org.boon.primitive.Arry
|
||||
* org.boon.core.Strings (planned)
|
||||
* org.boon.core.StrBuf (planned)
|
||||
* org.boon.Lists
|
||||
* org.boon.Maps
|
||||
* org.boon.Sets
|
||||
* </pre>
|
||||
*
|
||||
* @return for arrays, this will return the new array,
|
||||
* for all other collection like things, it returns void.
|
||||
* @see org.boon.primitive.Byt
|
||||
* @see org.boon.primitive.Chr
|
||||
* @see org.boon.primitive.Int
|
||||
* @see org.boon.primitive.Arry
|
||||
* @see Lists
|
||||
* @see Maps
|
||||
* @see Sets
|
||||
*/
|
||||
Returns add( ITEM item );
|
||||
|
||||
|
||||
/**
|
||||
* Copies something.
|
||||
* This does a shallow copy.
|
||||
* There will be a clone that does a deep invasive copy.
|
||||
* <p/>
|
||||
* <p/>
|
||||
* <p/>
|
||||
* Implemented by:
|
||||
* <pre>
|
||||
* org.boon.primitive.Byt
|
||||
* org.boon.primitive.Chr
|
||||
* org.boon.primitive.Int (in progress)
|
||||
* org.boon.primitive.Lng (in progress)
|
||||
* org.boon.primitive.Arry
|
||||
* org.boon.core.Strings (planned)
|
||||
* org.boon.core.StrBuf (planned)
|
||||
* org.boon.Lists
|
||||
* org.boon.Maps
|
||||
* org.boon.Sets
|
||||
* </pre>
|
||||
*
|
||||
* @return the copied object
|
||||
* @see org.boon.primitive.Byt
|
||||
* @see org.boon.primitive.Chr
|
||||
* @see org.boon.primitive.Int
|
||||
* @see org.boon.primitive.Arry
|
||||
* @see Lists
|
||||
* @see Maps
|
||||
* @see Sets
|
||||
*/
|
||||
UniversalOperations copy( UniversalOperations thing );
|
||||
|
||||
|
||||
/**
|
||||
* NOT IMPLEMENTED YET.
|
||||
* Clone does a deep recursive copy.
|
||||
* <p/>
|
||||
* <p/>
|
||||
* <p/>
|
||||
* Implemented by:
|
||||
* <pre>
|
||||
* org.boon.primitive.Byt
|
||||
* org.boon.primitive.Chr
|
||||
* org.boon.primitive.Int (in progress)
|
||||
* org.boon.primitive.Lng (in progress)
|
||||
* org.boon.primitive.Arry
|
||||
* org.boon.core.Strings (planned)
|
||||
* org.boon.core.StrBuf (planned)
|
||||
* org.boon.Lists
|
||||
* org.boon.Maps
|
||||
* org.boon.Sets
|
||||
* </pre>
|
||||
*
|
||||
* @return the length
|
||||
* @see org.boon.primitive.Byt
|
||||
* @see org.boon.primitive.Chr
|
||||
* @see org.boon.primitive.Int
|
||||
* @see org.boon.primitive.Arry
|
||||
* @see Lists
|
||||
* @see Maps
|
||||
* @see Sets
|
||||
*/
|
||||
UniversalOperations clone( UniversalOperations thing );
|
||||
|
||||
|
||||
/**
|
||||
* This does not work with Sets or Maps (use idx for those)
|
||||
* <p/>
|
||||
* Implemented by:
|
||||
* <pre>
|
||||
* org.boon.primitive.Byt
|
||||
* org.boon.primitive.Chr
|
||||
* org.boon.primitive.Int (in progress)
|
||||
* org.boon.primitive.Lng (in progress)
|
||||
* org.boon.primitive.Arry
|
||||
* org.boon.core.Strings (planned)
|
||||
* org.boon.core.StrBuf (planned)
|
||||
* org.boon.Lists
|
||||
* </pre>
|
||||
*
|
||||
* @see org.boon.primitive.Byt
|
||||
* @see org.boon.primitive.Chr
|
||||
* @see org.boon.primitive.Int
|
||||
* @see org.boon.primitive.Arry
|
||||
* @see Lists
|
||||
* @see Maps
|
||||
* @see Sets
|
||||
* @see org.boon.primitive.Byt#insert
|
||||
* @see org.boon.primitive.Chr#insert
|
||||
* @see org.boon.primitive.Int
|
||||
* @see org.boon.primitive.Arry#insert
|
||||
* @see Lists#insert
|
||||
*/
|
||||
void insert( ITEM item );
|
||||
|
||||
|
||||
/**
|
||||
* Slice a string, array, TreeSet, or TreeMap.
|
||||
* Works like python slice notation
|
||||
* <p/>
|
||||
* <pre>
|
||||
* >>> string [0:3]
|
||||
* 'foo'
|
||||
* >>> string [-3:7]
|
||||
* 'bar'
|
||||
* </pre>
|
||||
* <p/>
|
||||
* What follows is derived from
|
||||
* <a href="http://stackoverflow.com/questions/509211/pythons-slice-notation">
|
||||
* Python's slice notation
|
||||
* </a>.
|
||||
* <p/>
|
||||
* <br /> <br />
|
||||
* It's pretty simple really (Python):
|
||||
* <pre>
|
||||
*
|
||||
* a[ start : end ] # items start through end-1
|
||||
* a[ start : ] # items start through the rest of the array
|
||||
* a[ : end ] # items from the beginning through end-1
|
||||
* a[ : ] # a copy of the whole array
|
||||
*
|
||||
* </pre>
|
||||
* <p/>
|
||||
* Boon would be (Java):
|
||||
* <pre>
|
||||
*
|
||||
* slc( a, start, end ) // items start through end-1
|
||||
* slc( a, start ) // items start through the rest of the array
|
||||
* slcEnd( a, end ) // items from the beginning through end-1
|
||||
* copy( a ) // a copy of the whole array
|
||||
* </pre>
|
||||
* <p/>
|
||||
* NOT IMPLEMENTED YET: <br />
|
||||
* <p/>
|
||||
* There is also the step value, which can be used with any of the above:
|
||||
* <p/>
|
||||
* <br />
|
||||
* Python
|
||||
* <pre>
|
||||
*
|
||||
* a[ start : end : step] # start through not past end, by step
|
||||
*
|
||||
* </pre>
|
||||
* Boon
|
||||
* <pre>
|
||||
*
|
||||
* slc(a, start , end, step) // start through not past end, by step
|
||||
*
|
||||
* </pre>
|
||||
* The key point to remember is that the :end value represents the
|
||||
* first value that is not in the selected slice. So, the difference
|
||||
* between end and start is the number of elements selected
|
||||
* (if step is 1, the default).
|
||||
* <br />
|
||||
* The other feature is that start or end may be a
|
||||
* negative number, which means it counts from the end of the
|
||||
* array instead of the beginning. So:
|
||||
* <p/>
|
||||
* <br/>
|
||||
* Python slice notation
|
||||
* <pre>
|
||||
* a[ -1 ] # last item in the array
|
||||
* a[ -2: ] # last two items in the array
|
||||
* a[ :-2 ] # everything except the last two items
|
||||
* </pre>
|
||||
* Boon slice notation
|
||||
* <pre>
|
||||
* slc( a, -1) # last item in the array
|
||||
* slc( -2 ) # last two items in the array
|
||||
* slcEnd( -2 ) # everything except the last two items
|
||||
* </pre>
|
||||
* <p/>
|
||||
* Python and boon are kind to the programmer
|
||||
* if there are fewer items than you ask for.
|
||||
* For example, if you ask for a[:-2] and a only contains one element,
|
||||
* you get an empty listStream instead of an error.
|
||||
* Sometimes you would prefer the error, so you have to
|
||||
* be aware that this may happen.
|
||||
* <p/>
|
||||
* Implemented by:
|
||||
* <pre>
|
||||
*
|
||||
* org.boon.primitive.Byt
|
||||
* org.boon.primitive.Chr
|
||||
* org.boon.primitive.Int (in progress)
|
||||
* org.boon.primitive.Lng (in progress)
|
||||
* org.boon.primitive.Arry
|
||||
* org.boon.core.Strings (planned)
|
||||
* org.boon.core.StrBuf (planned)
|
||||
* org.boon.Lists
|
||||
* </pre>
|
||||
*
|
||||
* @see org.boon.primitive.Byt
|
||||
* @see org.boon.primitive.Chr
|
||||
* @see org.boon.primitive.Int
|
||||
* @see org.boon.primitive.Arry
|
||||
* @see Lists
|
||||
* @see Maps
|
||||
* @see Sets
|
||||
* @see org.boon.primitive.Byt#slc
|
||||
* @see org.boon.primitive.Chr#slc
|
||||
* @see org.boon.primitive.Int
|
||||
* @see org.boon.primitive.Arry#slc
|
||||
* @see Lists#slc
|
||||
* @see Maps#slc
|
||||
* @see Sets#slc
|
||||
*/
|
||||
void slc( INDEX start, INDEX end );
|
||||
|
||||
/**
|
||||
* @param start index start
|
||||
* @see UniversalOperations#slc(Object, Object)
|
||||
*/
|
||||
void slc( INDEX start );
|
||||
|
||||
/**
|
||||
* @param end index end
|
||||
* @see UniversalOperations#slc(Object, Object)
|
||||
*/
|
||||
void slcEnd( INDEX end );
|
||||
|
||||
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
/*
|
||||
* Copyright 2013-2014 Richard M. Hightower
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* __________ _____ __ .__
|
||||
* \______ \ ____ ____ ____ /\ / \ _____ | | _|__| ____ ____
|
||||
* | | _// _ \ / _ \ / \ \/ / \ / \\__ \ | |/ / |/ \ / ___\
|
||||
* | | ( <_> | <_> ) | \ /\ / Y \/ __ \| <| | | \/ /_/ >
|
||||
* |______ /\____/ \____/|___| / \/ \____|__ (____ /__|_ \__|___| /\___ /
|
||||
* \/ \/ \/ \/ \/ \//_____/
|
||||
* ____. ___________ _____ ______________.___.
|
||||
* | |____ ___ _______ \_ _____/ / _ \ / _____/\__ | |
|
||||
* | \__ \\ \/ /\__ \ | __)_ / /_\ \ \_____ \ / | |
|
||||
* /\__| |/ __ \\ / / __ \_ | \/ | \/ \ \____ |
|
||||
* \________(____ /\_/ (____ / /_______ /\____|__ /_______ / / ______|
|
||||
* \/ \/ \/ \/ \/ \/
|
||||
*/
|
||||
|
||||
package org.boon.cache;
|
||||
|
||||
/**
|
||||
* Holds a set of key value pairs in a cache interface.
|
||||
*
|
||||
* @param <KEY> key
|
||||
* @param <VALUE> value
|
||||
*/
|
||||
public interface Cache<KEY, VALUE> {
|
||||
|
||||
/**
|
||||
* Puts the key in.
|
||||
* @param key the key
|
||||
* @param value the value
|
||||
*/
|
||||
void put( KEY key, VALUE value );
|
||||
|
||||
/**
|
||||
* return the value given the key.
|
||||
* @param key the key
|
||||
* @return the value
|
||||
*/
|
||||
VALUE get( KEY key );
|
||||
|
||||
VALUE getSilent( KEY key );
|
||||
|
||||
void remove( KEY key );
|
||||
|
||||
int size();
|
||||
}
|
|
@ -1,232 +0,0 @@
|
|||
/*
|
||||
* Copyright 2013-2014 Richard M. Hightower
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* __________ _____ __ .__
|
||||
* \______ \ ____ ____ ____ /\ / \ _____ | | _|__| ____ ____
|
||||
* | | _// _ \ / _ \ / \ \/ / \ / \\__ \ | |/ / |/ \ / ___\
|
||||
* | | ( <_> | <_> ) | \ /\ / Y \/ __ \| <| | | \/ /_/ >
|
||||
* |______ /\____/ \____/|___| / \/ \____|__ (____ /__|_ \__|___| /\___ /
|
||||
* \/ \/ \/ \/ \/ \//_____/
|
||||
* ____. ___________ _____ ______________.___.
|
||||
* | |____ ___ _______ \_ _____/ / _ \ / _____/\__ | |
|
||||
* | \__ \\ \/ /\__ \ | __)_ / /_\ \ \_____ \ / | |
|
||||
* /\__| |/ __ \\ / / __ \_ | \/ | \/ \ \____ |
|
||||
* \________(____ /\_/ (____ / /_______ /\____|__ /_______ / / ______|
|
||||
* \/ \/ \/ \/ \/ \/
|
||||
*/
|
||||
|
||||
package org.boon.cache;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import static org.boon.Exceptions.die;
|
||||
|
||||
/**
|
||||
* A cache entry.
|
||||
* @param <KEY> the key for the cache entry
|
||||
* @param <VALUE> the value
|
||||
*/
|
||||
class CacheEntry<KEY, VALUE> implements Comparable<CacheEntry> {
|
||||
|
||||
/** Keep track of the read count. */
|
||||
final AtomicInteger readCount = new AtomicInteger();
|
||||
|
||||
/** order. */
|
||||
final int order;
|
||||
|
||||
/** The value. */
|
||||
VALUE value;
|
||||
|
||||
/** The key. */
|
||||
final KEY key;
|
||||
|
||||
/** The type of cache.*/
|
||||
final CacheType type;
|
||||
|
||||
/** The time the entry was added. */
|
||||
final long time;
|
||||
|
||||
|
||||
/** Creates a cache entry.
|
||||
*
|
||||
* @param key key
|
||||
* @param value value
|
||||
* @param order order
|
||||
* @param type type
|
||||
* @param time time of entry
|
||||
*/
|
||||
CacheEntry( KEY key, VALUE value, int order, CacheType type, long time ) {
|
||||
this.order = order;
|
||||
this.value = value;
|
||||
this.key = key;
|
||||
this.time = time;
|
||||
this.type = type;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Comparison of entries this determines what we will order the cache by
|
||||
* which determines which type of cache it is.
|
||||
* @param other the other entry
|
||||
* @return results
|
||||
*/
|
||||
@Override
|
||||
public final int compareTo( CacheEntry other ) {
|
||||
switch ( type ) {
|
||||
|
||||
case LFU:
|
||||
return compareToLFU( other );
|
||||
case LRU:
|
||||
return compareToLRU( other );
|
||||
case FIFO:
|
||||
return compareToFIFO( other );
|
||||
default:
|
||||
die();
|
||||
return 0;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param other other entry to compare to
|
||||
* @return
|
||||
*/
|
||||
private final int compareReadCount( CacheEntry other ) {
|
||||
|
||||
if ( readCount.get() > other.readCount.get() ) { //this read count is greater so it has higher priority
|
||||
return 1;
|
||||
} else if ( readCount.get() < other.readCount.get() ) {//this read count is lower so it has lower priority
|
||||
return -1;
|
||||
} else if ( readCount.get() == other.readCount.get() ) {
|
||||
return 0;
|
||||
}
|
||||
die();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare the time.
|
||||
* @param other the other entry
|
||||
* @return results
|
||||
*/
|
||||
private final int compareTime( CacheEntry other ) {
|
||||
|
||||
if ( time > other.time ) { //this time stamp is greater so it has higher priority
|
||||
return 1;
|
||||
} else if ( time < other.time ) {//this time stamp is lower so it has lower priority
|
||||
return -1;
|
||||
} else if ( time == other.time ) {//equal priority
|
||||
return 0;
|
||||
}
|
||||
die();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare the order.
|
||||
* @param other the other entry
|
||||
* @return results
|
||||
*/
|
||||
private final int compareOrder( CacheEntry other ) {
|
||||
|
||||
if ( order > other.order ) { //this order is lower so it has higher priority
|
||||
return 1;
|
||||
} else if ( order < other.order ) {//this order is higher so it has lower priority
|
||||
return -1;
|
||||
} else if ( order == other.order ) {//equal priority
|
||||
return 0;
|
||||
}
|
||||
die();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the read counts.
|
||||
* @param other read count
|
||||
* @return results
|
||||
*/
|
||||
private final int compareToLFU( CacheEntry other ) {
|
||||
|
||||
int cmp = compareReadCount( other );
|
||||
if ( cmp != 0 ) {
|
||||
return cmp;
|
||||
}
|
||||
|
||||
cmp = compareTime( other );
|
||||
if ( cmp != 0 ) {
|
||||
return cmp;
|
||||
}
|
||||
|
||||
return compareOrder( other );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compare the time.
|
||||
* @param other other entry to compare to
|
||||
* @return results
|
||||
*/
|
||||
private final int compareToLRU( CacheEntry other ) {
|
||||
|
||||
int cmp = compareTime( other );
|
||||
if ( cmp != 0 ) {
|
||||
return cmp;
|
||||
}
|
||||
|
||||
|
||||
cmp = compareOrder( other );
|
||||
if ( cmp != 0 ) {
|
||||
return cmp;
|
||||
}
|
||||
|
||||
|
||||
return compareReadCount( other );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compare for FIFO
|
||||
* @param other the other entry
|
||||
* @return results
|
||||
*/
|
||||
private final int compareToFIFO( CacheEntry other ) {
|
||||
int cmp = compareOrder( other );
|
||||
if ( cmp != 0 ) {
|
||||
return cmp;
|
||||
}
|
||||
|
||||
|
||||
cmp = compareTime( other );
|
||||
if ( cmp != 0 ) {
|
||||
return cmp;
|
||||
}
|
||||
|
||||
|
||||
return cmp = compareReadCount( other );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CE{" +
|
||||
"c=" + readCount +
|
||||
", ord=" + order +
|
||||
", val=" + value +
|
||||
", ky=" + key +
|
||||
", typ=" + type +
|
||||
", t=" + time +
|
||||
'}';
|
||||
}
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
/*
|
||||
* Copyright 2013-2014 Richard M. Hightower
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* __________ _____ __ .__
|
||||
* \______ \ ____ ____ ____ /\ / \ _____ | | _|__| ____ ____
|
||||
* | | _// _ \ / _ \ / \ \/ / \ / \\__ \ | |/ / |/ \ / ___\
|
||||
* | | ( <_> | <_> ) | \ /\ / Y \/ __ \| <| | | \/ /_/ >
|
||||
* |______ /\____/ \____/|___| / \/ \____|__ (____ /__|_ \__|___| /\___ /
|
||||
* \/ \/ \/ \/ \/ \//_____/
|
||||
* ____. ___________ _____ ______________.___.
|
||||
* | |____ ___ _______ \_ _____/ / _ \ / _____/\__ | |
|
||||
* | \__ \\ \/ /\__ \ | __)_ / /_\ \ \_____ \ / | |
|
||||
* /\__| |/ __ \\ / / __ \_ | \/ | \/ \ \____ |
|
||||
* \________(____ /\_/ (____ / /_______ /\____|__ /_______ / / ______|
|
||||
* \/ \/ \/ \/ \/ \/
|
||||
*/
|
||||
|
||||
package org.boon.cache;
|
||||
|
||||
public enum CacheType {
|
||||
|
||||
LRU,
|
||||
LFU,
|
||||
FIFO
|
||||
}
|
|
@ -1,165 +0,0 @@
|
|||
/*
|
||||
* Copyright 2013-2014 Richard M. Hightower
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* __________ _____ __ .__
|
||||
* \______ \ ____ ____ ____ /\ / \ _____ | | _|__| ____ ____
|
||||
* | | _// _ \ / _ \ / \ \/ / \ / \\__ \ | |/ / |/ \ / ___\
|
||||
* | | ( <_> | <_> ) | \ /\ / Y \/ __ \| <| | | \/ /_/ >
|
||||
* |______ /\____/ \____/|___| / \/ \____|__ (____ /__|_ \__|___| /\___ /
|
||||
* \/ \/ \/ \/ \/ \//_____/
|
||||
* ____. ___________ _____ ______________.___.
|
||||
* | |____ ___ _______ \_ _____/ / _ \ / _____/\__ | |
|
||||
* | \__ \\ \/ /\__ \ | __)_ / /_\ \ \_____ \ / | |
|
||||
* /\__| |/ __ \\ / / __ \_ | \/ | \/ \ \____ |
|
||||
* \________(____ /\_/ (____ / /_______ /\____|__ /_______ / / ______|
|
||||
* \/ \/ \/ \/ \/ \/
|
||||
*/
|
||||
|
||||
package org.boon.cache;
|
||||
|
||||
import java.util.Deque;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentLinkedDeque;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
/**
|
||||
* ConcurrentLruCache cache.
|
||||
* This has the limitation of using a single lock to update live status of key.
|
||||
*
|
||||
* @param <KEY> the key
|
||||
* @param <VALUE> the value
|
||||
*/
|
||||
public class ConcurrentLruCache<KEY, VALUE> implements Cache<KEY, VALUE> {
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Map to hold the cache values
|
||||
*/
|
||||
private final Map<KEY, VALUE> map = new ConcurrentHashMap<>();
|
||||
|
||||
/** Queue to hold keys in the LRU cache.
|
||||
*/
|
||||
private final Deque<KEY> queue = new ConcurrentLinkedDeque<>();
|
||||
|
||||
/** Limit the amount you can hold in the map. */
|
||||
private final int limit;
|
||||
|
||||
|
||||
/** Creates an LRU Cache with a given limit. */
|
||||
public ConcurrentLruCache( int limit ) {
|
||||
this.limit = limit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Key
|
||||
* @param key the key
|
||||
* @param value the value
|
||||
*/
|
||||
@Override
|
||||
public void put( KEY key, VALUE value ) {
|
||||
VALUE oldValue = map.put( key, value );
|
||||
if ( oldValue != null ) {
|
||||
removeThenAddKey( key );
|
||||
} else {
|
||||
addKey( key );
|
||||
}
|
||||
if ( map.size() > limit ) {
|
||||
map.remove( removeLast() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the value at key
|
||||
* @param key the key
|
||||
* @return value
|
||||
*/
|
||||
@Override
|
||||
public VALUE get( KEY key ) {
|
||||
removeThenAddKey( key );
|
||||
return map.get( key );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the key without updating the LRU status for testing
|
||||
* @param key key
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public VALUE getSilent( KEY key ) {
|
||||
return map.get( key );
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the key.
|
||||
* @param key
|
||||
*/
|
||||
@Override
|
||||
public void remove( KEY key ) {
|
||||
removeFirstOccurrence( key );
|
||||
map.remove( key );
|
||||
}
|
||||
|
||||
/**
|
||||
* Size of the cache.
|
||||
* @return size
|
||||
*/
|
||||
@Override
|
||||
public int size() {
|
||||
return map.size();
|
||||
}
|
||||
|
||||
|
||||
/** Add a key. */
|
||||
private void addKey( KEY key ) {
|
||||
queue.addFirst(key);
|
||||
}
|
||||
|
||||
/** Remove the last key. */
|
||||
private KEY removeLast() {
|
||||
final KEY removedKey = queue.removeLast();
|
||||
return removedKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* This removes the item from the queue and then re-adds it to increment the
|
||||
* live-ness of the item. It updates the LRU since this key was read.
|
||||
*
|
||||
* @param key key
|
||||
*/
|
||||
private void removeThenAddKey( KEY key ) {
|
||||
queue.removeFirstOccurrence( key );
|
||||
queue.addFirst( key );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the key.
|
||||
* @param key
|
||||
*/
|
||||
private void removeFirstOccurrence( KEY key ) {
|
||||
queue.removeFirstOccurrence(key);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public String toString() {
|
||||
return map.toString();
|
||||
}
|
||||
}
|
|
@ -1,250 +0,0 @@
|
|||
/*
|
||||
* Copyright 2013-2014 Richard M. Hightower
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* __________ _____ __ .__
|
||||
* \______ \ ____ ____ ____ /\ / \ _____ | | _|__| ____ ____
|
||||
* | | _// _ \ / _ \ / \ \/ / \ / \\__ \ | |/ / |/ \ / ___\
|
||||
* | | ( <_> | <_> ) | \ /\ / Y \/ __ \| <| | | \/ /_/ >
|
||||
* |______ /\____/ \____/|___| / \/ \____|__ (____ /__|_ \__|___| /\___ /
|
||||
* \/ \/ \/ \/ \/ \//_____/
|
||||
* ____. ___________ _____ ______________.___.
|
||||
* | |____ ___ _______ \_ _____/ / _ \ / _____/\__ | |
|
||||
* | \__ \\ \/ /\__ \ | __)_ / /_\ \ \_____ \ / | |
|
||||
* /\__| |/ __ \\ / / __ \_ | \/ | \/ \ \____ |
|
||||
* \________(____ /\_/ (____ / /_______ /\____|__ /_______ / / ______|
|
||||
* \/ \/ \/ \/ \/ \/
|
||||
*/
|
||||
|
||||
package org.boon.cache;
|
||||
|
||||
import org.boon.collections.SortableConcurrentList;
|
||||
import org.boon.core.timer.TimeKeeper;
|
||||
import org.boon.core.timer.TimeKeeperBasic;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
|
||||
/**
|
||||
* Fast concurrent read cache with many options.
|
||||
*
|
||||
* Writes are slow (single threaded lock)
|
||||
* Reads are very fast no lock.
|
||||
* Compaction (if you are over the limit) is slow.
|
||||
*
|
||||
*
|
||||
* @param <KEY> key
|
||||
* @param <VALUE> value
|
||||
*/
|
||||
public class FastConcurrentReadLruLfuFifoCache<KEY, VALUE> implements Cache<KEY, VALUE> {
|
||||
|
||||
|
||||
/**
|
||||
* Map to hold cache items.
|
||||
*/
|
||||
private final ConcurrentHashMap<KEY, CacheEntry<KEY, VALUE>> map = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* A list that can be sorted easily. It is concurrent.
|
||||
*/
|
||||
private final SortableConcurrentList<CacheEntry<KEY, VALUE>> list;
|
||||
|
||||
/**
|
||||
* Eviction size.
|
||||
*/
|
||||
private final int evictSize;
|
||||
|
||||
/**
|
||||
* Count which determines order.
|
||||
*/
|
||||
private final AtomicInteger count = new AtomicInteger();
|
||||
|
||||
/**
|
||||
* CacheType.
|
||||
*/
|
||||
private final CacheType type;
|
||||
|
||||
/**
|
||||
* How do we determine time of entry.
|
||||
*/
|
||||
private final TimeKeeper timeKeeper;
|
||||
|
||||
/**
|
||||
* New cache LFU is the default.
|
||||
* @param evictSize
|
||||
*/
|
||||
public FastConcurrentReadLruLfuFifoCache( int evictSize ) {
|
||||
this.evictSize = ( int ) ( evictSize + ( evictSize * 0.20f ) );
|
||||
list = new SortableConcurrentList<>();
|
||||
this.type = CacheType.LFU;
|
||||
timeKeeper = new TimeKeeperBasic();
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* New cache
|
||||
* @param evictSize eviction size
|
||||
* @param tradeoffs tradeoffs
|
||||
* @param type cache type.
|
||||
*/
|
||||
public FastConcurrentReadLruLfuFifoCache( int evictSize, Tradeoffs tradeoffs, CacheType type ) {
|
||||
this.evictSize = ( int ) ( evictSize + ( evictSize * 0.20f ) );
|
||||
|
||||
this.type = type;
|
||||
|
||||
if ( tradeoffs == Tradeoffs.FAST_REMOVE ) {
|
||||
list = new SortableConcurrentList<>( new LinkedList<CacheEntry<KEY, VALUE>>() );
|
||||
} else if ( tradeoffs == Tradeoffs.FAST_SORT ) {
|
||||
list = new SortableConcurrentList<>( new ArrayList<CacheEntry<KEY, VALUE>>() );
|
||||
} else {
|
||||
list = new SortableConcurrentList<>();
|
||||
}
|
||||
|
||||
|
||||
timeKeeper = new TimeKeeperBasic();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Just for testing
|
||||
*
|
||||
* @param evictSize
|
||||
* @param type
|
||||
*/
|
||||
FastConcurrentReadLruLfuFifoCache( boolean test, int evictSize, CacheType type ) {
|
||||
this.evictSize = ( int ) ( evictSize + ( evictSize * 0.20f ) );
|
||||
list = new SortableConcurrentList<>();
|
||||
this.type = type;
|
||||
|
||||
timeKeeper = new TimeKeeper() {
|
||||
int i;
|
||||
|
||||
@Override
|
||||
public long time() {
|
||||
return System.currentTimeMillis() + i++;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/** Get the value from the cache. It does not touch the lock so
|
||||
* reads are fast.
|
||||
* This does not touch the order list so it is fast.
|
||||
* @param key the key
|
||||
* @return value
|
||||
*/
|
||||
public VALUE get( KEY key ) {
|
||||
CacheEntry<KEY, VALUE> cacheEntry = map.get( key );
|
||||
if ( cacheEntry != null ) {
|
||||
cacheEntry.readCount.incrementAndGet();
|
||||
return cacheEntry.value;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Used for testing as it gets the value without updating stats
|
||||
* @param key key
|
||||
* @return value
|
||||
*/
|
||||
public VALUE getSilent( KEY key ) {
|
||||
CacheEntry<KEY, VALUE> cacheEntry = map.get( key );
|
||||
if ( cacheEntry != null ) {
|
||||
return cacheEntry.value;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the key. This touches the lock.
|
||||
* So removes are **not** fast.
|
||||
* @param key key
|
||||
*/
|
||||
@Override
|
||||
public void remove( KEY key ) {
|
||||
CacheEntry<KEY, VALUE> entry = map.remove( key );
|
||||
if ( entry != null ) {
|
||||
list.remove( entry );
|
||||
}
|
||||
}
|
||||
|
||||
/** Put the value. This touches the lock so puts are **not** fast.
|
||||
*
|
||||
* @param key the key key
|
||||
* @param value the value value
|
||||
*/
|
||||
public void put( KEY key, VALUE value ) {
|
||||
CacheEntry<KEY, VALUE> entry = map.get( key );
|
||||
|
||||
|
||||
if ( entry == null ) {
|
||||
entry = new CacheEntry<>( key, value, order(), type, time() );
|
||||
list.add( entry );
|
||||
map.put( key, entry );
|
||||
} else {
|
||||
entry.readCount.incrementAndGet();
|
||||
entry.value = value;
|
||||
}
|
||||
evictIfNeeded();
|
||||
}
|
||||
|
||||
/** Gets the time. */
|
||||
private long time() {
|
||||
return this.timeKeeper.time();
|
||||
}
|
||||
|
||||
|
||||
/** Avoid overflow. */
|
||||
private final int order() {
|
||||
int order = count.incrementAndGet();
|
||||
if ( order > Integer.MAX_VALUE - 100 ) {
|
||||
count.set( 0 );
|
||||
}
|
||||
return order;
|
||||
}
|
||||
|
||||
/** Evict if we are over the size limit.*/
|
||||
private final void evictIfNeeded() {
|
||||
if ( list.size() > evictSize ) {
|
||||
|
||||
final List<CacheEntry<KEY, VALUE>> killList = list.sortAndReturnPurgeList( 0.1f );
|
||||
|
||||
for ( CacheEntry<KEY, VALUE> cacheEntry : killList ) {
|
||||
map.remove( cacheEntry.key );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return map.toString();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* How many items do we have in the cache?
|
||||
* @return size
|
||||
*/
|
||||
public int size() {
|
||||
return this.map.size();
|
||||
}
|
||||
}
|
|
@ -1,96 +0,0 @@
|
|||
/*
|
||||
* Copyright 2013-2014 Richard M. Hightower
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, |