Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
236 changes: 236 additions & 0 deletions asdf-core/src/main/java/org/asdfformat/asdf/node/AsdfNode.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.Instant;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
Expand Down Expand Up @@ -75,6 +76,18 @@ public boolean containsKey(final AsdfNode key) {
return false;
}

@Override
public boolean containsKey(final Object... keys) {
if (keys.length == 0) {
return true;
}

final AsdfNode currentKey = constructKeyNode(keys[0]);

return getOptional(currentKey).map(node -> node.containsKey(Arrays.copyOfRange(keys, 1, keys.length)))
.orElse(false);
}

@Override
public int size() {
return 0;
Expand All @@ -100,6 +113,17 @@ public AsdfNode get(final AsdfNode key) {
throw new IllegalStateException(makeGetErrorMessage("AsdfNode"));
}

@Override
public AsdfNode get(final Object... keys) {
if (keys.length == 0) {
return this;
}

final AsdfNode currentKey = constructKeyNode(keys[0]);

return get(currentKey).get(Arrays.copyOfRange(keys, 1, keys.length));
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can see a reason to copy the array for this operation. If upoi were going to modify it or it was threaded it might make sense but it does not appear necessary here.

I see this in other places as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to pass the array without its first element, is there a better way to do that? I could add an additional get(...) overload that accepts the array start index.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh, I missed that. That makes sense.

}

@Override
public Optional<AsdfNode> getOptional(final String key) {
if (containsKey(key)) {
Expand Down Expand Up @@ -156,6 +180,17 @@ public Optional<AsdfNode> getOptional(final AsdfNode key) {
}
}

@Override
public Optional<AsdfNode> getOptional(final Object... keys) {
if (keys.length == 0) {
return Optional.of(this);
}

final AsdfNode currentKey = constructKeyNode(keys[0]);

return getOptional(currentKey).flatMap(node -> node.getOptional(Arrays.copyOfRange(keys, 1, keys.length)));
}

@Override
public BigDecimal getBigDecimal(final String key) {
return get(key).asBigDecimal();
Expand All @@ -176,6 +211,11 @@ public BigDecimal getBigDecimal(final AsdfNode key) {
return get(key).asBigDecimal();
}

@Override
public BigDecimal getBigDecimal(final Object... keys) {
return get(keys).asBigDecimal();
}

@Override
public BigInteger getBigInteger(final String key) {
return get(key).asBigInteger();
Expand All @@ -196,6 +236,11 @@ public BigInteger getBigInteger(final AsdfNode key) {
return get(key).asBigInteger();
}

@Override
public BigInteger getBigInteger(final Object... keys) {
return get(keys).asBigInteger();
}

@Override
public boolean getBoolean(final String key) {
return get(key).asBoolean();
Expand All @@ -216,6 +261,11 @@ public boolean getBoolean(final AsdfNode key) {
return get(key).asBoolean();
}

@Override
public boolean getBoolean(final Object... keys) {
return get(keys).asBoolean();
}

@Override
public byte getByte(final String key) {
return get(key).asByte();
Expand All @@ -236,6 +286,11 @@ public byte getByte(final AsdfNode key) {
return get(key).asByte();
}

@Override
public byte getByte(final Object... keys) {
return get(keys).asByte();
}

@Override
public double getDouble(final String key) {
return get(key).asDouble();
Expand All @@ -256,6 +311,11 @@ public double getDouble(final AsdfNode key) {
return get(key).asDouble();
}

@Override
public double getDouble(final Object... keys) {
return get(keys).asDouble();
}

@Override
public float getFloat(final String key) {
return get(key).asFloat();
Expand All @@ -276,6 +336,11 @@ public float getFloat(final AsdfNode key) {
return get(key).asFloat();
}

@Override
public float getFloat(final Object... keys) {
return get(keys).asFloat();
}

@Override
public Instant getInstant(final String key) {
return get(key).asInstant();
Expand All @@ -296,6 +361,11 @@ public Instant getInstant(final AsdfNode key) {
return get(key).asInstant();
}

@Override
public Instant getInstant(final Object... keys) {
return get(keys).asInstant();
}

@Override
public int getInt(final String key) {
return get(key).asInt();
Expand All @@ -316,6 +386,11 @@ public int getInt(final AsdfNode key) {
return get(key).asInt();
}

@Override
public int getInt(final Object... keys) {
return get(keys).asInt();
}

@Override
public <T> List<T> getList(final String key, final Class<T> elementClass) {
return get(key).asList(elementClass);
Expand All @@ -336,6 +411,31 @@ public <T> List<T> getList(final AsdfNode key, final Class<T> elementClass) {
return get(key).asList(elementClass);
}

@Override
public <T> List<T> getList(final Class<T> elementClass, final String key) {
return get(key).asList(elementClass);
}

@Override
public <T> List<T> getList(final Class<T> elementClass, final long key) {
return get(key).asList(elementClass);
}

@Override
public <T> List<T> getList(final Class<T> elementClass, final boolean key) {
return get(key).asList(elementClass);
}

@Override
public <T> List<T> getList(final Class<T> elementClass, final AsdfNode key) {
return get(key).asList(elementClass);
}

@Override
public <T> List<T> getList(final Class<T> elementClass, final Object... keys) {
return get(keys).asList(elementClass);
}

@Override
public long getLong(final String key) {
return get(key).asLong();
Expand All @@ -356,6 +456,11 @@ public long getLong(final AsdfNode key) {
return get(key).asLong();
}

@Override
public long getLong(final Object... keys) {
return get(keys).asLong();
}

@Override
public Number getNumber(final String key) {
return get(key).asNumber();
Expand All @@ -376,6 +481,11 @@ public Number getNumber(final AsdfNode key) {
return get(key).asNumber();
}

@Override
public Number getNumber(final Object... keys) {
return get(keys).asNumber();
}

@Override
public <K, V> Map<K, V> getMap(final String key, final Class<K> keyClass, final Class<V> valueClass) {
return get(key).asMap(keyClass, valueClass);
Expand All @@ -396,6 +506,31 @@ public <K, V> Map<K, V> getMap(final AsdfNode key, final Class<K> keyClass, fina
return get(key).asMap(keyClass, valueClass);
}

@Override
public <K, V> Map<K, V> getMap(final Class<K> keyClass, final Class<V> valueClass, final String key) {
return get(key).asMap(keyClass, valueClass);
}

@Override
public <K, V> Map<K, V> getMap(final Class<K> keyClass, final Class<V> valueClass, final long key) {
return get(key).asMap(keyClass, valueClass);
}

@Override
public <K, V> Map<K, V> getMap(final Class<K> keyClass, final Class<V> valueClass, final boolean key) {
return get(key).asMap(keyClass, valueClass);
}

@Override
public <K, V> Map<K, V> getMap(final Class<K> keyClass, final Class<V> valueClass, final AsdfNode key) {
return get(key).asMap(keyClass, valueClass);
}

@Override
public <K, V> Map<K, V> getMap(final Class<K> keyClass, final Class<V> valueClass, final Object... keys) {
return get(keys).asMap(keyClass, valueClass);
}

@Override
public NdArray<?> getNdArray(final String key) {
return get(key).asNdArray();
Expand All @@ -416,6 +551,11 @@ public NdArray<?> getNdArray(final AsdfNode key) {
return get(key).asNdArray();
}

@Override
public NdArray<?> getNdArray(final Object... keys) {
return get(keys).asNdArray();
}

@Override
public short getShort(final String key) {
return get(key).asShort();
Expand All @@ -436,6 +576,11 @@ public short getShort(final AsdfNode key) {
return get(key).asShort();
}

@Override
public short getShort(final Object... keys) {
return get(keys).asShort();
}

@Override
public String getString(final String key) {
return get(key).asString();
Expand All @@ -456,6 +601,11 @@ public String getString(final AsdfNode key) {
return get(key).asString();
}

@Override
public String getString(final Object... keys) {
return get(keys).asString();
}

@Override
public BigDecimal asBigDecimal() {
throw new IllegalStateException(makeAsErrorMessage("BigDecimal"));
Expand Down Expand Up @@ -552,4 +702,18 @@ protected String makeGetErrorMessage(final String keyType) {
protected String makeAsErrorMessage(final String asType) {
return String.format("%s node cannot be represented as %s", getNodeType(), asType);
}

protected AsdfNode constructKeyNode(final Object key) {
if (key instanceof String) {
return StringAsdfNode.of((String)key);
} else if (key instanceof AsdfNode) {
return (AsdfNode)key;
} else if (key instanceof Number) {
return NumberAsdfNode.of((Number)key);
} else if (key instanceof Boolean) {
return BooleanAsdfNode.of((Boolean)key);
} else {
throw new IllegalArgumentException("Unhandled key class: " + key.getClass().getSimpleName());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,9 @@ public BigInteger asBigInteger() {
@Override
public byte asByte() {
if (value instanceof Byte) {
return (Byte)value;
return (Byte) value;
} else if (value instanceof Integer && (int)value >= Byte.MIN_VALUE && (int)value <= Byte.MAX_VALUE) {
return value.byteValue();
} else {
throw new IllegalStateException("Node cannot be represented as byte");
}
Expand Down Expand Up @@ -152,7 +154,9 @@ public Number asNumber() {
public short asShort() {
if (value instanceof Byte || value instanceof Short) {
return value.shortValue();
} else {
} else if (value instanceof Integer && (int)value >= Short.MIN_VALUE && (int)value <= Short.MAX_VALUE) {
return value.shortValue();
}else {
throw new IllegalStateException("Node cannot be represented as short");
}
}
Expand All @@ -162,16 +166,39 @@ public boolean equals(final Object other) {
if (this == other) {
return true;
}
if (other == null || getClass() != other.getClass()) {

if (!(other instanceof NumberAsdfNode)) {
return false;
}

final NumberAsdfNode otherNode = (NumberAsdfNode)other;

if (!Objects.equals(this.tag, otherNode.tag)) {
return false;
}
final NumberAsdfNode typedOther = (NumberAsdfNode) other;
return Objects.equals(tag, typedOther.tag) && Objects.equals(value, typedOther.value);

if (this.value == null || otherNode.value == null) {
return this.value == otherNode.value;
}

if (this.value.getClass() == otherNode.value.getClass() && this.value.equals(otherNode.value)) {
return true;
}

if (isSpecialFloatingPointValue(this.value) || isSpecialFloatingPointValue(otherNode.value)) {
return Double.compare(this.value.doubleValue(), otherNode.value.doubleValue()) == 0;
}

return asBigDecimal().compareTo(otherNode.asBigDecimal()) == 0;
}

@Override
public int hashCode() {
return Objects.hash(tag, value);
if (isSpecialFloatingPointValue(value)) {
return Double.hashCode(value.doubleValue());
}

return asBigDecimal().stripTrailingZeros().hashCode();
}

@Override
Expand All @@ -188,4 +215,9 @@ public String toString() {

return NodeUtils.nodeToString(this, fields);
}

private boolean isSpecialFloatingPointValue(final Number number) {
return (number instanceof Double && (((Double)number).isInfinite() || ((Double)number).isNaN())) ||
(number instanceof Float && (((Float)number).isInfinite() || ((Float)number).isNaN()));
}
}
Loading