
net.javapla.jawn.core.Value Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jawn-core Show documentation
Show all versions of jawn-core Show documentation
java-web-planet / jawn - A simple web framework in Java
The newest version!
package net.javapla.jawn.core;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.time.format.DateTimeParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;
import net.javapla.jawn.core.internal.ValueParser;
import net.javapla.jawn.core.util.DateUtil;
public interface Value extends Iterable { // SimpleValue
/**
* {@link Boolean#parseBoolean(String)} always returns either true
or false
* regardless of input
*
* (That is why no asBoolean(default)
exists)
*
* @see Boolean#parseBoolean
* @return
*/
default boolean asBoolean() {
return Boolean.parseBoolean(value());
}
default double asDouble() {
return simpleValue(Double::parseDouble, double.class);
}
default double asDouble(final double fallback) {
try {
return asDouble();
} catch (Up.ParseError e) {
return fallback;
}
//return toOptional().map(Double::parseDouble).orElse(fallback);//toOptional(Double.class).orElse(fallback);
}
default double asDouble(final Function mapper, final double fallback) {
try {
return mapper.apply(asDouble());
} catch (Up.ParseError e) {
return fallback;
}
}
default int asInt() {
return simpleValue(Integer::parseInt, int.class);
}
default int asInt(final int fallback) {
//return map((s) -> (Integer::parseInt)).orElse(fallback);
try {
return asInt();
} catch (Up.ParseError e) {
return fallback;
}
}
/**
* Applies the mapper
to the {@link #asInt()}, if a value is present.
* Otherwise returns the fallback
*
* @param fallback
* @param mapper
* @return
*/
default int asInt(final Function mapper, final int fallback) {
try {
return mapper.apply(asInt());
} catch (Up.ParseError e) {
return fallback;
}
}
default long asLong() {
try {
return Long.valueOf(value());
} catch (NumberFormatException e) {
// might be a date
try {
return DateUtil.fromDateString(value()).toEpochMilli();
} catch (DateTimeParseException ignored) { }
throw new Up.ParseError("Failed to parse value as: " + long.class, e);
}
}
default long asLong(final long fallback) {
try {
return asLong();
} catch (Up.ParseError e) {
return fallback;
}
//return toOptional().map(Long::parseLong).orElse(fallback);
}
default long asLong(final Function mapper, final long fallback) {
try {
return mapper.apply(asLong());
} catch (Up.ParseError e) {
return fallback;
}
}
private T simpleValue(final Function callback, Class type) {
try {
return callback.apply(value());
} catch (NumberFormatException e) {
throw Up.ParseError("Failed to parse value as: " + type, e);
}
}
@Override
default Iterator iterator() {
return Collections.singleton(this).iterator();
}
default String value(final String fallback) {
return asOptional().orElse(fallback);
}
default T value(final Function mapper, final T fallback) {
if (!isPresent()) return fallback;
try {
return mapper.apply(value());
} catch (Exception e) {
return fallback;
}
}
/**
* Simply another name for {@link #value()}
*/
default String asString() {
return value();
}
default > T asEnum(final Class type) {
EnumSet set = EnumSet.allOf(type);
return set
.stream()
.filter(e -> e.name().equalsIgnoreCase(value()))
.findFirst()
.orElseGet(() -> java.lang.Enum.valueOf(type, value()));
}
default T as(Class type) {
return ValueParser.to(this, type);
}
// Commented out until we know if we ever are going to need it
/*default Object as(Type type) {
return ValueParser.to(this, type);
}*/
default List asList() {
if (isPresent())
return Collections.singletonList(value());
return Collections.emptyList();
}
default List asList(final Class type) {
return ValueParser.toCollection(this, type, new ArrayList(4));
}
default Set asSet() {
return Collections.singleton(value());
}
default Set asSet(final Class type) {
return ValueParser.toCollection(this, type, new HashSet(4));
}
default Optional asOptional() {
if (!isPresent()) return Optional.empty();
try {
return Optional.of(value());
} catch (Exception e) {
return Optional.empty();
}
}
default Optional asOptional(final Class type) {
//if (type.isPrimitive()) throw new IllegalArgumentException("Primitive types are not allowed in type parameters: " + type);
if (!isPresent()) return Optional.empty();
try {
return Optional.ofNullable(ValueParser.to(this, type));//to(type));
} catch (Exception e) {
return Optional.empty();
}
}
String value();
boolean isPresent();
default boolean isMissing() {
return !isPresent();
}
default void ifPresent(final Consumer action) {
if (isPresent()) {
action.accept(value());
}
}
default void ifPresent(final Class type, Consumer action) {
if (isPresent()) {
action.accept(as(type));
}
}
default Value orElse(Value other) {
return isPresent() ? this : other;
}
default Optional map(Function mapper) {
if (!isPresent()) {
return Optional.empty();
} else {
return Optional.ofNullable(mapper.apply(value()));
}
}
default Optional map(Class type, Function mapper) {
if (!isPresent()) {
return Optional.empty();
} else {
return Optional.ofNullable(mapper.apply(ValueParser.to(this, type)));
}
}
static Value of(final String value) {
return new StringValue(value);
}
static Value of(Number value) {
return new NumberValue(value);
}
static Value of(final String ... valuables) {
return of(Arrays.asList(valuables));//new ListValue(Arrays.asList(valuables).stream().map(StringValue::new).collect(Collectors.toList()));
}
static Value of(final List valuables) {
if (valuables == null || valuables.size() == 0) return empty();
if (valuables.size() == 1) return Value.of(valuables.get(0));
return new ListValue(valuables.stream().map(StringValue::new).collect(Collectors.toList()));
}
static Value of(final Optional opt) {
return opt.map(StringValue::new).orElse(new StringValue());
}
static Value of(final Value value) {
return value;
}
static Value of(final Value ... valuables) {
return new ListValue(Arrays.asList(valuables));
}
/*static Value of(final List valuables) {
return new ListValue(valuables);
}*/
final class StringValue implements Value {
private final String value;
public StringValue() {
this(null);
}
public StringValue(final String value) {
this.value = value;
}
@Override
public String value() {
return value;
}
@Override
public boolean isPresent() {
return value != null && !value.isBlank();
}
@Override
public String toString() {
return value != null
? String.format("%s[%s]", this.getClass().getSimpleName(), value)
: "Value.empty";
}
}
final class NumberValue implements Value {
private final Number value;
public NumberValue() {
this(null);
}
public NumberValue(Number n) {
this.value = n;
}
@Override
public String value() {
return String.valueOf(value);
}
@Override
public int asInt() {
if (!isPresent()) throw Up.ParseError("Value is missing");
return value.intValue();
}
@Override
public long asLong() {
if (!isPresent()) throw Up.ParseError("Value is missing");
return value.longValue();
}
@Override
public double asDouble() {
if (!isPresent()) throw Up.ParseError("Value is missing");
return value.doubleValue();
}
@Override
public boolean isPresent() {
return value != null;
}
@Override
public String toString() {
return value != null
? String.format("%s[%s]", this.getClass().getSimpleName(), value)
: "Value.empty";
}
}
final class ListValue implements Value {
private final List valuables;
public ListValue(final List valuables) {
this.valuables = valuables;
}
@Override
public String value() {
return valuables.get(0).value();
}
@Override
public List asList() {
return valuables.stream().map(Value::value).collect(Collectors.toList());
}
@Override
public Set asSet() {
return valuables.stream().map(Value::value).collect(Collectors.toSet());
}
@Override
public boolean isPresent() {
return !valuables.isEmpty();
}
@Override
public Iterator iterator() {
return valuables.iterator();
}
@Override
public String toString() {
return valuables != null
? String.format("%s[%s]", this.getClass().getSimpleName(), valuables)
: "Value.empty";
}
}
interface ByteArrayValue extends Value {
default String value(Charset charset) {
return new String(bytes(), charset);
}
byte[] bytes();
/**
* The same as Content-Length
header
* @return size in bytes
*/
long size();
/**
* Is the data contained in memory
* @return if data is in memory
*/
boolean inMemory();
InputStream stream();
}
static Value empty() {
return new Value() {
@Override
public String value() {
return null;
}
@Override
public boolean isPresent() {
return false;
}
};
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy