Progressed on port from dotnet to java

This commit is contained in:
David Noble
2019-09-10 01:30:06 -07:00
parent d3029f55d2
commit 30c7cb9256
8 changed files with 385 additions and 355 deletions

View File

@@ -16,6 +16,7 @@ import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import it.unimi.dsi.fastutil.ints.Int2ReferenceMap; import it.unimi.dsi.fastutil.ints.Int2ReferenceMap;
import it.unimi.dsi.fastutil.ints.Int2ReferenceOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2ReferenceOpenHashMap;
import javax.annotation.Nonnull;
import java.io.IOException; import java.io.IOException;
import static com.google.common.base.Strings.lenientFormat; import static com.google.common.base.Strings.lenientFormat;
@@ -26,7 +27,7 @@ import static com.google.common.base.Strings.lenientFormat;
*/ */
@JsonDeserialize(using = SchemaId.JsonDeserializer.class) @JsonDeserialize(using = SchemaId.JsonDeserializer.class)
@JsonSerialize(using = SchemaId.JsonSerializer.class) @JsonSerialize(using = SchemaId.JsonSerializer.class)
public final class SchemaId { public final class SchemaId implements Comparable<SchemaId> {
public static final int BYTES = Integer.BYTES; public static final int BYTES = Integer.BYTES;
public static final SchemaId INVALID = null; public static final SchemaId INVALID = null;
@@ -46,9 +47,21 @@ public final class SchemaId {
this.value = value; this.value = value;
} }
@Override
public int compareTo(@Nonnull SchemaId other) {
return Integer.compare(this.value, other.value);
}
@Override @Override
public boolean equals(Object other) { public boolean equals(Object other) {
return other instanceof SchemaId && this.equals((SchemaId) other); if (this == other) {
return true;
}
if (other == null || this.getClass() != other.getClass()) {
return false;
}
SchemaId schemaId = (SchemaId) other;
return this.value == schemaId.value;
} }
/** /**

View File

@@ -20,7 +20,6 @@ import com.azure.data.cosmos.serialization.hybridrow.schemas.TuplePropertyType;
import com.azure.data.cosmos.serialization.hybridrow.schemas.TypeKind; import com.azure.data.cosmos.serialization.hybridrow.schemas.TypeKind;
import com.azure.data.cosmos.serialization.hybridrow.schemas.UdtPropertyType; import com.azure.data.cosmos.serialization.hybridrow.schemas.UdtPropertyType;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import tangible.ListHelper;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.util.List; import java.util.List;
@@ -46,7 +45,7 @@ public final class LayoutCompiler {
checkNotNull(ns, "expected non-null ns"); checkNotNull(ns, "expected non-null ns");
checkNotNull(schema, "expected non-null schema"); checkNotNull(schema, "expected non-null schema");
checkArgument(schema.type() == TypeKind.Schema); checkArgument(schema.type() == TypeKind.SCHEMA);
checkArgument(!Strings.isNullOrEmpty(schema.name())); checkArgument(!Strings.isNullOrEmpty(schema.name()));
checkArgument(ns.schemas().contains(schema)); checkArgument(ns.schemas().contains(schema));
@@ -162,82 +161,82 @@ public final class LayoutCompiler {
switch (logicalType.type()) { switch (logicalType.type()) {
case Null: case NULL:
return LayoutTypes.NULL; return LayoutTypes.NULL;
case Boolean: case BOOLEAN:
return LayoutTypes.BOOLEAN; return LayoutTypes.BOOLEAN;
case Int8: case INT_8:
return LayoutTypes.INT_8; return LayoutTypes.INT_8;
case Int16: case INT_16:
return LayoutTypes.INT_16; return LayoutTypes.INT_16;
case Int32: case INT_32:
return LayoutTypes.INT_32; return LayoutTypes.INT_32;
case Int64: case INT_64:
return LayoutTypes.INT_64; return LayoutTypes.INT_64;
case UInt8: case UINT_8:
return LayoutTypes.UINT_8; return LayoutTypes.UINT_8;
case UInt16: case UINT_16:
return LayoutTypes.UINT_16; return LayoutTypes.UINT_16;
case UInt32: case UINT_32:
return LayoutTypes.UINT_32; return LayoutTypes.UINT_32;
case UInt64: case UINT_64:
return LayoutTypes.UINT_64; return LayoutTypes.UINT_64;
case Float32: case FLOAT_32:
return LayoutTypes.FLOAT_32; return LayoutTypes.FLOAT_32;
case Float64: case FLOAT_64:
return LayoutTypes.FLOAT_64; return LayoutTypes.FLOAT_64;
case Float128: case FLOAT_128:
return LayoutTypes.FLOAT_128; return LayoutTypes.FLOAT_128;
case Decimal: case DECIMAL:
return LayoutTypes.DECIMAL; return LayoutTypes.DECIMAL;
case DateTime: case DATE_TIME:
return LayoutTypes.DATE_TIME; return LayoutTypes.DATE_TIME;
case UnixDateTime: case UNIX_DATE_TIME:
return LayoutTypes.UNIX_DATE_TIME; return LayoutTypes.UNIX_DATE_TIME;
case Guid: case GUID:
return LayoutTypes.GUID; return LayoutTypes.GUID;
case MongoDbObjectId: case MONGODB_OBJECT_ID:
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
// return LayoutTypes.MONGO_DB_OBJECT_ID; // return LayoutTypes.MONGO_DB_OBJECT_ID;
case Utf8: case UTF_8:
return LayoutTypes.UTF_8; return LayoutTypes.UTF_8;
case Binary: case BINARY:
return LayoutTypes.BINARY; return LayoutTypes.BINARY;
case VarInt: case VAR_INT:
return LayoutTypes.VAR_INT; return LayoutTypes.VAR_INT;
case VarUInt: case VAR_UINT:
return LayoutTypes.VAR_UINT; return LayoutTypes.VAR_UINT;
case Object: case OBJECT:
return immutable ? LayoutTypes.IMMUTABLE_OBJECT : LayoutTypes.OBJECT; return immutable ? LayoutTypes.IMMUTABLE_OBJECT : LayoutTypes.OBJECT;
case Array: { case ARRAY: {
assert logicalType instanceof ArrayPropertyType; assert logicalType instanceof ArrayPropertyType;
ArrayPropertyType ap = (ArrayPropertyType) logicalType; ArrayPropertyType ap = (ArrayPropertyType) logicalType;
if (ap.items() != null && (ap.items().type() != TypeKind.Any)) { if (ap.items() != null && (ap.items().type() != TypeKind.ANY)) {
final Out<TypeArgumentList> out = new Out<>(); final Out<TypeArgumentList> out = new Out<>();
@@ -260,7 +259,7 @@ public final class LayoutCompiler {
assert logicalType instanceof SetPropertyType; assert logicalType instanceof SetPropertyType;
SetPropertyType sp = (SetPropertyType) logicalType; SetPropertyType sp = (SetPropertyType) logicalType;
if ((sp.items() != null) && (sp.items().type() != TypeKind.Any)) { if ((sp.items() != null) && (sp.items().type() != TypeKind.ANY)) {
final Out<TypeArgumentList> out = new Out<>(); final Out<TypeArgumentList> out = new Out<>();
@@ -288,7 +287,7 @@ public final class LayoutCompiler {
assert logicalType instanceof MapPropertyType; assert logicalType instanceof MapPropertyType;
MapPropertyType mp = (MapPropertyType) logicalType; MapPropertyType mp = (MapPropertyType) logicalType;
if (mp.keys() != null && (mp.keys().type() != TypeKind.Any) && (mp.values() != null) && (mp.values().type() != TypeKind.Any)) { if (mp.keys() != null && (mp.keys().type() != TypeKind.ANY) && (mp.values() != null) && (mp.values().type() != TypeKind.ANY)) {
final Out<TypeArgumentList> out = new Out<>(); final Out<TypeArgumentList> out = new Out<>();
@@ -322,7 +321,7 @@ public final class LayoutCompiler {
"Unknown property type: %s", logicalType.type()) "Unknown property type: %s", logicalType.type())
); );
} }
case Tuple: { case TUPLE: {
assert logicalType instanceof TuplePropertyType; assert logicalType instanceof TuplePropertyType;
final TuplePropertyType tp = (TuplePropertyType) logicalType; final TuplePropertyType tp = (TuplePropertyType) logicalType;
@@ -389,7 +388,7 @@ public final class LayoutCompiler {
throw new LayoutCompilationException("Unexpected tagged arity"); throw new LayoutCompilationException("Unexpected tagged arity");
} }
} }
case Schema: { case SCHEMA: {
assert logicalType instanceof UdtPropertyType; assert logicalType instanceof UdtPropertyType;
UdtPropertyType up = (UdtPropertyType) logicalType; UdtPropertyType up = (UdtPropertyType) logicalType;

View File

@@ -9,7 +9,7 @@ package com.azure.data.cosmos.serialization.hybridrow.schemas;
* Maps are typed or untyped. Within typed maps, all key MUST be the same type, and all values MUST be the same type. * Maps are typed or untyped. Within typed maps, all key MUST be the same type, and all values MUST be the same type.
* The type of both key and values is specified via {@link #keys} and {@link #values} respectively. Typed maps may be * The type of both key and values is specified via {@link #keys} and {@link #values} respectively. Typed maps may be
* stored more efficiently than untyped maps. When {@link #keys} or {@link #values} is unspecified or marked * stored more efficiently than untyped maps. When {@link #keys} or {@link #values} is unspecified or marked
* {@link TypeKind#Any}, the map is untyped and its key and/or values may be heterogeneous. * {@link TypeKind#ANY}, the map is untyped and its key and/or values may be heterogeneous.
*/ */
public class MapPropertyType extends ScopePropertyType { public class MapPropertyType extends ScopePropertyType {

View File

@@ -25,12 +25,13 @@ public class Namespace {
/** /**
* The fully qualified identifier of the namespace. * The fully qualified identifier of the namespace.
*/ */
public final String getName() { public final String name() {
return this.name; return this.name;
} }
public final void setName(String value) { public final Namespace name(String value) {
this.name = value; this.name = value;
return this;
} }
/** /**

View File

@@ -42,7 +42,7 @@ public class Schema {
* Initializes a new instance of the {@link Schema} class. * Initializes a new instance of the {@link Schema} class.
*/ */
public Schema() { public Schema() {
this.type(TypeKind.Schema); this.type(TypeKind.SCHEMA);
this.properties = Collections.emptyList(); this.properties = Collections.emptyList();
this.partitionKeys = Collections.emptyList(); this.partitionKeys = Collections.emptyList();
this.primaryKeys = Collections.emptyList(); this.primaryKeys = Collections.emptyList();
@@ -209,7 +209,7 @@ public class Schema {
/** /**
* The type of this schema * The type of this schema
* <p> * <p>
* This value MUST be {@link TypeKind#Schema}. * This value MUST be {@link TypeKind#SCHEMA}.
*/ */
public final TypeKind type() { public final TypeKind type() {
return this.type; return this.type;

View File

@@ -3,126 +3,222 @@
package com.azure.data.cosmos.serialization.hybridrow.schemas; package com.azure.data.cosmos.serialization.hybridrow.schemas;
import com.azure.data.cosmos.core.Json;
import com.azure.data.cosmos.serialization.hybridrow.SchemaId; import com.azure.data.cosmos.serialization.hybridrow.SchemaId;
import com.google.common.base.Strings;
import org.checkerframework.checker.nullness.qual.NonNull;
import javax.annotation.Nonnull;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Strings.lenientFormat;
public final class SchemaValidator { public final class SchemaValidator {
HashMap<SchemaId, Schema> ids
HashMap<SchemaId, Schema> ids>schemas,
HashMap<SchemaId, Schema> ids)
HashMap<SchemaId, Schema> ids
{ private static class SchemaIdentification implements Comparable<SchemaIdentification> {
for (Schema s : ns.getSchemas()) {
SchemaValidator.Visit(s, schemas, ids);
}
}>schemas,
{ private final SchemaId id;
ValidateAssert.AreEqual(s.getType(), TypeKind.Schema, String.format("The type of a schema MUST be %1$s: %2$s" private final String name;
, TypeKind.Schema, s.getType()));
HashMap<String, Property> pathDupCheck = new HashMap<String, Property>(s.getProperties().size()); private SchemaIdentification(@Nonnull final String name, @Nonnull final SchemaId id) {
for (Property p : s.getProperties()) { checkNotNull(name, "expected non-null name");
ValidateAssert.DuplicateCheck(p.path(), p, pathDupCheck, "Property path", "Schema"); checkNotNull(id, "expected non-null id");
this.name = name;
this.id = id;
} }
for (PartitionKey pk : s.getPartitionKeys()) { @Override
ValidateAssert.Exists(pk.path(), pathDupCheck, "Partition key column", "Schema"); public int compareTo(@Nonnull SchemaIdentification other) {
checkNotNull(other, "expected non-null other");
int result = Integer.compare(this.id.value(), other.id.value());
return result == 0 ? this.name().compareTo(other.name()) : result;
} }
for (PrimarySortKey ps : s.getPrimarySortKeys()) { @Override
ValidateAssert.Exists(ps.path(), pathDupCheck, "Primary sort key column", "Schema"); public boolean equals(Object other) {
if (this == other) {
return true;
}
if (null == other || this.getClass() != other.getClass()) {
return false;
}
SchemaIdentification that = (SchemaIdentification) other;
return this.id.equals(that.id) && this.name.equals(that.name);
} }
for (StaticKey sk : s.getStaticKeys()) { @Override
ValidateAssert.Exists(sk.path(), pathDupCheck, "Static key column", "Schema"); public int hashCode() {
return Objects.hash(this.id, this.name);
} }
for (Property p : s.getProperties()) { public SchemaId id() {
SchemaValidator.Visit(p, s, schemas, ids); return this.id;
} }
})
{ public String name() {
ValidateAssert.IsValidIdentifier(p.getPath(), "Property path"); return this.name;
SchemaValidator.Visit(p.getPropertyType(), null, schemas, ids); }
@Override
public String toString() {
return Json.toString(this);
}
public static SchemaIdentification of(@NonNull String name, @NonNull SchemaId id) {
return new SchemaIdentification(name, id);
}
} }
public static void Validate(@NonNull final Namespace namespace) {
checkNotNull(namespace, "expected non-null namespace");
final int initialCapacity = namespace.schemas().size();
final Map<SchemaIdentification, Schema> nameDupCheck = new HashMap<>(initialCapacity);
final Map<String, Integer> nameVersioningCheck = new HashMap<>(initialCapacity);
final Map<SchemaId, Schema> idDupCheck = new HashMap<>(initialCapacity);
for (Schema schema : namespace.schemas()) {
SchemaIdentification identification = SchemaIdentification.of(schema.name(), schema.schemaId());
Assert.isValidIdentifier(identification.name(), "Schema name");
Assert.isValidSchemaId(identification.id(), "Schema id");
Assert.duplicateCheck(identification.id(), schema, idDupCheck, "Schema id", "Namespace");
Assert.duplicateCheck(identification, schema, nameDupCheck, "Schema reference", "Namespace");
// Count the versions of each schema by name.
nameVersioningCheck.TryGetValue(schema.name(), out int count);
nameVersioningCheck.put(schema.name(), count + 1);
}
// Enable id-less Schema references for all types with a unique version in the namespace
for (Schema schema : namespace.schemas()) {
if (nameVersioningCheck.get(schema.name()) == 1) {
Assert.duplicateCheck(SchemaIdentification.of(schema.name(), SchemaId.INVALID), schema, nameDupCheck, "Schema reference", "Namespace");
}
}
SchemaValidator.visit(namespace, nameDupCheck, idDupCheck);
}
/// <summary>Visit an entire namespace and validate its constraints.</summary>
/// <param name="ns">The <see cref="Namespace" /> to validate.</param>
/// <param name="schemas">A map from schema names within the namespace to their schemas.</param>
/// <param name="ids">A map from schema ids within the namespace to their schemas.</param>
private static void visit(Namespace ns, Map<SchemaIdentification, Schema> schemas, Map<SchemaId, Schema> ids) {
for (Schema schema : ns.schemas()) {
SchemaValidator.visit(schema, schemas, ids);
}
}
/// <summary>Visit a single schema and validate its constraints.</summary>
/// <param name="schema">The <see cref="Schema" /> to validate.</param>
/// <param name="schemas">A map from schema names within the namespace to their schemas.</param>
/// <param name="ids">A map from schema ids within the namespace to their schemas.</param>
private static void visit(Schema schema, Map<SchemaIdentification, Schema> schemas, Map<SchemaId, Schema> ids) {
Assert.areEqual(
schema.type(), TypeKind.SCHEMA, lenientFormat("The type of a schema MUST be %s: %s", TypeKind.SCHEMA, schema.type())
);
HashMap<String, Property> pathDupCheck = new HashMap<>(schema.properties().size());
for (Property p : schema.properties()) {
Assert.duplicateCheck(p.path(), p, pathDupCheck, "Property path", "Schema");
}
for (PartitionKey pk : schema.partitionKeys()) {
Assert.exists(pk.path(), pathDupCheck, "Partition key column", "Schema");
}
for (PrimarySortKey ps : schema.primarySortKeys()) {
Assert.exists(ps.path(), pathDupCheck, "Primary sort key column", "Schema");
}
for (StaticKey sk : schema.staticKeys()) {
Assert.exists(sk.path(), pathDupCheck, "Static key column", "Schema");
}
for (Property p : schema.properties()) {
SchemaValidator.visit(p, schema, schemas, ids);
}
}
private static void visit(
Property p, Schema s, Map<SchemaIdentification, Schema> schemas, Map<SchemaId, Schema> ids) {
Assert.isValidIdentifier(p.path(), "Property path");
SchemaValidator.visit(p.propertyType(), null, schemas, ids);
}
private static void visit(
PropertyType p,
PropertyType parent,
Map<SchemaIdentification, Schema> schemas,
Map<SchemaId, Schema> ids)
{
switch (p)
{ {
switch (p) { case PrimitivePropertyType pp:
// TODO: C# TO JAVA CONVERTER: Java has no equivalent to C# pattern variables in 'case' statements: Assert.isTrue(pp.Length >= 0, "Length MUST be positive");
//ORIGINAL LINE: case PrimitivePropertyType pp: if (parent != null)
case PrimitivePropertyType {
pp: Assert.areEqual(pp.Storage, StorageKind.Sparse, $"Nested fields MUST have storage {StorageKind.Sparse}");
ValidateAssert.IsTrue(pp.Length >= 0, "Length MUST be positive");
if (parent != null) {
ValidateAssert.AreEqual(pp.Storage, StorageKind.SPARSE, String.format("Nested fields MUST have " +
"storage %1$s", StorageKind.SPARSE));
} }
break; break;
// TODO: C# TO JAVA CONVERTER: Java has no equivalent to C# pattern variables in 'case' statements: case ArrayPropertyType ap:
//ORIGINAL LINE: case ArrayPropertyType ap: if (ap.Items != null)
case ArrayPropertyType {
ap: SchemaValidator.visit(ap.Items, p, schemas, ids);
if (ap.Items != null) { }
SchemaValidator.Visit(ap.Items, p, schemas, ids);
}
break; break;
// TODO: C# TO JAVA CONVERTER: Java has no equivalent to C# pattern variables in 'case' statements: case MapPropertyType mp:
//ORIGINAL LINE: case MapPropertyType mp: SchemaValidator.visit(mp.Keys, p, schemas, ids);
case MapPropertyType SchemaValidator.visit(mp.Values, p, schemas, ids);
mp:
SchemaValidator.Visit(mp.keySet(), p, schemas, ids);
SchemaValidator.Visit(mp.Values, p, schemas, ids);
break; break;
// TODO: C# TO JAVA CONVERTER: Java has no equivalent to C# pattern variables in 'case' statements: case SetPropertyType sp:
//ORIGINAL LINE: case SetPropertyType sp: SchemaValidator.visit(sp.Items, p, schemas, ids);
case SetPropertyType
sp:
SchemaValidator.Visit(sp.Items, p, schemas, ids);
break; break;
// TODO: C# TO JAVA CONVERTER: Java has no equivalent to C# pattern variables in 'case' statements: case TaggedPropertyType gp:
//ORIGINAL LINE: case TaggedPropertyType gp: for (PropertyType item : gp.Items)
case TaggedPropertyType {
gp: SchemaValidator.visit(item, p, schemas, ids);
for (PropertyType item : gp.Items) { }
SchemaValidator.Visit(item, p, schemas, ids);
}
break; break;
// TODO: C# TO JAVA CONVERTER: Java has no equivalent to C# pattern variables in 'case' statements: case TuplePropertyType tp:
//ORIGINAL LINE: case TuplePropertyType tp: for (PropertyType item : tp.Items)
case TuplePropertyType {
tp: SchemaValidator.visit(item, p, schemas, ids);
for (PropertyType item : tp.Items) { }
SchemaValidator.Visit(item, p, schemas, ids);
}
break; break;
// TODO: C# TO JAVA CONVERTER: Java has no equivalent to C# pattern variables in 'case' statements: case ObjectPropertyType op:
//ORIGINAL LINE: case ObjectPropertyType op: Map<String, Property> pathDupCheck = new HashMap<>(op.Properties.Count);
case ObjectPropertyType for (Property nested : op.Properties)
op: {
HashMap<String, Property> pathDupCheck = new HashMap<String, Property>(op.Properties.Count); Assert.duplicateCheck(nested.path(), nested, pathDupCheck, "Property path", "Object");
for (Property nested : op.Properties) { SchemaValidator.visit(nested.propertyType(), p, schemas, ids);
ValidateAssert.DuplicateCheck(nested.path(), nested, pathDupCheck, "Property path", "Object"); }
SchemaValidator.Visit(nested.propertyType(), p, schemas, ids);
}
break; break;
// TODO: C# TO JAVA CONVERTER: Java has no equivalent to C# pattern variables in 'case' statements: case UdtPropertyType up:
//ORIGINAL LINE: case UdtPropertyType up: Assert.exists((up.Name, up.SchemaId), schemas, "Schema reference", "Namespace");
case UdtPropertyType if (up.SchemaId != SchemaId.Invalid)
up: {
ValidateAssert.Exists((up.Name, up.SchemaId), schemas, "Schema reference", "Namespace") Schema s = Assert.exists(up.SchemaId, ids, "Schema id", "Namespace");
if (SchemaId.opNotEquals(up.SchemaId, Assert.areEqual(
SchemaId.INVALID)) { up.Name,
Schema s = ValidateAssert.Exists(up.SchemaId, ids, "Schema id", "Namespace"); s.Name,
ValidateAssert.AreEqual(up.Name, s.name(), String.format("Schema name '%1$s' does not match " + $"Schema name '{up.Name}' does not match the name of schema with id '{up.SchemaId}': {s.Name}");
"the name of schema with id '%2$s': %3$s", up.Name, up.SchemaId, s.name()));
} }
break; break;
@@ -130,146 +226,79 @@ HashMap<SchemaId, Schema> ids
Contract.Fail("Unknown property type"); Contract.Fail("Unknown property type");
break; break;
} }
}>schemas, }
public static void Validate(Namespace ns) { private static class Assert {
HashMap<String, Integer> nameVersioningCheck = new HashMap<String, Integer>(ns.schemas().size());
HashMap< (String, SchemaId),
Schema > nameDupCheck = new HashMap<(String, SchemaId), Schema > (ns.schemas().size());
HashMap<SchemaId, Schema> idDupCheck = new HashMap<SchemaId, Schema>(ns.schemas().size());
for (Schema s : ns.schemas()) {
ValidateAssert.IsValidSchemaId(s.schemaId().clone(), "Schema id");
ValidateAssert.IsValidIdentifier(s.name(), "Schema name");
ValidateAssert.DuplicateCheck(s.schemaId().clone(), s, idDupCheck, "Schema id", "Namespace");
ValidateAssert.DuplicateCheck((s.name(), s.schemaId().clone()), s, nameDupCheck, "Schema reference"
, "Namespace")
// Count the versions of each schema by name. /// <summary>Validate <paramref name="key" /> does not already appear within the given scope.</summary>
int count; /// <typeparam name="TKey">The type of the keys within the scope.</typeparam>
count = nameVersioningCheck.get(s.name()); /// <typeparam name="TValue">The type of the values within the scope.</typeparam>
nameVersioningCheck.put(s.name(), count + 1); /// <param name="key">The key to check.</param>
} /// <param name="value">The value to add to the scope if there is no duplicate.</param>
/// <param name="scope">The set of existing values within the scope.</param>
// Enable id-less Schema references for all types with a unique version in the namespace. /// <param name="label">Diagnostic label describing <paramref name="key" />.</param>
for (Schema s : ns.schemas()) { /// <param name="scopeLabel">Diagnostic label describing <paramref name="scope" />.</param>
if (nameVersioningCheck.get(s.name()).equals(1)) { static <TKey, TValue> void duplicateCheck(
ValidateAssert.DuplicateCheck((s.name(), SchemaId.INVALID), s, nameDupCheck, "Schema reference", TKey key, TValue value, Map<TKey, TValue> scope, String label, String scopeLabel) {
"Namespace") if (scope.containsKey(key)) {
throw new SchemaException(lenientFormat("%s must be unique within a %s: %s", label, scopeLabel, key));
} }
scope.put(key, value);
} }
SchemaValidator.Visit(ns, nameDupCheck, idDupCheck); /// <summary>Validate <paramref name="key" /> does appear within the given scope.</summary>
}) /// <typeparam name="TKey">The type of the keys within the scope.</typeparam>
/// <typeparam name="TValue">The type of the values within the scope.</typeparam>
/// <param name="key">The key to check.</param>
/// <param name="scope">The set of existing values within the scope.</param>
/// <param name="label">Diagnostic label describing <paramref name="key" />.</param>
/// <param name="scopeLabel">Diagnostic label describing <paramref name="scope" />.</param>
static <TKey, TValue> TValue exists(TKey key, Map<TKey, TValue> scope, String label, String scopeLabel) {
TValue value = scope.get(key);
if (value == null) {
throw new SchemaException(lenientFormat("%s must exist within a %s: %s", label, scopeLabel, key));
}
return value;
}
/** /// <summary>Validate two values are equal.</summary>
* Visit an entire namespace and validate its constraints. /// <typeparam name="T">Type of the values to compare.</typeparam>
* /// <param name="left">The left value to compare.</param>
* @param ns The {@link Namespace} to validate. /// <param name="right">The right value to compare.</param>
* @param schemas A map from schema names within the namespace to their schemas. /// <param name="message">Diagnostic message if the comparison fails.</param>
* @param ids A map from schema ids within the namespace to their schemas. static <T> void areEqual(T left, T right, String message) {
*/
private static void Visit(Namespace ns, HashMap<(String, SchemaId),Schema
/**
* Visit a single schema and validate its constraints.
*
* @param s The {@link Schema} to validate.
* @param schemas A map from schema names within the namespace to their schemas.
* @param ids A map from schema ids within the namespace to their schemas.
*/
private static void Visit(Schema s, HashMap<(String, SchemaId),Schema>schemas,
private static void Visit(Property p, Schema s, HashMap<(String, SchemaId),Schema)
private static void Visit(PropertyType p, PropertyType parent, HashMap<(String, SchemaId),Schema
private static class ValidateAssert {
/**
* Validate two values are equal.
* <typeparam name="T">Type of the values to compare.</typeparam>
*
* @param left The left value to compare.
* @param right The right value to compare.
* @param message Diagnostic message if the comparison fails.
*/
public static <T> void AreEqual(T left, T right, String message) {
if (!left.equals(right)) { if (!left.equals(right)) {
throw new SchemaException(message); throw new SchemaException(message);
} }
} }
/** /// <summary>Validate a predicate is true.</summary>
* Validate <paramref name="key" /> does not already appear within the given scope. /// <param name="predicate">The predicate to check.</param>
* <typeparam name="TKey">The type of the keys within the scope.</typeparam> /// <param name="message">Diagnostic message if the comparison fails.</param>
* <typeparam name="TValue">The type of the values within the scope.</typeparam> static void isTrue(boolean predicate, String message) {
*
* @param key The key to check.
* @param value The value to add to the scope if there is no duplicate.
* @param scope The set of existing values within the scope.
* @param label Diagnostic label describing <paramref name="key" />.
* @param scopeLabel Diagnostic label describing <paramref name="scope" />.
*/
public static <TKey, TValue> void DuplicateCheck(TKey key, TValue value, HashMap<TKey, TValue> scope, String label, String scopeLabel) {
if (scope.containsKey(key)) {
throw new SchemaException(String.format("%1$s must be unique within a %2$s: %3$s", label, scopeLabel, key));
}
scope.put(key, value);
}
/**
* Validate <paramref name="key" /> does appear within the given scope.
* <typeparam name="TKey">The type of the keys within the scope.</typeparam>
* <typeparam name="TValue">The type of the values within the scope.</typeparam>
*
* @param key The key to check.
* @param scope The set of existing values within the scope.
* @param label Diagnostic label describing <paramref name="key" />.
* @param scopeLabel Diagnostic label describing <paramref name="scope" />.
*/
public static <TKey, TValue> TValue Exists(TKey key, HashMap<TKey, TValue> scope, String label, String scopeLabel) {
TValue value;
if (!(scope.containsKey(key) && (value = scope.get(key)) == value)) {
throw new SchemaException(String.format("%1$s must exist within a %2$s: %3$s", label, scopeLabel, key));
}
return value;
}
/**
* Validate a predicate is true.
*
* @param predicate The predicate to check.
* @param message Diagnostic message if the comparison fails.
*/
public static void IsTrue(boolean predicate, String message) {
if (!predicate) { if (!predicate) {
throw new SchemaException(message); throw new SchemaException(message);
} }
} }
/** /// <summary>
* Validate <paramref name="identifier" /> contains only characters valid in a schema /// Validate <paramref name="identifier" /> contains only characters valid in a schema
* identifier. /// identifier.
* /// </summary>
* @param identifier The identifier to check. /// <param name="identifier">The identifier to check.</param>
* @param label Diagnostic label describing <paramref name="identifier" />. /// <param name="label">Diagnostic label describing <paramref name="identifier" />.</param>
*/ static void isValidIdentifier(String identifier, String label) {
public static void IsValidIdentifier(String identifier, String label) { if (Strings.isNullOrEmpty(identifier)) {
if (tangible.StringHelper.isNullOrWhiteSpace(identifier)) { throw new SchemaException(lenientFormat("%s must be a valid identifier: %s", label, identifier));
throw new SchemaException(String.format("%1$s must be a valid identifier: %2$s", label, identifier));
} }
} }
/** /// <summary>Validate <paramref name="id" /> is a valid <see cref="SchemaId" />.</summary>
* Validate <paramref name="id" /> is a valid {@link SchemaId}. /// <param name="id">The id to check.</param>
* /// <param name="label">Diagnostic label describing <paramref name="id" />.</param>
* @param id The id to check. static void isValidSchemaId(SchemaId id, String label) {
* @param label Diagnostic label describing <paramref name="id" />. if (id == SchemaId.INVALID) {
*/ throw new SchemaException(lenientFormat("%s cannot be 0", label));
public static void IsValidSchemaId(SchemaId id, String label) {
if (SchemaId.opEquals(id.clone(), SchemaId.INVALID)) {
throw new SchemaException(String.format("%1$s cannot be 0", label));
} }
} }
} }

View File

@@ -3,166 +3,150 @@
package com.azure.data.cosmos.serialization.hybridrow.schemas; package com.azure.data.cosmos.serialization.hybridrow.schemas;
// TODO: DANOBLE: Fixup JSON-serialized naming for agreement with the dotnet code
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
/** /**
* Describes the logical type of a property. * Describes the logical type of a property.
*/ */
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes:
//ORIGINAL LINE: [JsonConverter(typeof(StringEnumConverter), true)] public enum TypeKind
public enum TypeKind { public enum TypeKind {
/** /**
* Reserved. * Reserved.
*/ */
Invalid(0), INVALID(0),
/** /**
* The literal null. * The literal null.
* <p> * <p>
* When used as a fixed column, only a presence bit is allocated. When used as a sparse * When used as a fixed column, only a presence bit is allocated. When used as a sparse column, a sparse value with
* column, a sparse value with 0-length payload is written. * 0-length payload is written.
*/ */
Null(1), NULL(1),
/** /**
* A boolean property. Boolean properties are allocated a single bit when schematized within * A boolean property.
* a row. * <p>
* Boolean properties are allocated a single bit when schematized within a row.
*/ */
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: BOOLEAN(2),
//ORIGINAL LINE: [EnumMember(Value = "bool")] Boolean,
Boolean(2),
/** /**
* 8-bit signed integer. * 8-bit signed integer.
*/ */
Int8(3), INT_8(3),
/** /**
* 16-bit signed integer. * 16-bit signed integer.
*/ */
Int16(4), INT_16(4),
/** /**
* 32-bit signed integer. * 32-bit signed integer.
*/ */
Int32(5), INT_32(5),
/** /**
* 64-bit signed integer. * 64-bit signed integer.
*/ */
Int64(6), INT_64(6),
/** /**
* 8-bit unsigned integer. * 8-bit unsigned integer.
*/ */
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: UINT_8(7),
//ORIGINAL LINE: [EnumMember(Value = "uint8")] UInt8,
UInt8(7),
/** /**
* 16-bit unsigned integer. * 16-bit unsigned integer.
*/ */
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: UINT_16(8),
//ORIGINAL LINE: [EnumMember(Value = "uint16")] UInt16,
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
//ORIGINAL LINE: [EnumMember(Value = "uint16")] UInt16,
UInt16(8),
/** /**
* 32-bit unsigned integer. * 32-bit unsigned integer.
*/ */
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: UINT_32(9),
//ORIGINAL LINE: [EnumMember(Value = "uint32")] UInt32,
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
//ORIGINAL LINE: [EnumMember(Value = "uint32")] UInt32,
UInt32(9),
/** /**
* 64-bit unsigned integer. * 64-bit unsigned integer.
*/ */
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: UINT_64(10),
//ORIGINAL LINE: [EnumMember(Value = "uint64")] UInt64,
//C# TO JAVA CONVERTER WARNING: Unsigned integer types have no direct equivalent in Java:
//ORIGINAL LINE: [EnumMember(Value = "uint64")] UInt64,
UInt64(10),
/** /**
* Variable length encoded signed integer. * Variable length encoded signed integer.
*/ */
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: VAR_INT(11),
//ORIGINAL LINE: [EnumMember(Value = "varint")] VarInt,
VarInt(11),
/** /**
* Variable length encoded unsigned integer. * Variable length encoded unsigned integer.
*/ */
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: VAR_UINT(12),
//ORIGINAL LINE: [EnumMember(Value = "varuint")] VarUInt,
VarUInt(12),
/** /**
* 32-bit IEEE 754 floating point value. * 32-bit IEEE 754 floating point value.
*/ */
Float32(13), FLOAT_32(13),
/** /**
* 64-bit IEEE 754 floating point value. * 64-bit IEEE 754 floating point value.
*/ */
Float64(14), FLOAT_64(14),
/** /**
* 128-bit IEEE 754-2008 floating point value. * 128-bit IEEE 754-2008 floating point value.
*/ */
Float128(15), FLOAT_128(15),
/** /**
* 128-bit floating point value. See {@link decimal} * 128-bit floating point value.
*
* @see java.math.BigDecimal
*/ */
Decimal(16), DECIMAL(16),
/** /**
* 64-bit date/time value in 100ns increments from C# epoch. See {@link System.DateTime} * 64-bit date/time value in 100ns increments from C# epoch.
*
* @see java.time.OffsetDateTime
*/ */
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: DATE_TIME(17),
//ORIGINAL LINE: [EnumMember(Value = "datetime")] DateTime,
DateTime(17),
/** /**
* 64-bit date/time value in milliseconds increments from Unix epoch. See {@link UnixDateTime} * 64-bit date/time value in milliseconds increments from Unix epoch.
*
* @see com.azure.data.cosmos.serialization.hybridrow.UnixDateTime
*/ */
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: UNIX_DATE_TIME(18),
//ORIGINAL LINE: [EnumMember(Value = "unixdatetime")] UnixDateTime,
UnixDateTime(18),
/** /**
* 128-bit globally unique identifier (in little-endian byte order). * 128-bit globally unique identifier (in little-endian byte order).
*/ */
Guid(19), GUID(19),
/** /**
* 12-byte MongoDB Object Identifier (in little-endian byte order). * 12-byte MongoDB Object Identifier (in little-endian byte order).
*/ */
// TODO: C# TO JAVA CONVERTER: Java annotations will not correspond to .NET attributes: MONGODB_OBJECT_ID(20),
//ORIGINAL LINE: [EnumMember(Value = "mongodbobjectid")] MongoDbObjectId,
MongoDbObjectId(20),
/** /**
* Zero to MAX_ROW_SIZE bytes encoded as UTF-8 code points. * Zero to MAX_ROW_SIZE bytes encoded as UTF-8 code points.
*/ */
Utf8(21), UTF_8(21),
/** /**
* Zero to MAX_ROW_SIZE untyped bytes. * Zero to MAX_ROW_SIZE untyped bytes.
*/ */
Binary(22), BINARY(22),
/** /**
* An object property. * An object property.
*/ */
Object(23), OBJECT(23),
/** /**
* An array property, either typed or untyped. * An array property, either typed or untyped.
*/ */
Array(24), ARRAY(24),
/** /**
* A set property, either typed or untyped. * A set property, either typed or untyped.
@@ -177,47 +161,51 @@ public enum TypeKind {
/** /**
* A tuple property. Tuples are typed, finite, ordered, sets. * A tuple property. Tuples are typed, finite, ordered, sets.
*/ */
Tuple(27), TUPLE(27),
/** /**
* A tagged property. Tagged properties pair one or more typed values with an API-specific uint8 type code. * A tagged property.
* <p>
* Tagged properties pair one or more typed values with an API-specific uint8 type code.
*/ */
TAGGED(28), TAGGED(28),
/** /**
* A row with schema. * A row with schema.
* <p>
* May define either a top-level table schema or a UDT (nested row). * May define either a top-level table schema or a UDT (nested row).
*/ */
Schema(29), SCHEMA(29),
/** /**
* An untyped sparse field. * An untyped sparse field.
* May only be used to define the type within a nested scope (e.g. {@link Object} or {@link Array}. * <p>
* May only be used to define the type within a nested scope.
*/ */
Any(30); ANY(30);
public static final int SIZE = java.lang.Integer.SIZE; public static final int BYTES = Integer.BYTES;
private static java.util.HashMap<Integer, TypeKind> mappings; private static Int2ObjectMap<TypeKind> mappings;
private int intValue; private int value;
TypeKind(int value) { TypeKind(int value) {
intValue = value; this.value = value;
getMappings().put(value, this); mappings().put(value, this);
} }
public int getValue() { public int value() {
return intValue; return this.value;
} }
public static TypeKind forValue(int value) { public static TypeKind from(int value) {
return getMappings().get(value); return mappings().get(value);
} }
private static java.util.HashMap<Integer, TypeKind> getMappings() { private static Int2ObjectMap<TypeKind> mappings() {
if (mappings == null) { if (mappings == null) {
synchronized (TypeKind.class) { synchronized (TypeKind.class) {
if (mappings == null) { if (mappings == null) {
mappings = new java.util.HashMap<Integer, TypeKind>(); mappings = new Int2ObjectOpenHashMap<>();
} }
} }
} }

View File

@@ -84,7 +84,7 @@ public class SchemaUnitTests {
Assert.AreEqual(1, n1.getSchemas().size(), "Json: {0}", json); Assert.AreEqual(1, n1.getSchemas().size(), "Json: {0}", json);
Assert.AreEqual("emptyTable", n1.getSchemas().get(0).getName(), "Json: {0}", json); Assert.AreEqual("emptyTable", n1.getSchemas().get(0).getName(), "Json: {0}", json);
Assert.AreEqual(new SchemaId(-1), n1.getSchemas().get(0).getSchemaId().clone(), "Json: {0}", json); Assert.AreEqual(new SchemaId(-1), n1.getSchemas().get(0).getSchemaId().clone(), "Json: {0}", json);
Assert.AreEqual(TypeKind.Schema, n1.getSchemas().get(0).getType(), "Json: {0}", json); Assert.AreEqual(TypeKind.SCHEMA, n1.getSchemas().get(0).getType(), "Json: {0}", json);
Assert.AreEqual(true, n1.getSchemas().get(0).getOptions().getDisallowUnschematized(), "Json: {0}", json); Assert.AreEqual(true, n1.getSchemas().get(0).getOptions().getDisallowUnschematized(), "Json: {0}", json);
Assert.IsNotNull(n1.getSchemas().get(0).getProperties().size(), "Json: {0}", json); Assert.IsNotNull(n1.getSchemas().get(0).getProperties().size(), "Json: {0}", json);
Assert.AreEqual(0, n1.getSchemas().get(0).getProperties().size(), "Json: {0}", json); Assert.AreEqual(0, n1.getSchemas().get(0).getProperties().size(), "Json: {0}", json);
@@ -106,7 +106,7 @@ public class SchemaUnitTests {
Assert.AreEqual(1, n1.getSchemas().size(), "Json: {0}", json); Assert.AreEqual(1, n1.getSchemas().size(), "Json: {0}", json);
Assert.AreEqual("myUDT", n1.getSchemas().get(0).getName(), "Json: {0}", json); Assert.AreEqual("myUDT", n1.getSchemas().get(0).getName(), "Json: {0}", json);
Assert.AreEqual(new SchemaId(1), n1.getSchemas().get(0).getSchemaId().clone(), "Json: {0}", json); Assert.AreEqual(new SchemaId(1), n1.getSchemas().get(0).getSchemaId().clone(), "Json: {0}", json);
Assert.AreEqual(TypeKind.Schema, n1.getSchemas().get(0).getType(), "Json: {0}", json); Assert.AreEqual(TypeKind.SCHEMA, n1.getSchemas().get(0).getType(), "Json: {0}", json);
Assert.AreEqual(false, n1.getSchemas().get(0).getOptions().getDisallowUnschematized(), "Json: {0}", json); Assert.AreEqual(false, n1.getSchemas().get(0).getOptions().getDisallowUnschematized(), "Json: {0}", json);
Assert.AreEqual(2, n1.getSchemas().get(0).getProperties().size(), "Json: {0}", json); Assert.AreEqual(2, n1.getSchemas().get(0).getProperties().size(), "Json: {0}", json);
@@ -136,8 +136,8 @@ public class SchemaUnitTests {
Storage = _Storage; Storage = _Storage;
} }
} }
Object[] expectedProps = new Object[] { AnonymousType("a", TypeKind.Int8, StorageKind.FIXED), Object[] expectedProps = new Object[] { AnonymousType("a", TypeKind.INT_8, StorageKind.FIXED),
AnonymousType2("b", TypeKind.Utf8, StorageKind.VARIABLE) }; AnonymousType2("b", TypeKind.UTF_8, StorageKind.VARIABLE) };
for (int i = 0; i < n1.getSchemas().get(0).getProperties().size(); i++) { for (int i = 0; i < n1.getSchemas().get(0).getProperties().size(); i++) {
Property p = n1.getSchemas().get(0).getProperties().get(i); Property p = n1.getSchemas().get(0).getProperties().get(i);
@@ -448,27 +448,27 @@ public class SchemaUnitTests {
} }
} }
// TODO: C# TO JAVA CONVERTER: There is no Java equivalent to the C# 'dynamic' keyword: // TODO: C# TO JAVA CONVERTER: There is no Java equivalent to the C# 'dynamic' keyword:
dynamic[] expectedSchemas = { AnonymousType("{'type': 'bool', 'storage': 'fixed'}", TypeKind.Boolean), dynamic[] expectedSchemas = { AnonymousType("{'type': 'bool', 'storage': 'fixed'}", TypeKind.BOOLEAN),
AnonymousType2("{'type': 'int8', 'storage': 'fixed'}", TypeKind.Int8), AnonymousType3("{'type': 'int16', " + AnonymousType2("{'type': 'int8', 'storage': 'fixed'}", TypeKind.INT_8), AnonymousType3("{'type': 'int16', " +
"'storage': 'fixed'}", TypeKind.Int16), AnonymousType4("{'type': 'int32', 'storage': 'fixed'}", "'storage': 'fixed'}", TypeKind.INT_16), AnonymousType4("{'type': 'int32', 'storage': 'fixed'}",
TypeKind.Int32), AnonymousType5("{'type': 'int64', 'storage': 'fixed'}", TypeKind.Int64), AnonymousType6( TypeKind.INT_32), AnonymousType5("{'type': 'int64', 'storage': 'fixed'}", TypeKind.INT_64), AnonymousType6(
"{'type': 'uint8', 'storage': 'fixed'}", TypeKind.UInt8), AnonymousType7("{'type': 'uint16', " + "{'type': 'uint8', 'storage': 'fixed'}", TypeKind.UINT_8), AnonymousType7("{'type': 'uint16', " +
"'storage': 'fixed'}", TypeKind.UInt16), AnonymousType8("{'type': 'uint32', 'storage': 'fixed'}", "'storage': 'fixed'}", TypeKind.UINT_16), AnonymousType8("{'type': 'uint32', 'storage': 'fixed'}",
TypeKind.UInt32), AnonymousType9("{'type': 'uint64', 'storage': 'fixed'}", TypeKind.UInt64), TypeKind.UINT_32), AnonymousType9("{'type': 'uint64', 'storage': 'fixed'}", TypeKind.UINT_64),
AnonymousType10("{'type': 'float32', 'storage': 'fixed'}", TypeKind.Float32), AnonymousType11("{'type': " + AnonymousType10("{'type': 'float32', 'storage': 'fixed'}", TypeKind.FLOAT_32), AnonymousType11("{'type': " +
"'float64', 'storage': 'fixed'}", TypeKind.Float64), AnonymousType12("{'type': 'float128', 'storage': " + "'float64', 'storage': 'fixed'}", TypeKind.FLOAT_64), AnonymousType12("{'type': 'float128', 'storage': " +
"'fixed'}", TypeKind.Float128), AnonymousType13("{'type': 'decimal', 'storage': 'fixed'}", "'fixed'}", TypeKind.FLOAT_128), AnonymousType13("{'type': 'decimal', 'storage': 'fixed'}",
TypeKind.Decimal), AnonymousType14("{'type': 'datetime', 'storage': 'fixed'}", TypeKind.DateTime), TypeKind.DECIMAL), AnonymousType14("{'type': 'datetime', 'storage': 'fixed'}", TypeKind.DATE_TIME),
AnonymousType15("{'type': 'unixdatetime', 'storage': 'fixed'}", TypeKind.UnixDateTime), AnonymousType16( AnonymousType15("{'type': 'unixdatetime', 'storage': 'fixed'}", TypeKind.UNIX_DATE_TIME), AnonymousType16(
"{'type': 'guid', 'storage': 'fixed'}", TypeKind.Guid), AnonymousType17("{'type': 'mongodbobjectid', " + "{'type': 'guid', 'storage': 'fixed'}", TypeKind.GUID), AnonymousType17("{'type': 'mongodbobjectid', " +
"'storage': 'fixed'}", TypeKind.MongoDbObjectId), AnonymousType18("{'type': 'varint', 'storage': " + "'storage': 'fixed'}", TypeKind.MONGODB_OBJECT_ID), AnonymousType18("{'type': 'varint', 'storage': " +
"'variable'}", TypeKind.VarInt), AnonymousType19("{'type': 'varuint', 'storage': 'variable'}", "'variable'}", TypeKind.VAR_INT), AnonymousType19("{'type': 'varuint', 'storage': 'variable'}",
TypeKind.VarUInt), AnonymousType20("{'type': 'utf8', 'storage': 'fixed', 'length': 2}", TypeKind.Utf8, 2) TypeKind.VAR_UINT), AnonymousType20("{'type': 'utf8', 'storage': 'fixed', 'length': 2}", TypeKind.UTF_8, 2)
, AnonymousType21("{'type': 'binary', 'storage': 'fixed', 'length': 2}", TypeKind.Binary, 2), , AnonymousType21("{'type': 'binary', 'storage': 'fixed', 'length': 2}", TypeKind.BINARY, 2),
AnonymousType22("{'type': 'utf8', 'storage': 'variable', 'length': 100}", TypeKind.Utf8, 100), AnonymousType22("{'type': 'utf8', 'storage': 'variable', 'length': 100}", TypeKind.UTF_8, 100),
AnonymousType23("{'type': 'binary', 'storage': 'variable', 'length': 100}", TypeKind.Binary, 100), AnonymousType23("{'type': 'binary', 'storage': 'variable', 'length': 100}", TypeKind.BINARY, 100),
AnonymousType24("{'type': 'utf8', 'sparse': 'variable', 'length': 1000}", TypeKind.Utf8, 1000), AnonymousType24("{'type': 'utf8', 'sparse': 'variable', 'length': 1000}", TypeKind.UTF_8, 1000),
AnonymousType25("{'type': 'binary', 'sparse': 'variable', 'length': 1000}", TypeKind.Binary, 1000) }; AnonymousType25("{'type': 'binary', 'sparse': 'variable', 'length': 1000}", TypeKind.BINARY, 1000) };
for (dynamic expected : expectedSchemas) { for (dynamic expected : expectedSchemas) {
String columnSchema = String.format("{'path': 'a', 'type': %1$s", expected.Json String columnSchema = String.format("{'path': 'a', 'type': %1$s", expected.Json
@@ -517,8 +517,8 @@ class AnonymousType4 {
public String Json; public String Json;
public String Name; public String Name;
// TODO: C# TO JAVA CONVERTER: There is no Java equivalent to the C# 'dynamic' keyword: // TODO: C# TO JAVA CONVERTER: There is no Java equivalent to the C# 'dynamic' keyword:
dynamic[] expectedSchemas = { AnonymousType("{'type': 'int8' }", TypeKind.Int8), AnonymousType2("{'type': " + dynamic[] expectedSchemas = { AnonymousType("{'type': 'int8' }", TypeKind.INT_8), AnonymousType2("{'type': " +
"'array', 'items': {'type': 'int32'}}", TypeKind.Int32), AnonymousType3("{'type': 'object', 'properties': " + "'array', 'items': {'type': 'int32'}}", TypeKind.INT_32), AnonymousType3("{'type': 'object', 'properties': " +
"null}", 0), AnonymousType4("{'type': 'schema', 'name': 'myUDT'}", "myUDT") }; "null}", 0), AnonymousType4("{'type': 'schema', 'name': 'myUDT'}", "myUDT") };
public AnonymousType4(String _Json, String _Name) { public AnonymousType4(String _Json, String _Name) {
@@ -601,8 +601,8 @@ class AnonymousType4 {
publ TO JAVA CONVERTER TODO TASK: There is no Java equivalent to the C# 'dynamic' keyword: publ TO JAVA CONVERTER TODO TASK: There is no Java equivalent to the C# 'dynamic' keyword:
dynamic[] expectedSchemas = { AnonymousType("{'path': 'b', 'type': {'type': 'int8', 'storage': 'fixed'}}", dynamic[] expectedSchemas = { AnonymousType("{'path': 'b', 'type': {'type': 'int8', 'storage': 'fixed'}}",
TypeKind.Int8), AnonymousType2("{'path': 'b', 'type': {'type': 'array', 'items': {'type': 'int32'}}}", TypeKind.INT_8), AnonymousType2("{'path': 'b', 'type': {'type': 'array', 'items': {'type': 'int32'}}}",
TypeKind.Int32), AnonymousType3("{'path': 'b', 'type': {'type': 'object', 'properties': [{'path': 'c', " + TypeKind.INT_32), AnonymousType3("{'path': 'b', 'type': {'type': 'object', 'properties': [{'path': 'c', " +
"'type': {'type': 'bool'}}]}}", 1), AnonymousType4("{'path': 'b', 'type': {'type': 'schema', 'name': " + "'type': {'type': 'bool'}}]}}", 1), AnonymousType4("{'path': 'b', 'type': {'type': 'schema', 'name': " +
"'myUDT'}}", "myUDT") }; "'myUDT'}}", "myUDT") };